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);
}