简体   繁体   中英

rigidbody.AddForce() don't make my player jump at the same height everytime in unity

So i made a player with a rigidbody and a child game object "feet", i also added a layer "floor" to every plateforme my player can jump off so i can use Physics.CheckSphere() to see if my player is actually on the ground and can jump. In this last case i add a force to my rigidbody with a ForceMode.Impulse. Everything work except that sometimes the player do a little jump and sometimes a higher jump. Here is my code :

    [SerializeField] private float speed;
    [SerializeField] private float jumpForce;
    [SerializeField] private Transform feet = null;
    [SerializeField] private LayerMask floorMask;

    private Vector3 direction;
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        direction = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical")) * speed;
        transform.LookAt(transform.position + new Vector3(direction.x, 0, direction.z));

    }

    void FixedUpdate()
    {
        rb.velocity = new Vector3(direction.x, rb.velocity.y, direction.z);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (Physics.CheckSphere(feet.position, 0.1f, floorMask))
            {
                rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
            }
        }
    }

I replaced the AddForce method with velocity and it seems to work but AddForce isn't the proper way to do jumps ?

rb.velocity = new Vector3(rb.velocity.x, 1 * jumpForce, rb.velocity.z);

Using ForceMode.Impulse is the ideal way to implement a jump with RigidBody. I beleive you need to take your button input out of FixedUpdate() and place it into regular Update(). Then use a bool such as "canJump". This is because your input is being read inside FixedUpdate(); Which is only called every other frame with the physics engine. Also, your rb.velocity.y should be set to 0 when touching ground.

void Update() {
    direction = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical")) * speed;
    transform.LookAt(transform.position + new Vector3(direction.x, 0, direction.z));


    bool canJump = Input.GetKeyDown(keyCode.Space) ? true : false;
}

void FixedUpdate() {

    if (Physics.CheckSphere(feet.position, 0.1f, floorMask)) {
        
        if (canJump)
            rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
        
        else
            rb.velocity = new Vector3(direction.x, 0, direction.z);
    }
     
    else
        rb.velocity = new Vector3(direction.x, rb.velocity.y, direction.z);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM