Unity 中根据 Y 值不一致的跳跃

我正在 Unity 中制作一个游戏,您可以在其中使用 WASD 和空间跳跃。这是我的代码:


using UnityEngine;


public class PlayerMovement : MonoBehaviour {


    public Rigidbody rb;

    public bool canJump;


    void FixedUpdate () {

        if (Input.GetKey("w"))

        {

            rb.AddForce(0, 0, 750 * Time.deltaTime, ForceMode.Acceleration);

        }


        if (Input.GetKey("a"))

        {

            rb.AddForce(-750 * Time.deltaTime, 0, 0, ForceMode.Acceleration);

        }


        if (Input.GetKey("s"))

        {

            rb.AddForce(0, 0, -750 * Time.deltaTime, ForceMode.Acceleration);

        }


        if (Input.GetKey("d"))

        {

            rb.AddForce(750 * Time.deltaTime, 0, 0, ForceMode.Acceleration);

        }


        if (canJump)

        {

            if (Input.GetKeyDown("space"))

            {

                rb.AddForce(0, 10, 0, ForceMode.VelocityChange);

                Debug.Log("jump");

                canJump = false;

            }

        }


        Vector3 v = rb.velocity;

        v.y = 0;

        v = Vector3.ClampMagnitude(v, 6);

        v.y = rb.velocity.y;

        rb.velocity = v;

    }


    void OnCollisionEnter(Collision other)

    {

        if (other.gameObject.name == "Ground")

        {

            canJump = true;

        }

    }


    void OnCollisionExit(Collision other)

    {

        if (other.gameObject.name == "Ground")

        {

            canJump = false;

        }

    }

}

但是,当我跳跃时,它有时会跳得很高,有时根本不会跳。我已经测试过按住空格键是否有任何区别,但没有。我曾尝试使用 ForceMode.Impulse 和 ForceMode.VelocityChange,但跳跃仍然不一致。


我还注意到,当玩家在地板上的 Y 值约为 0.23 时,它只会在空中跳得很高。它也可以是~0.16,像这样,它根本不会跳得很高。


这是~0.16

http://img2.mukewang.com/61c6d6be0001674413640682.jpg

这是~0.23

http://img.mukewang.com/61c6d6cd00011f8213640684.jpg

最低的跳跃使其 Y 值达到 ~0.7,但最高的跳跃使其达到 4.83 左右。

如果有人有任何想法,我将不胜感激。


慕神8447489
浏览 403回答 2
2回答

白板的微信

我通常做的是检查我是向上还是向下。如果我向下走,我只接受地面检查。void OnCollisionEnter(Collision other){&nbsp; &nbsp; if (other.gameObject.name == "Ground" && rb.velocity.y < 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; canJump = true;&nbsp; &nbsp; }}但是,您使用getKeyDOWN所以这与保持空间等无关。所以我可以推荐的下一件事是:在跳跃之前将velocity.y 设置为0。if (Input.GetKeyDown("space")){&nbsp; &nbsp; Vector3 vel = rb.velocity;&nbsp; &nbsp; vel.y = 0;&nbsp; &nbsp; rb.velocity = vel;&nbsp; &nbsp; rb.AddForce(0, 10, 0, ForceMode.VelocityChange);&nbsp; &nbsp; // ...}编辑:等等,我的第一个想法是“他使用 getKey 并持有空间”,我的第二个想法是:“他错过了 Time.deltaTime”。但现在我看到了:您Input.Get...在 FixedUpdate 中使用过!让我解释:在Update调用所有s之前评估所有输入。 正如您在执行顺序中看到的,输入事件在更新之前被处理。现在,根据您的帧速率,与(几乎)恒定的 FixedUpdate 相比,Update 会经常或很少被调用。所以 FixedUpdate 可以在Update调用之间多次调用。这意味着输入事件运行一次。所以我必须假设Input.GetKeyDown(Key.SPACE)在多个 FixedUpdates 中这将是正确的!轻松修复:bool jump_pressed = false;void Update(){&nbsp; &nbsp; if(Input.GetKeyDown("space"))&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; jump_pressed = true;&nbsp; &nbsp; }&nbsp; &nbsp; if(Input.GetKeyUp("space"))&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; jump_pressed = false;&nbsp; &nbsp; }}void FixedUpdate(){&nbsp; &nbsp; if(jump_pressed)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; jump_pressed = false;&nbsp; &nbsp; &nbsp; &nbsp; rb.AddForce(0, 10, 0, ForceMode.VelocityChange);&nbsp; &nbsp; &nbsp; &nbsp; // etc...&nbsp; &nbsp; }}因此,您只需在 Update 中处理所有 Input 逻辑,并在固定更新中执行其余部分。当然,在 FixedUpdate 中 jump_pressed 需要设置为 false,因为否则它会在多个 FixedUpdates 中保持 true。edit2:我又看了你的代码。无论你做什么,无论是在 FixedUpdate 还是 Update 中,都不要使用Time.deltaTimein AddForce.AddForce 将操纵速度。并且在每个 PhysicsUpdate 中都使用速度来移动变换。但是 PhysicsUpdate/FixedUpdate 尝试以(几乎)固定的速率运行,而 Time.deltaTime 为您提供最后一个(更新)帧的经过时间。如果您自己移动变换 ( position +=...) - 使用 Time.deltaTime。但是在使用 AddForce 时不要使用它。

慕雪6442864

好的,如果你需要这个来紧急修复。获取 unity 默认 FPS 角色并探索其属性和组件,并尝试对您自己的对象执行相同操作。你可以稍后再详谈
打开App,查看更多内容
随时随地看视频慕课网APP