Why does this not stop my character from jumping unlimited times?

Viewed 51

My character just jumps continuously even in the air, I'm not sure why the boolean does not stop it and I cannot figure it out. This is what I have so far:

using UnityEngine;
public class PlayerCollision : MonoBehaviour
{
    public Rigidbody rb;
    bool spacePressed = false;
    float upForce = 200f;

    void OnCollisionEnter(Collision collisionInfo)
    {
        if (collisionInfo.collider.tag == "Obstacle")
        {
            spacePressed = false;
        }
    }

    void Update()
    {
        if (Input.GetKey("space") && spacePressed == false)
        {
            spacePressed = true;
            rb.AddForce(0, upForce * Time.deltaTime, 0, ForceMode.VelocityChange);
        }
    }
}
2 Answers

My guess is that 'space pressed' is never or instantly set to false. So a first step on debuging it can be to watch the boolean. You can do that with 'public ...'. Then you should just observe when it's set to true/false.

There is also the possiblilty of this being a totally different kind of issue. For instance that one of the colliders could be of the wrong size (too big/small)

And to complete the holy trinity: There is a free 2D platformer example in the unity hub. I think they use a different approche by using an empty GO as a 'isGrounded' checker. One of the first things I learned as a hobbist is not to be ashamed to copy code of example projects.

Good luck.

It is likely that the collider is hitting Obstacle as it makes its first jump. OnCollisionEnter is very unreliable when checking if an object is beside/on another object. This can be checked if you use Debug.Log and check to see how much times it randomly activates OnCollisionEnter.

To reliably check if an object is beside another object use raycasts or boxcasts instead.

This is some code that should work that uses raycasts:

using UnityEngine;
public class PlayerCollision : MonoBehaviour
{
    public Rigidbody rb;
    public Collider collider;
    public float extraCheckHeight = 0.1f;

    float upForce = 200f;

    bool isGrounded(){
        Physics2D.Raycast(collider.bounds.center, Vector3.down, collider.bounds.extents.y + extraCheckHeight);
    }

    void Update()
    {
        if (Input.GetKey("space") && isGrounded)
        {
            rb.AddForce(0, upForce, 0, ForceMode.VelocityChange);//Time.deltaTime is should not be here because it should be the same force regardless of the time between frames
        }
    }
}

This should do the trick but I recommend researching about unity raycasts and boxcasts. Here is a video on Ground Checking that I found useful when I was approached with a similar problem: Ground Check

Related