public void FixedUpdate()
{
    Vector3 movementDirection = new Vector3(_playerActions.CurrentMovementDirection.x, 0, _playerActions.CurrentMovementDirection.y);
    Vector3 movementVelocity = movementDirection * _context.Config.GroundControlMult;
    Vector3 movementDisplacement = movementVelocity * Time.fixedDeltaTime;

    Vector3 currentPosition = _context.Rigidbody.position;
    float colliderRadius = _context.Collider.radius;
    float colliderHeight = _context.Collider.height;

    for (int i = 0; i < KCCUtils.MAX_WALL_CHECK_ITERATIONS; i++)
    {
        if 
        (
            KCCUtils.CheckWillBeAgainstWall
            (
                currentPosition, colliderRadius, 
                colliderHeight, movementDisplacement.normalized,
                movementDisplacement.magnitude, out RaycastHit hit
            )
        )
        {
            float distanceToWall = Mathf.Max(hit.distance - KCCUtils.SKIN_WIDTH, 0);

            Vector3 movementDirectionToWall = movementDisplacement.normalized * distanceToWall;
            Vector3 movementInsideWall = movementDisplacement - movementDirectionToWall;

            currentPosition += movementDirectionToWall;

            movementDisplacement = Vector3.ProjectOnPlane(movementInsideWall, hit.normal);
        }
        else
        {
            currentPosition += movementDisplacement;
            break;
        }
    }

    _context.Rigidbody.MovePosition(currentPosition);
}




// Will collide with wall check
public static bool CheckWillBeAgainstWall(Vector3 startPosition, float radius, float height, Vector3 movementDirection, float maxDistance, out RaycastHit hit)
{
    radius -= SKIN_WIDTH;

    Vector3 topSphereOrigin = startPosition + Vector3.up * ((height / 2) - radius);
    Vector3 bottomSphereOrigin = startPosition + Vector3.down * ((height / 2) - radius);

    return Physics.CapsuleCast(topSphereOrigin, bottomSphereOrigin, radius, movementDirection, out hit, maxDistance);
}