Unity Rigidbody的速度为零,但对象仍在移动

时间:2018-07-29 18:14:36

标签: c# unity3d

目前,我正在编写用于移动播放器的脚本。希望沿x轴平滑运动。一切正常,但是当我编写一些代码以缓慢停止播放器时,出现了一些奇怪的行为。宇宙飞船永远不会完全停止,而是在当场摇晃。

首先,我知道文档说的是,我在这里做的不好:

  

在大多数情况下,您不应该直接修改速度,因为这会导致不切实际的行为。

我还是想问问是否有人知道为什么会这样,或者我如何避免在代码中使用rb.velocity *= BREAKING_FACTOR;。 (在刚体中,检查器的速度从0跳到0.04并返回每帧)。

public class PlayerController : MonoBehaviour 
{
    private const float MAX_SPEED = 8f, FORCE_FACTOR = 20f, BREAKING_FACTOR = .9f;
    private Rigidbody2D rb;

    private void Start () { rb = this.GetComponent<Rigidbody2D> (); }
    private void Update () 
    {
        var inputDirection = new Vector2 (0f, 0f);

        if (Input.GetKey (KeyCode.A) && rb.velocity.x > -MAX_SPEED) 
            inputDirection += new Vector2 (-1f, 0f);
        else if (Input.GetKey (KeyCode.D) && rb.velocity.x < MAX_SPEED)
            inputDirection += new Vector2 (1f, 0f);
        else 
        {
            // rb.velocity *= BREAKING_FACTOR;

            // If no force is added on the x-asis, the spaceship shall slow down
            if (rb.velocity.x > 0f) 
                inputDirection += new Vector2 (-1, 0);
            else if (rb.velocity.x < 0f) 
                inputDirection += new Vector2 (1, 0);               

            // Get it to stop completely when very slow
            if (Mathf.Abs (rb.velocity.x) < 1f) 
                // The Thing you shouldn't do:
                rb.velocity = new Vector2(0f, rb.velocity.y);
        }

        rb.AddForce (inputDirection * FORCE_FACTOR);
    }
}

1 个答案:

答案 0 :(得分:1)

我知道这篇文章已有一个月的历史,但也许我仍然可以为您提供帮助。

首先,这里有一些避免直接速度修改的一般技巧:

-您可以通过使用刚体的'drag'变量来避免使用“ BREAKING_FACTOR”直接修改。 将其设置为大于0的值会不断降低刚体的速度,但是不断设置速度会使它保持运动而不会降低速度,因此,我认为这确实对您有帮助。 -为了避免在不断设置速度的同时移动,请确保已禁用重力。 -.AddForce()始终是一种无需直接修改速度即可施加力的好方法。

您说过速度抖动,了解有关此方面的更多信息将很有帮助。 但我认为问题出在以下代码段中:

        if (rb.velocity.x > 0f) 
            inputDirection += new Vector2 (-1, 0);
        else if (rb.velocity.x < 0f) 
            inputDirection += new Vector2 (1, 0);       

        // Get it to stop completely when very slow
        if (Mathf.Abs (rb.velocity.x) < 1f) 
            // The Thing you shouldn't do:
            rb.velocity = new Vector2(0f, rb.velocity.y);

您始终在物体上施加力,因此,x速度永远不会为零,并且总是会发生两种情况之一。 您可以通过添加阈值来改变速度的减慢方式(例如,将速度乘以0.9f来进行折断)来解决此问题 (代码可能看起来像这样)

        if (rb.velocity.x > 0.1f) 
            inputDirection += new Vector2 (-1, 0);
        else if (rb.velocity.x < -0.1f) 
            inputDirection += new Vector2 (1, 0);       

(但不拖曳飞船只会使抖动变慢) 或(这就是我要做的方式),只需将这段代码放在脚本之外,然后向刚体添加一个拖动(我之前提到过)。

最后,我认为这是您需要的阻力。然后,您可以摆脱这整个部分

        // If no force is added on the x-asis, the spaceship shall slow down
        if (rb.velocity.x > 0f) 
            inputDirection += new Vector2 (-1, 0);
        else if (rb.velocity.x < 0f) 
            inputDirection += new Vector2 (1, 0);               

        // Get it to stop completely when very slow
        if (Mathf.Abs (rb.velocity.x) < 1f) 
            // The Thing you shouldn't do:
            rb.velocity = new Vector2(0f, rb.velocity.y);

因为它会使您的刚体抖动。

希望这对您有所帮助 -朱利安-