- Home /
Collision Flags on Character Controller flip between Below and None
I am playing with the Unity Standard Asset Third Person Controller, which utilizes the CharacterController.
I have s separate scripts that is supposed to work while the CharacterController is grounded.
On Update, the character Controller's collision flags seem to jump between CollisionFlags.Below and CollisionFlags.None.
When I walk uphill, the flags stay set to below, but going downhill standing still seems to flit between Below and None every update.
Is this a known behavior? I am almost certain the the third person Controller has not been changed...
Answer by davedx · Mar 19, 2012 at 07:09 AM
I don't have time to test right now, but I'd guess it's standard behaviour of the character controller - you're trying to move forwards using your inputs, which constantly puts the character slightly above the ground so he falls slightly down.
What we did in a game where you had to be able to slide down hills was write additional code to modify the character's y position according to the slope of the ground. This forced him to stay grounded.
Answer by Avaista · Mar 19, 2012 at 08:40 AM
So I think I discovered the reason that the collision flags were being flipped.
Unity Standard Asset ThirdPersonCharacterController applies gravity like so:
function ApplyGravity ()
{
if (isControllable) // don't move player at all if not controllable.
{
// Apply gravity
var jumpButton = Input.GetButton("Jump");
// When we reach the apex of the jump we send out a message
if (jumping && !jumpingReachedApex && verticalSpeed <= 0.0)
{
jumpingReachedApex = true;
SendMessage("DidJumpReachApex", SendMessageOptions.DontRequireReceiver);
}
if (IsGrounded ())
verticalSpeed = 0;
else
verticalSpeed -= gravity * Time.deltaTime;
}
}
Basically gravity is only applied if you are not connected to the ground. Makes sense.
But the collision flags are based off of the movement. When the controller moved with 0 in the y, it did not hit the object beneath it, meaning that the controller was not grounded. On the next Apply gravity, because the object was not grounded from the last move, it applies the gravity, which meant now the controller was grounded, meaning the next time around verticalSpeed was set to 0, and would not hit collider again. This loops.
I can't imagine this is intended behaviors, though I noticed that when I commented out the if else and always applied gravity, the checks were consistent, but the character controller dropped like a brick once you stepped off of a platform, which makes sense(gravity was "accumulating" while on the platform).
I switched it to verticalSpeed = -.001; and it worked well enough, with the flags stating that their was a hit below each frame, while not having the character drop like a brick. Sadly, I found a better way of going about what I was doing(in terms of needed to know if the controller was grounded or not)
@davedx Thank you for your answer!
Your answer
Follow this Question
Related Questions
How to detect on which side my character controller was hit? 1 Answer
Problem detecting ground with collision flags and controller.move (vector3.down) 1 Answer
Excluding Gameobjects/Colliders from reacting with Collision Flags? 1 Answer
Collision with character controller and cube not working 1 Answer