0
\$\begingroup\$

Sometimes, the jump height will be so high, and sometimes it jumps normally. How do I solve this? Code:

using UnityEngine;

public class PlayerController : MonoBehaviour
{

    [SerializeField] private LayerMask platformsLayerMask;

    public Rigidbody2D rb;

    public float MovementSpeed = 100f;

    public float JumpingHeight = 100f;

    public BoxCollider2D bc;

    public float fallMultiplier = 2.5f;
    public float lowJumpMultiplier = 2f;

    public Animator anim;

    void Awake()
    {
        rb = transform.GetComponent<Rigidbody2D>();
        bc = transform.GetComponent<BoxCollider2D>();
    }

    void Update()
    {
        if (IsGrounded() && Input.GetKeyDown(KeyCode.Space))
        {
            rb.velocity = new Vector2(rb.velocity.x, JumpingHeight * Time.deltaTime);
            Debug.Log("Jumping");
        }
        HandleMovement();

    }

    private bool IsGrounded()
    {
        RaycastHit2D raycastHit2d = Physics2D.BoxCast(bc.bounds.center, bc.bounds.size, 0f, Vector2.down, 1f, platformsLayerMask);
        Debug.Log(raycastHit2d.collider);
        return raycastHit2d.collider != null;
    }

    void HandleMovement()
    {
        if (Input.GetKey(KeyCode.A))
        {
            rb.velocity = new Vector2(-MovementSpeed * Time.deltaTime, rb.velocity.y);
            Debug.Log("Going Left");
            transform.localScale = new Vector2(-1, 1);
        }
        else
        {
            if (Input.GetKey(KeyCode.D))
            {
                rb.velocity = new Vector2(+MovementSpeed * Time.deltaTime, rb.velocity.y);
                Debug.Log("Going Right");
                transform.localScale = new Vector2(1, 1);
            }
            else
            {
                //no keys pressed
                rb.velocity = new Vector2(0, rb.velocity.y);
                Debug.Log("No key pressed");
            }
        }
        if (rb.velocity.y < 0) //reponsive jumping and falling
        {
            rb.velocity += Vector2.up * Physics2D.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
        }
        else if (rb.velocity.y > 0 && Input.GetKeyDown(KeyCode.Space))
        {
            rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
        }

    }

}
\$\endgroup\$
5
  • 1
    \$\begingroup\$ What if you put your code in fixedupdate instead of update? \$\endgroup\$
    – Vaillancourt
    Mar 10, 2020 at 10:14
  • \$\begingroup\$ No, if you do fixedupdate, then sometimes jumping while running won't work \$\endgroup\$
    – user136618
    Mar 10, 2020 at 10:18
  • \$\begingroup\$ That sounds like an underlying bug that desperately needs fixing \$\endgroup\$ Mar 10, 2020 at 10:59
  • 2
    \$\begingroup\$ @htmlcoderexe No, it's very much by design that FixedUpdate does not necessarily run exactly once per frame. It's up to the developer to put anything that needs to tick exactly once per frame into the Update loop, and put anything that needs to tick at a consistent rate in game time in FixedUpdate — the entire reason for these two methods is so developers can choose the tick rate that's right for the functionality they need. \$\endgroup\$
    – DMGregory
    Mar 10, 2020 at 12:38
  • \$\begingroup\$ Oh, I did not see the distinction. In fact had to reread your text a few times, I think I get it now. Is this Unity-specific? \$\endgroup\$ Mar 10, 2020 at 12:44

1 Answer 1

2
\$\begingroup\$

Don't scale your jump velocity by Time.deltaTime

What that says is "If I running at a low framerate, jump higher" which is not what you want. You want a consistent change in velocity no matter whether the button was pressed on a short frame or a long frame.

For consistency, you'll want to put your falling acceleration in FixedUpdate, so you get the same falling arc at any framerate.

\$\endgroup\$
5
  • \$\begingroup\$ That's what they had at first gamedev.stackexchange.com/questions/179696/… \$\endgroup\$
    – Vaillancourt
    Mar 10, 2020 at 13:27
  • 1
    \$\begingroup\$ Note that I said put the falling acceleration there, not the input check. Moving the input check to Update was correct. Moving all movement physics was incorrect. \$\endgroup\$
    – DMGregory
    Mar 10, 2020 at 13:28
  • \$\begingroup\$ So you suggest to add a constant velocity for the jump impulse? Also, please enlighten me: why is putting all the movement physics in FixedUpdate incorrect? \$\endgroup\$
    – Vaillancourt
    Mar 10, 2020 at 14:39
  • \$\begingroup\$ @vaillancourt I believe DMGregory was saying that putting all the movement physics in Update was incorrect. The input checking should be in Update, but then the physics effects should take place in FixedUpdate, as you say. \$\endgroup\$
    – Tashus
    Mar 10, 2020 at 18:07
  • \$\begingroup\$ Maybe you should insert your comment from the question here. It's a valuable advise in general and the issue is a common culprit. And a good explanation for this question as well. \$\endgroup\$
    – Battle
    Mar 11, 2020 at 13:17

You must log in to answer this question.