Search Unity

Question Grounded boolean turns on and off seemingly randomly when moving.

Discussion in 'Editor & General Support' started by VoltageUltra072, Feb 28, 2024.

  1. VoltageUltra072

    VoltageUltra072

    Joined:
    Dec 17, 2023
    Posts:
    4
    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


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerMovement : MonoBehaviour
    6. {
    7.     public float speed;
    8.     public float jump;
    9.     public bool Grounded;
    10.     private float Move;
    11.     private Rigidbody2D rb;
    12.    
    13.    
    14.     // Start is called before the first frame update
    15.     void Start()
    16.     {
    17.         rb = GetComponent<Rigidbody2D>();
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.  
    24.  
    25.         transform.rotation = Quaternion.Euler(0, 0, 0);
    26.        
    27.         if (Grounded == true)
    28.         {
    29.             Move = Input.GetAxis("Horizontal");
    30.         }
    31.        
    32.        
    33.  
    34.         rb.velocity = new Vector2(speed * Move, rb.velocity.y);
    35.  
    36.         if (Input.GetKeyDown(KeyCode.Space))
    37.         {
    38.             if (Grounded == true)
    39.             {
    40.              
    41.              
    42.                rb.AddForce(new Vector2(rb.velocity.x, jump));
    43.             }
    44.            
    45.         }
    46.     }
    47.  
    48.     private void OnCollisionEnter2D(Collision2D other)
    49.     {
    50.         if (other.gameObject.CompareTag("floor"))
    51.         {
    52.             Grounded = true;
    53.         }
    54.     }
    55.  
    56.     private void OnCollisionExit2D(Collision2D other)
    57.     {
    58.         if (other.gameObject.CompareTag("floor"))
    59.         {
    60.             Grounded = false;
    61.         }
    62.     }
    63. }
    64.  
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,797
    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.
     
    CodeSmile likes this.
  3. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,798
    Or a Sphere/Capsule cast.

    This for example: https://docs.unity3d.com/ScriptReference/Physics.CheckSphere.html

    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.