IsGrounded working to slow?

Hey Guys,

I am trying to solve this CharacterController isGrounded problem. I have a 2d jump and run, like super mario. After implementing my CharacterController I found that sometimes my player cant jump. Basicly the isGrounded variable works very well. It only happens if my player was in the air/ notGrounded a short time before. For example my character runs down some stairs. The player clearly stops falling on every single stair, but the is grounded variable is never true. If I wait for a millisec the isGrounded becomes true. See the following picture.


If my character walks ( not running) down the exact same stairs the isGrounded variable becomes true on every stair. While bugfixing I tried several things:
I used a raycast from the bottom of my player downwards. See the red line on the next screenshot.


The raycast behaves exactly the same like the isGrounded variable. It only „hits“ the stairs when the character walks slow enough.

I don’t really understand, why the
character stops falling on every stair and clearly collides with the stairs neither the raycast nor the isGrounded variable becomes true? I even tried to add another collider a little bit below the players feet. Same result :frowning:
Any ideas how to overcome this problem.


Most likely your problem is a missconception between the meaning of isGrounded:

IsGrounded (like your raycast) Is surprisingly not a state that gets evaluated over the time of the Move, but instead is only relative to the outcome of the Move.

Lets say your character is standing on the default 1x1x1 cube and call Move in a downward/forward direction. After the Move you will end up in the air somewhere off the cube. Obviously you had to collide with the cube for the Move however, when you check isGrounded you will see it is false, as expected.
The same happens when your character starts in the air above the cube. If you have a large vector for Move, then your character will again end up in a similar position, but on the way down/forward, it must have it the cube. If you check isGrounded again, it will also be false.

From this we canconclude, that at any point in time, isGrounded only checks whether you are currently on the ground, not whether you previously collided with something below you. This usually happens, because your framerate is not high enough for Move to be accurate enough that you end up on the ground at the same time your jump button is pressed.

As a workaround you have a choice of 2 things:

  1. Use the FixedUpdate loop with a low interval in order to keep movement more accurate (will cause problems making your input work)
  2. Write your own CharacterController and have it remember collisions from below and store them in the isGrounded state variable (hard work, but definately possible since I’ve done it before :wink: )

Hope this helps,