Grounded boolean turns on and off seemingly randomly when moving.

I have a bool that tracks when the player is or isnt in contact with the ground which dictates whether the player is able to jump or not. while playing, moving back and forth will randomly turn off the bool, even if the player is still in contact with the ground. Ive tried changing the offset of the box collider, changing my speed, gravity friction etc., and checking the rotation of the floor.

Here is the code in question

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

public class PlayerMovement : MonoBehaviour
{
    public float speed;
    public float jump;
    public bool Grounded;
    private float Move;
    private Rigidbody2D rb;
   
   
    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

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


        transform.rotation = Quaternion.Euler(0, 0, 0);
       
        if (Grounded == true)
        {
            Move = Input.GetAxis("Horizontal");
        }
       
       

        rb.velocity = new Vector2(speed * Move, rb.velocity.y);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (Grounded == true)
            {
              
              
               rb.AddForce(new Vector2(rb.velocity.x, jump));
            }
           
        }
    }

    private void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("floor"))
        {
            Grounded = true;
        }
    }

    private void OnCollisionExit2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("floor"))
        {
            Grounded = false;
        }
    }
}

That method of ground-testing won’t work very well. Pretty much any time you exit the collider of a ‘floor’ piece, grounded will be set to false, even if you are still touching another.

Generally testing whether a character is grounded is better done by raycasting or similarly towards the ground.

1 Like

Or a Sphere/Capsule cast.

This for example: Unity - Scripting API: Physics.CheckSphere

You need to make sure that the object and its collider you cast this from is not on the same layer as the ground. Basically you want to create a “Player” layer, set that layer to the Player object (and children) and exclude it from the Physics layer mask.