- Home /
How does character controller's isGrounded() detect whether the character's on the ground?
I was initially hoping that character controller's isGrounded() operated purely on whether or not the bottom of the controller was colliding with anything, but I've got a rotatable character controller that, for example, can run on walls, and if I'm running up a horizontal surface I no longer get a true result for isGrounded().
Is there something else I can edit on character controller to change the behavior of isGrounded(), for example setting what relative vector to look for the ground on?
I can go and look at the colliders myself, I'm just seeing if there's a way to do this using isGrounded().
Answer by Bunny83 · Feb 15, 2011 at 08:11 PM
As far as i know isGrounded is just a wrapper for
if((controller.collisionFlags & CollisionFlags.Below) != 0)
You can check the collision bit flag if he collides above or at the sides.
CollisionFlags.Sides don't tell you what side you collided. You could use CharacterController.OnControllerColliderHit to get detailed information about all collisions of your charactercontroller.
The ControllerColliderHit structure gives you everything, the exact hit point, the object you collided with and the surface normal.
Thanks for the info, it helped me figure out what I was doing wrong. Foolishly enough, it was just that the CharacterController wasn't rotating with the rest of my object. I'm not too optimistic that I'll be able to change that situation, based on searching :(.
Yeah, :D i tried it myself, but the CharacterController keeps aligned in space. A workaround would be to rotate the world around your player, but that involves a lot of calculations on your side. You could even do it without CharacterController and maybe use a normal capsule + rigidbody. Or maybe just a capsule-cast against the ground?
Helpful notice helped me a lot. This might help someone too: For my controller to work properly i wrapped CharacterController.isGrounded into: public bool IsGroundedBetter => (collisionFlags & CollisionFlags.Below) != 0 || ((collisionFlags & CollisionFlags.Sides) != 0 && currentNormals.Any(n => n.y > 0.1f));
But for that we need to store collisionFlags and collision normals. Those can be got from CharacterController.OnControllerColliderHit method as Bunny83 described.
Salveiro, Can you elaborate on how you got this to work? I tried to use OnControllerColliderHit to store the normal of the hit, but it says .Any is not an extension of the normal.