using UnityEngine; using KinematicCharacterController; namespace Code.Gameplay.Character.Controller { public class GroundMovementSystem { private readonly float _maxStableMoveSpeed; private readonly float _sprintMoveSpeed; private readonly float _stableMovementSharpness; public GroundMovementSystem(float maxStableMoveSpeed, float sprintMoveSpeed, float stableMovementSharpness) { _maxStableMoveSpeed = maxStableMoveSpeed; _sprintMoveSpeed = sprintMoveSpeed; _stableMovementSharpness = stableMovementSharpness; } public void UpdateVelocity( ref Vector3 currentVelocity, CharacterInputHandler inputHandler, KinematicCharacterMotor motor, float deltaTime) { var currentVelocityMagnitude = currentVelocity.magnitude; var effectiveGroundNormal = motor.GroundingStatus.GroundNormal; currentVelocity = motor.GetDirectionTangentToSurface(currentVelocity, effectiveGroundNormal) * currentVelocityMagnitude; var inputRight = Vector3.Cross(inputHandler.MoveInputVector, motor.CharacterUp); var reorientedInput = Vector3.Cross(effectiveGroundNormal, inputRight).normalized * inputHandler.MoveInputVector.magnitude; var targetSpeed = inputHandler.IsSprinting ? _sprintMoveSpeed : _maxStableMoveSpeed; var targetMovementVelocity = reorientedInput * targetSpeed; currentVelocity = Vector3.Lerp( currentVelocity, targetMovementVelocity, 1f - Mathf.Exp(-_stableMovementSharpness * deltaTime) ); } } }