Need help with polishing jumping mechanic

Hello! I am not sure if this is the right place to ask but I am a beginner at using Unity and I am working on a First Person Shooter. I currently have some problems with the jumping mechanics of the game. It seems to work but there is this bug that whenever the player runs into another object (let’s say a wall) they are unable to jump against the wall. However when they jump towards the wall and collides with it whilst mid air they are able to jump against the wall.

Here is my code:

    void Update()
    {
        if (Input.GetKey(KeyCode.Space) && Grounded == true)
        {
            rb.AddForce(Vector3.up * jumpForce);
        }
        Grounded = false;
    }

    void OnCollisionStay(Collision collision)
    {
        if (collision.collider.gameObject.tag == "Ground")
        {
            Grounded = true;
        }
        else
        {
            Grounded = false;
        }

    }

Just to check I understand that: are you saying that if the player is stood on the ground against a wall, they should still be able to jump vertically upwards but are not able to do so?

Assuming my understanding is correct, I think the problem could be that being in contact with a wall (which presumably does not have the “Ground” tag) means that Grounded will be set to false preventing the jump.

If I could make a few other observations about the code:

  • In this case prefer OnCollisionEnter and OnCollisionExit to OnCoillsionStay. There is no need to perform the check you are doing every frame.
  • Prefer using CompareTag over “tag ==” as it uses less resources.
  • When checking a bool, it is sufficient to say if(Grounded) rather than if(Grounded == true).

I haven’t tested this code (and rb obviously needs setting), but maybe something along these lines may help? One possible problem here is if you have multiple ground colliders in close proximity, you may want to consider changing m_grounded from a “bool” to a reference-counting “int” :-

void Update()
{
    if (Input.GetKey(KeyCode.Space) && m_grounded)
    {
        rb.AddForce(Vector3.up * jumpForce);
    }
}

void OnCollisionEnter(Collision collision)
{
    if(collision.collider.gameObject.CompareTag(m_ground))
        m_grounded = true;
}

void OnCollisionExit(Collision collision)
{
    if(collision.collider.gameObject.CompareTag(m_ground))
        m_grounded = false;
}

#pragma warning disable 649
[SerializeField] float jumpForce = 2f;
#pragma warning restore 649

const string m_ground = "Ground";
bool m_grounded;

Thanks! I’ve changed OnCollisionStay to OnCollisionEnter and added an extra OnCollisionExit function and it seems to work very well!

1 Like