Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Unexplainable jump boost when touching wall collider.

Discussion in 'Physics' started by Yasso165, Jul 24, 2015.

  1. Yasso165

    Yasso165

    Joined:
    Jul 24, 2015
    Posts:
    3
    As asked here:
    http://answers.unity3d.com/questions/420946/why-is-my-jump-height-affected-by-walls.html
    http://answers.unity3d.com/questions/301462/rigidbody-character-jumps-higher-with-at-least-2-c.html
    The solution is supposedly to add a rigid-body component to all of the existing game-objects with colliders and set them to kinematic, that doesn't fix it for me. I have no idea what could be causing this, but it's obviously game breaking and i can't continue with that bug in the game.
    Video (don't mind the character falling through the collider towards the end :rolleyes:):
    https://imgrush.com/FWZ-bpKK4pF6
    Any help appreciated, i've pretty much hit a roadblock here.:(
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    The problem is simply, but it depends on, what kind of method do you use for onGround detection?
     
  3. Yasso165

    Yasso165

    Joined:
    Jul 24, 2015
    Posts:
    3
    There:
    Code (CSharp):
    1.     void OnCollisionStay2D(){
    2.         onGround = true;
    3.     }
    4.     void OnCollisionEnter2D(){
    5.         onGround = true;
    6.     }
    7.     void OnCollisionExit2D(){
    8.         onGround = false;
    9.     }
     
  4. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    This is the problem, the wall is a collision too, so you're "on ground" whilst touching a wall.
    You should do:
    Code (CSharp):
    1. void OnCollisionEnter2D (Collision2D collisionInfo) {
    2.    for (ContactPoint2D c in collisionInfo.contacts[]) {
    3.       if (c.normal = Vector2.up) {
    4.          onGround = true;
    5.          break;
    6.       }
    7.    }
    8. }
    9.  
    10. void OnCollisionExit2D (Collision2D collisionInfo) {
    11.    for (ContactPoint2D co in collisionInfo.contacts[]) {
    12.       if (co.normal = Vector2.up) {
    13.          onGround = false;
    14.          break;
    15.       }
    16.    }
    17. }
    Just set the collision detection to continous dynamic, and you're done.
     
  5. Yasso165

    Yasso165

    Joined:
    Jul 24, 2015
    Posts:
    3
    Thank's a lot dude, although i didn't use that same code but i managed to fix it now :D
     
  6. BrandonB12

    BrandonB12

    Joined:
    Oct 1, 2017
    Posts:
    1
    but how did u fix it
     
  7. Ivanho2020

    Ivanho2020

    Joined:
    May 17, 2020
    Posts:
    1
    that didn't work for me
     
  8. the_0dium

    the_0dium

    Joined:
    Nov 29, 2018
    Posts:
    15
    I did it by putting a low friction physics material on a character. But as far as I remember your character then might be sliding around the floor. You'll have to stop him through code
     
  9. Inxentas

    Inxentas

    Joined:
    Jan 15, 2020
    Posts:
    275
    The underlying principle is that the original code pretty much says we are grounded when we touch which isn't the desired logic. The second example checks the actual point of collision. There are many ways to "ground" a character. I use a RayCast from which I grab the point and angle to detect when my character is slipping off a slope (and subsequently disable jumping).

    Below my method. The (best) offsetY var is dependent on character size, I raycast 1.2 units from it's center, 0.2 below it's actual feet. It checks whether what I hit was on the Platform layer (a layer I use for the level layout). It then grabs some angles for later use and returns true whenever an object was detected within range.

    Code (CSharp):
    1. private bool CastRayGround()
    2.     {
    3.         float offsetY = 1.2f;
    4.         Ray ray = new Ray(transform.position, Vector3.down);
    5.         RaycastHit[] hits = Physics.RaycastAll(ray);
    6.         foreach (RaycastHit hit in hits)
    7.         {
    8.             if (hit.collider)
    9.             {
    10.                 if (hit.collider.gameObject.layer.ToString() == "9")
    11.                 {
    12.                     _platformNormal = hit.normal;
    13.                     _platformAngleForward = Vector3.Angle(hit.normal, transform.forward) - 90;
    14.                     _platformAngleBackward = 0 - _platformAngleForward;
    15.                     _platformAngleAbs = Math.Abs(_platformAngleForward);
    16.                     if (Vector3.Distance(transform.position, hit.point) < offsetY)
    17.                     {
    18.                         return true;
    19.                     }
    20.                 }
    21.             }
    22.         }
    23.         return false;
    24.     }
    I would like some feedback on this method, I feel I should reference the layer in a different way. I know it can be done by name.

    The friction method is not ideal because the character might be affected by gravity more, the value of the onGround variable will still be true while the objects touch. Imagine your player steer your character against a wall when falling. During it's descent the onGround variable will be true until that collision no longer happens. Outside of that notion, low friction would typically be want you'd typically want on walls.
     
    Last edited: Jul 14, 2020