Search Unity

Better ground detection

Discussion in 'Physics' started by Neekolls, Mar 30, 2020.

  1. Neekolls

    Neekolls

    Joined:
    Oct 12, 2018
    Posts:
    3
    Hey everyone!

    I come ask for advice for an issue with my ground detection for a 2D project (I'm new to unity)
    So, i basically made a jump and use a transform with a radius of 0.06 under my character to detect the ground under it.

    It works fine most of the time, however, if a very specific case i have some troble with "steps"



    If i touch the corner of that step, it actually reset my boolean "isGrounded" allowing the character to make another jump.
    So i wanted to know if there is a better way to detect ground for 2D game. Or perhaps if i just need to adjust my code detect that case in particular.

    Here's my code, btw i'm learning how to script so all advices are welcomed!

    Code (CSharp):
    1. public class PlayerControler : MonoBehaviour
    2. {
    3.     public float speed;
    4.     public float jumpforce;
    5.     private float moveInput;
    6.  
    7.     private Rigidbody2D rb;
    8.  
    9.     private bool facingLeft = true;
    10.  
    11.  
    12.     public bool isGrounded = false;
    13.     public Transform groundCheck;
    14.     public float checkradius;
    15.     public LayerMask whatIsGround;
    16.  
    17.     private float jumpTimeCounter;
    18.     public float jumpTime;
    19.     private bool isFirstJumping;
    20.     private bool hasJumped;
    21.  
    22.     public bool mutationDoubleJump;
    23.     private bool isSecondJumping;
    24.     public float jumpforce2;
    25.  
    26.     private bool canCoyote;
    27.     public float coyoteTime;
    28.     private float coyoteTimeCounter;
    29.  
    30.     public float gravityScale;
    31.     public float addedGravity;
    32.  
    33.     public float PourcentInertie;
    34.  
    35.     public int hasBeenGrounded;
    36.     private bool lastGroundedState;
    37.  
    38.     void Start()
    39.     {
    40.         mutationDoubleJump = false;
    41.         rb = GetComponent<Rigidbody2D>();
    42.         gravityScale = rb.gravityScale;
    43.     }
    44.  
    45.  
    46.     private void Update()
    47.     {
    48.  
    49.         //On vérifie si le joueur touche le sol dur
    50.         if (lastGroundedState != isGrounded && isGrounded == true) hasBeenGrounded++;
    51.  
    52.         if (canCoyote)
    53.         {
    54.             if (coyoteTimeCounter<=0)
    55.             {
    56.                 canCoyote = false;
    57.             }
    58.             else
    59.             {
    60.                 coyoteTimeCounter -= Time.deltaTime;
    61.             }
    62.         }
    63.  
    64.         //Saut simple
    65.         if (isGrounded == true && Input.GetKeyDown(KeyCode.Space) || canCoyote == true && Input.GetKeyDown(KeyCode.Space))
    66.         {
    67.             isFirstJumping = true;
    68.             jumpTimeCounter = jumpTime;
    69.             rb.velocity = Vector2.up * jumpforce;
    70.             hasJumped = true;
    71.         }
    72.  
    73.         //Saut à nuances
    74.         if ( Input.GetKey(KeyCode.Space)&& isFirstJumping==true)
    75.         {
    76.             if(jumpTimeCounter>0 )
    77.             {
    78.                 rb.velocity = Vector2.up * jumpforce;
    79.                 jumpTimeCounter-= Time.deltaTime;
    80.                 hasJumped = true;
    81.             }
    82.             else
    83.             {
    84.                 isFirstJumping = false;
    85.             }
    86.         }
    87.        
    88.         else if(isFirstJumping == false && mutationDoubleJump == true && Input.GetKeyDown(KeyCode.Space)&& isSecondJumping==true && hasJumped == true)
    89.         {
    90.             rb.velocity = Vector2.up * jumpforce2;
    91.             isSecondJumping = false;
    92.             rb.gravityScale += addedGravity;
    93.         }
    94.        
    95.         if(Input.GetKeyUp(KeyCode.Space))
    96.         {
    97.             isFirstJumping = false;
    98.         }
    99.         if(isGrounded == true)
    100.         {
    101.             isSecondJumping = true;
    102.             canCoyote = true;
    103.             hasJumped = false;
    104.             coyoteTimeCounter = coyoteTime;
    105.             rb.gravityScale = gravityScale;
    106.         }
    107.         lastGroundedState = isGrounded;
    Thanck you for your time. I also apologyze for the poor english
     
  2. Neekolls

    Neekolls

    Joined:
    Oct 12, 2018
    Posts:
    3
    I have resolve the problem myself. The post can be closed
     
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    In-case it still helps, I maintain a GitHub project that demonstrates 2D physics features. One example shows how to use existing contacts for a simple IsGrounded state. You can also differentiate angles to detect floor/walls etc and no queries (no raycast etc) are involved. That test scene is here. Note, there are branches for earlier versions of Unity.

    Note that the set-up I demonstrate reduces the IsGrounded to a simple property shown here.

    This is that specific scene that demonstrates beyond a certain angle is not counted as grounded i.e. the slope:
     
    MaykeBr, Poprobertb6 and Krull like this.
  4. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    1,553
    It might be helpful for the community if you told how you solved the problem. After all, you posted your question here.