5
\$\begingroup\$

I'm tinkering with a unity2D sidescroller, and am trying to make a player controller to jump. However, when I tell my character to jump, it sometimes jumps twice the distance, and I don't know why. Below is my controller script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{

    public float playerSpeed = 10;
    public float jumpForce = 20;
    private bool ableToJump = false;
    public GameObject groundCheck;  // place an empty object slightly below the character where it will collide with any ground

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey("space") && ableToJump)
        {
            ableToJump = !ableToJump;
            GetComponent<Rigidbody2D>().AddForce(new Vector3(0,1,0) * jumpForce);
        }
        if (Input.GetKey("a"))
        {
            transform.Translate(-playerSpeed * Time.deltaTime, 0, 0);
        }
        if (Input.GetKey("d"))
        {
            transform.Translate(playerSpeed * Time.deltaTime, 0, 0);
        }

        // The player is grounded if a linecast to the groundcheck position hits anything on the ground layer.
        ableToJump = Physics2D.Linecast(transform.position, groundCheck.transform.position, 1 << LayerMask.NameToLayer("Wall"));
    }
}

Here is the glitch as it appears when I am previewing the game (watch how the third jump seems to be twice as high). There is no consistency to when it occurs, but it has occurred any time between two in a row and 10-12 between times it happens. I have tried long versus short presses of the jump key (space bar), moving versus standing still, and jumping on different locations. I have also tried disabling animations and waiting between presses versus pressing and holding space, versus pressing space rapidly. The only consistent thing is that sometimes I jump about three blocks (200 x 200px each) high, and sometimes I jump about six blocks high. Any tips are appreciated. Thanks!

The glitch in action

\$\endgroup\$
  • 1
    \$\begingroup\$ The problem could be that your bool ableToJump is being set to true in the last statement after you set it to false in the first if block and the the if block runs again the next frame. Try putting a Debug.Log() inside the if block to see if it gets called twice. \$\endgroup\$ – Aditya Yadav Feb 14 '17 at 5:39
  • \$\begingroup\$ gameprogrammingpatterns.com/state.html \$\endgroup\$ – MatthewRock Feb 14 '17 at 11:29
7
\$\begingroup\$

I'd recommend changing Input.GetKey("space") to Input.GetKeyDown("space"). This way the check is only performed on the initial key press, rather than every frame the spacebar is held.


The other issue is at the bottom of your script: ableToJump = Physics2D.Linecast(...

Since the physics step (aka fixed timestep) is only updating every 2 milliseconds (by default) rather than every Update frame, the Rigidbody.velocity change (and subsequent Rigidbody.position change) may not happen instantly. As such, checking for the ground position within Update may not be 100% accurate until the physics step happens and applies your AddForce call.

I'd recommend either:

  1. Move the ableToJump = Physics2D.Linecast(... line to the top of your Update method, so that the order of checking the ground comes before performing the jump; or

  2. Move the ableToJump = Physics2D.Linecast(... line into a FixedUpdate () { } method so that it's in sync and true with the physics step. (note that this could be inaccurate if you're altering transform.position rather than Rigidbody.position, so perhaps use the first option.)

\$\endgroup\$
  • 1
    \$\begingroup\$ I ended up putting the ableToJump line into the FixedUpdate() method because that seemed like the more organized way to do it, although both seemed to work fine after changing Input.GetKey() to Input.GetKeyDown(). Thanks for the help! \$\endgroup\$ – Ben Schwabe Feb 14 '17 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.