Unity中的Mathf.clamp()函数

时间:2017-05-02 12:58:19

标签: c# unity3d clamp

我的游戏场景中有一个立方体(玩家)。我编写了一个C#脚本来限制多维数据集的移动(使用Mathf.Clamp()),因此它不会离开屏幕。

以下是脚本中的FixedUpdate()方法

private void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        rb.velocity = movement * speed;

        rb.position = new Vector3(
            Mathf.Clamp (rb.position.x, x_min, x_max),
            0.5f,
            Mathf.Clamp(rb.position.z, z_min, z_max)
            );

    }

x_minx_maxz_minz_max的值分别为-3,3,-2,8,通过统一检查员输入。

问题

脚本工作正常,但我的播放器(立方体)最多可移动-3.1个单位为负X-AXIS(如果我一直按左箭头按钮),这个单位为负数X-AXIS多0.1个单位(这种行为也适用于其他轴)。当我停止按下按钮时,它显然会夹住-3.1到-3。

enter image description here

  • 为什么会这样?为什么它(Mathf.Clamp())首先将立方体限制为-3个单位?
  • 为什么我会额外获得0.1个单位?
  • 为什么这个值只有0.1个单位?为什么不多或少?

3 个答案:

答案 0 :(得分:4)

您的问题可能是因为您正在设置速度然后定位,但在下一帧之前,unity会将速度添加到对象位置。这就是它最终减少0.1个单位的原因。

要解决此问题,请尝试将对象的速度重置为零,如果它即将离开您的边界。

答案 1 :(得分:3)

  • 这种情况正在发生,因为内部物理更新会移动您将其置于夹紧位置的立方体after。 Mathf.Clamp()确实首先将多维数据集限制在预期的位置,因为您可以通过在分配位置后直接放置Debug.Log进行验证
  • 你得到额外的.1单位,因为你给对象提供了一个在你夹紧后应用的速度
  • 由于速度和固定时间步长的设置(在项目设置>时间),它是0.1单位。如果你设置更高的速度,它会更多。如果你想降低固定时间步长,它也会更多。

答案 2 :(得分:1)

你已经知道了这种情况发生的原因。

为了解决问题,您可以使用此代码来阻止多维数据集超出您的界限:

private void FixedUpdate() {
    Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));

    // Get new position in advance
    float xPos = rb.position.x + movement.x * speed * Time.fixedDeltaTime;
    float zPos = rb.position.z + movement.z * speed * Time.fixedDeltaTime;

    // Check if new position goes over boundaries and if true clamp it
    if (xPos > x_max || xPos < x_min) {
        if (xPos > x_max)
            rb.position = new Vector3(x_max, 0, rb.position.z);
        else
            rb.position = new Vector3(x_min, 0, rb.position.z);
        movement.x = 0;
    }
    if (zPos > z_max || zPos < z_min) {
        if (zPos > z_max)
            rb.position = new Vector3(rb.position.x, 0, z_max);
        else
            rb.position = new Vector3(rb.position.x, 0, z_min);
        movement.z = 0;
    }

    rb.velocity = movement * speed;
}