How to make sure character is not floating on the edge of objects?


I’m working on a player controller and the movement is made using a CharacterController.

To check if character is grounded, I use a Raycast:

        void CheckGround()
            RaycastHit hitInfo;

            if(Physics.Raycast(new Ray(m_center, -transform.up), out hitInfo, 100, groundedLayers) )
                grounded = (transform.position.y - hitInfo.point.y) < groundDistance;

Works perfectly! The thing is if the character controller is standing on the edge of an object, this Raycast will hit the ground beneath the object and grounded will be false, therefore the falling animation is triggered.

I tried making the CharacterController radius smaller, but that’s not a healthy fix and it won’t work perfectly anyway.

I also used CharacterController.isGrounded in combination with my Raycast, but this is unrealiable (it would alternate between grounded / not grouneded):

grounded = ((transform.position.y - hitInfo.point.y) < groundDistance) || m_characterController.isGrounded;

Anyone has a suggestion on how to keep the character grounded while on the edge of objects?

Thank you!

Simplest answer is probably to use a CapsuleCast instead, and adjust the radius of that capsule rather than your collider. Alternatively, generating several raycasts downward from the extents of your collider and have isGrounded be true if any of them return a result- though it’s mostly identical to using a CapsuleCast, and probably more expensive, it enables you to have special cases where only 1 or 2 of the raycasts are hitting something to do a “teetering” animation, and getting more accurate normal data for sliding down incline geometry.