Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Player Controller can jump when he's near wall

Discussion in 'Physics' started by PotatoSlayer777, May 1, 2024.

  1. PotatoSlayer777

    PotatoSlayer777

    Joined:
    Dec 19, 2021
    Posts:
    4
    Here's the case:
    In my game I have a 3D character controller that can walk, jump, interact etc. One of the core things to jumping mechanic - is checking whether the player is on ground on not. I'm doing that by Physics.CheckSphere method because it's simple and effective:
    Code (CSharp):
    1.  isOnGround = Physics.CheckSphere(GroundChecker.position, groundDistance, groundMask);
    But there comes a problem I recently discovered - if a character jumps and goes near a wall, script checks out that the character is on ground and he can jump. If he jumps, he doesnt go high because he's bumping into a wall but he still can jump because he's still near wall! That way if player mashes jump button, the jump force gets multiplied and this can be used to cheat. Here's a video example of what I'm talking about:


    Lowering groundDistance isn't an option because level-design of my game consists of non-flat surfaces and the character is supposed to be able to stand on them.
    Can yall help me with this?
    Maybe I should use another method or maybe I should somehow check the object's polygon rotation to figure if the surface is flat enough for it to count as ground?
     
  2. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,933
    Have you tried Physics.Raycast? Then check the angle between the player and the hit.normal

    Code (csharp):
    1.  
    2.         RaycastHit hitInfo;
    3.         if (Physics.Raycast (GroundChecker.position, Vector3.down, out hitInfo, groundDistance, groundMask)) {          
    4.             var groundNormal = hitInfo.normal;
    5.             var angle = Vector3.Angle (Vector3.up, groundNormal);
    6.             if (angle < 45f) {
    7.                 isOnGround = true;
    8.             } else {
    9.                 //too steep
    10.                 isOnGround = false;
    11.             }
    12.         } else {
    13.             //too far
    14.             isOnGround = false;
    15.         }
    16.  
     
    PotatoSlayer777 likes this.
  3. PotatoSlayer777

    PotatoSlayer777

    Joined:
    Dec 19, 2021
    Posts:
    4
    Hmm, no, I haven't. I'll try it this evening, thanks
     
  4. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    1,054
    SphereCast is good for detecting sloped ground and you won't need to use a ground mask because it ignores anything that it overlaps at the start of the cast, like your player.

    Code (CSharp):
    1. isOnGround=Physics.SphereCast(transform.position,0.5f,-transform.up,out RaycastHit hit,0.55f);
    But it's important that you set the radius to be the same radius as your player's capsule collider.
     
  5. PotatoSlayer777

    PotatoSlayer777

    Joined:
    Dec 19, 2021
    Posts:
    4
    It worked, thank you!