Mathf.clamp() Unity 中的函数

Mathf.clamp() function in Unity

我的游戏场景中有一个 Cube(Player)。我已经编写了一个 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的值分别是通过unity inspector输入的-3、3、-2、8。

问题

脚本运行良好,但我的播放器(立方体)最多可以负向移动 -3.1 个单位 X-AXIS(如果我一直按向左箭头按钮)负向移动 0.1 个单位 X-AXIS(此行为也适用于其他轴)。当我停止按下按钮时,它显然将 -3.1 夹在 -3 之间。

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

要解决此问题,请尝试在对象即将离开边界时将其速度重置为零。

  • 发生这种情况是因为内部物理更新移动了立方体 after 您已将其置于固定位置。 Mathf.Clamp() 确实 首先将立方体限制在预期位置,因为您可以通过在分配位置后直接放置 Debug.Log 来验证
  • 您获得了额外的 .1 单位,因为您为对象提供了一个在夹紧后应用的速度
  • 它是 0.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;
}