CharacterController flickering between "Below" & "None" state.

I try to write the movement control for myself via the "CharacterController component.
but having the weird issue, as title mention.

I can confirm the following information at this point.

  • The movement only apply on Update() loop.

  • The “IsGround” => CharacterController.IsGround

  • The CollisionFlags getting by calling characterController.Move(motionVector);

  • I found if I input Vector3.zero into Move() API above, will easier trigger the air state.

  • as video present - No Collider invoked - No Rigidbody invoked.

  • Layer Collision Matrix on project setting ‘Character’ & ‘Ground’ are able to collide each other.

  • The Handle.Label was draw on Gizmos update.

  • The red line draw when every time it fail to detect ground collider when characterController changed to IsGrounded state.

and here is the related code to apply movement.

Vector3 BiasGroundNormal = Vector3.up;
Collider groundObject = null;
CollisionFlags previousCollisionFlags;

void MoveWrapper(motionVector)
{
    previousCollisionFlags = characterController.Move(motionVector);
    if (characterController.isGrounded)
    {
        Ray ray = new Ray(body.transform.position, -BiasGroundNormal); // down
        if (characterController.Raycast(
            ray, out RaycastHit hit,
            characterController.skinWidth * 2f)) // assume double skinWidth will hit the floor.
        {
            groundObject = hit.collider;
        }
        else
        {
            Debug.DrawRay(ray.origin, ray.direction, Color.red, 3f);
            Debug.LogError("Unable to ray ground object during : " + nameof(CollisionFlags) + "." + previousCollisionFlags, avatar);
        }
    }
}

I would like to know what I done wrong, if anyone known please tell me more information.
we can do it via any other type of Raycast, but I really wanted to know why this one not working as expected.

I think the problem is your use of the .RayCast() method in CharacterController.

If you read these docs:

You will see the following note for Raycast:

“Casts a Ray that ignores all Colliders except this one.”

I presume “this one” means the Collider on your CharacterController, and hence it would ignore your ground collider(s).

I think instead what you want is Physics.Raycast() if you are trying to sense the ground.

You may need to either use layers and specify that the raycast ignores your character, or else each time you raycast, turn off your character’s collider, then switch it back on after.

1 Like

Wow, it was ! thanks for pointing that out.!!

1 Like