Home > Blockchain >  Why isn't this code working for double jumping in Unity?
Why isn't this code working for double jumping in Unity?

Time:12-21

I'm trying to make my character be able to jump once while in the air/double jump in a 2D Unity project and below is my code for it. The player character can jump once but just not again when in the air, though I think it is actually working in the program's eyes, because the jumpCounter variable does increase to 1 sometimes, but mainly straight to 2, so I think it's something to do with the space key being pressed multiple times in a frame even though I'm only pressing it once?

Code:

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

public class PlayerController2D : MonoBehaviour
{
    float xMovement = 0;
    float jumpValue = 0;
    Vector2 targetVelocity = new Vector2(0, 0);
    Rigidbody2D myRigidBody;
    public bool isGrounded = true;
    public int jumpCounter = 0;
    // Start is called before the first frame update
    void Start()
    {
        myRigidBody = GetComponent<Rigidbody2D>();
        myRigidBody.gravityScale = 8;
        //myRigidBody.simulated = false;
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void checkInputs()
    {
        xMovement = Input.GetAxis("Horizontal");
        jumpValue = 0;
        if (isGrounded)
        {
            jumpValue = Input.GetAxis("Jump");
            if (jumpValue > 0)
            {
                jumpCounter  = 1;
            }
            if (jumpCounter >= 2)
                isGrounded = false;
        }
    }

    private void FixedUpdate()
    {
        checkInputs();
        myRigidBody.velocity = new Vector2(xMovement * 20, myRigidBody.velocity.y);
        myRigidBody.velocity = new Vector2(myRigidBody.velocity.x, jumpValue * 20);
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.transform.CompareTag("Ground"))
        {
            isGrounded = true;
            jumpCounter = 0;
        }
    }
}

CodePudding user response:

The reason is that GetAxis stays >0 as long as the key is held down. The FixedUpdate event is called 50 times per second, so it's likely that even the quickest press results in both jumps to happen right away in two consecutive frames.

There are at least two ways to solve this: Have a sort of mechanism that checks that a jump was actually fulfilled by checking for when GetAxis is 0 again and only allow the second jump if that has happened inbetween.

An easier solution would be to use Input.GetButtonDown. That method will only be True that single frame when the button was pressed, no matter how long it's held down. Unfortunately there is no GetAxisDown or something.

One pitfall however: This forces you to use the Update() method for the checkInputs() call and not the FixedUpdate because it will only be true for a single rendering frame (synchronous with Update()), not for an entire, usually longer physics cycle (the physics cycles are what FixedUpdate is synchronous with).

CodePudding user response:

Try with Input.GetKeyDown("space"). Or Input.GetKeyDown(KeyCode.Space)

From the docs "Call this function from the Update function, since the state gets reset each frame. It will not return true until the user has released the key and pressed it again."

I would check this:

void checkInputs()
{
    xMovement = Input.GetAxis("Horizontal");
    jumpValue = 0;
    if (isGrounded)
    {
        jumpValue = Input.GetKeyDown(KeyCode.space);
        if (jumpValue > 0)
        {
            jumpCounter  = 1;
        }
        if (jumpCounter >= 2)
            isGrounded = false;
    }
}
  • Related