3

我的游戏场景中有一个 Cube(Player)。我编写了一个 C# 脚本来约束Mathf.Clamp()Cube 的移动(使用),使其不会离开屏幕。

以下是我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_min, x_max, z_min,的值z_max分别是通过统一检查器输入的 -3, 3, -2, 8。

问题

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

在此处输入图像描述

  • 为什么会这样?为什么 it( Mathf.Clamp()) 首先不将 Cube 限制为 -3 个单位?
  • 为什么我会得到额外的 0.1 个单位?
  • 为什么这个值只有 0.1 个单位?为什么不多或少?
4

3 回答 3

5

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

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

于 2017-05-02T13:25:36.593 回答
4
  • 发生这种情况是因为内部物理更新会在您将立方体置于其夹紧位置后移动立方体。Mathf.Clamp()确实首先将立方体限制在预期位置,因为您可以通过在分配位置后直接放置 Debug.Log 来验证
  • 您获得了额外的 0.1 单位,因为您为对象提供了在夹紧后应用的速度
  • 由于速度和固定时间步的设置(在项目设置 > 时间中),它是 0.1 个单位。如果您设置更高的速度,它会更多。如果您降低固定时间步长,它也会更多。
于 2017-05-02T13:27:28.563 回答
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;
}
于 2017-05-02T14:02:09.010 回答