【问题标题】:Unity Rigidbody's Velocity is zero but Object still movesUnity Rigidbody Velocity 为零,但 Object 仍在移动
【发布时间】:2018-07-29 18:14:35
【问题描述】:

目前我正在编写移动玩家的脚本。旨在沿 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);
    }
}

【问题讨论】:

  • 如果速度低于某个阈值,您可以直接设置速度。

标签: c# unity3d


【解决方案1】:

我知道这篇文章已经发布了一个月,但也许我仍然可以帮助你。

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

-您可以通过使用刚体的“拖动”变量来避免直接修改“BREAKING_FACTOR”。 将其设置为高于 0 的值会不断减慢刚体的速度,但不断设置速度会使其保持移动而不会减慢速度,因此我认为这对您很有帮助。 - 为避免在不断设置速度的同时移动,您应确保已禁用重力。 -.AddForce() 始终是在不直接修改速度的情况下施加力的好方法。

您说速度抖动,了解更多关于此的信息会有所帮助。 但我认为问题在于这个sn-p:

        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);

因为它会让你的刚体抖动。

我希望这对你有帮助 -朱利安-

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多