Slide character controller when is in the edge

I am using the unity’s character controller tool.

The problem is that if there exist below collision with the default character controler’s capsule collider it won’t slide down or fall unless could not detect any touch with a surface.

This is how it looks like:

I am using my own gravity just like this:

private void ApplyGravity() {
        if (!characterController.isGrounded) {
            gravity += Physics.gravity * Time.deltaTime * gravityFactor;
            if (gravity.y > 0 && !Input.GetButton(jumpButton))
                gravity += Physics.gravity * Time.deltaTime * gravityFactor * (lowJumpMultiplier - 1);
        }
        else if (!isJumping) gravity = Vector3.down;

        CheckCollisionFlags();
        movement += gravity;
    }

I’ve not found any way of modifying the character controller’s properties to apply any slippery or adding a new collider to take the collision.

I already tried to reduce the capsule collider’s radius but this results in a character that can go slightly through the walls.

I’ve thought about using a number of rays to check if middle of the body is beyond the edge and then apply a force to make it fall, but I think could be an easier and more optimal way to solve this problem.

I’m also curious how have a work around.

I’ve made it work by using the built in Unity’s collision listener that allows you to retrieve information about the world point where a certain collider is hitten on.
I first launched a ray from transform.position to the ground and checked if it collides and is grounded, if not, it means the player has at least half body off a surface. Then just deducted it to it’s center position and got a coordinate that increases as much far as you collides with an object far from the center of your character and used it to apply a movement in that direction.

private void OnControllerColliderHit(ControllerColliderHit hit) {
        if (RayGrounded(GetRayAtPos(0, 0)) && characterController.isGrounded) {
            Vector3 edgeFallMovement = transform.position - hit.point;
            edgeFallMovement.y = 0;
            movement += (edgeFallMovement * Time.deltaTime * edgeFallFactor);
        }
    }
2 Likes