I’m trying to determine if my character is standing on the ground or not. I’m using a character controller, but the build-in CharacterController.IsGrounded() gives me inconsistent results. So I’m trying to bypass that by just checking it myself. I’m using a sphere collider to see if there is anything within a reasonable area around the bottom of the character’s capsule.
But the trouble is, this is also giving me inconsistent results. When the character moves, every frame or so it comes back to say that it isn’t grounded, and then very next frame it IS grounded. The moment I stop walking it declares that it is grounded, but when I’m moving my indicator text constantly flashes between true and false.
This doesn’t make any sense to me. I could understand that I screwed up if it was always giving a false reading, but I don’t understand why it constantly changes every frame. Any ideas?
This is my code that checks for the ground, it gets called every update (and it doesn’t change anything if I move it to fixed update)
bGrounded = Physics.OverlapSphere(new Vector3(transform.position.x, transform.position.y + cCon.radius - 0.13f, transform.position.z), cCon.radius - 0.05f, WhatIsGround, QueryTriggerInteraction.Ignore).Length > 0;
CharacterController.isGrounded
checks if the bottom of the capsule was intersecting with another collider the last time it was moved.
This requires a constant downwards force to be applied to the controller (when it’s not going up) for it to give a consistent grounded result; even if stationary, even if moving horizontally. Otherwise if it’s just skimming above the ground, you won’t get the correct result.
As for your OverlapSphere, perhaps use CheckSphere instead: Unity - Scripting API: Physics.CheckSphere
Also use Gizmos to debug the sphere you’re overlapping with, to ensure it’s actually in a position and size that would consistently overlap the ground.
1 Like
That’s good to know; I guess I could make something with a constant downward force, but that sounds like it’s begging for problems if I’m ever standing on uneven ground.
I’ve switched over to CheckSphere, (at the very least it’s less overhead,) but I’m still getting the same results. It keeps changing its mind every frame while I’m walking.
The character controller component isn’t physics based and doesn’t slide along surfaces like a traditional rigidbody might.
Perhaps obvious question, but is it checking every frame or is this logic perhaps only running sometimes?
Without seeing more code we’re just shooting in the dark. And again, try using gizmos to visualise where you’re checking.
Okay, I’ve gone through and revised the movement code to constantly have a downward force on the character. (Previously I’ve always used rigidbodies so out of habit I was disabling my simulated gravity when a character was on the ground.)
Everything seems to be working now; both the Character Controller’s “IsGrounded” and my check sphere are giving consistent results.
I guess what was happening was the character controller was just “skipping” along the ground and slightly bouncing up for one frame, and then when it was considered off the ground it had its artificial gravity applied and became grounded again, then there was no gravity so it just bounced up again. At least, that’s the best I can figure.
If that were the case, then my grounded flag would just be giving the data it had from the last time it checked, not suddenly returning an opposite value.
But stating the obvious is a good thing to do here; it wouldn’t be the first time I’ve been stuck because of something like that.