Files
CourierOld/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/SlideMechanic.cs
T

91 lines
2.9 KiB
C#

using UnityEngine;
using Code.Gameplay.Camera;
using KinematicCharacterController;
namespace Code.Gameplay.Character.Controller.Abilities
{
public class SlideMechanic
{
private readonly AnimationCurve _velocityCurve;
private readonly float _minVelocityThreshold;
private readonly float _cooldown;
private float _slideTime;
private float _cooldownTimer;
private Vector3 _slideDirection;
private bool _slideRequested;
private float _initialSpeed;
public bool IsSliding { get; private set; }
public SlideMechanic(AnimationCurve velocityCurve, float minVelocityThreshold, float cooldown)
{
_velocityCurve = velocityCurve;
_minVelocityThreshold = minVelocityThreshold;
_cooldown = cooldown;
}
public void TickCooldown(float deltaTime)
{
if (_cooldownTimer > 0f) _cooldownTimer -= deltaTime;
}
public void RequestSlide(bool slidePressed)
{
if (slidePressed && !_slideRequested && _cooldownTimer <= 0f)
_slideRequested = true;
}
public void TryStartSlide(KinematicCharacterMotor motor,
CameraMode currentCameraMode,
Quaternion firstPersonCameraRotation,
Vector3 lookInputVector)
{
if (!_slideRequested || !motor.GroundingStatus.IsStableOnGround || _cooldownTimer > 0f)
{
_slideRequested = false;
return;
}
IsSliding = true;
_slideTime = 0f;
var dir = currentCameraMode == CameraMode.FirstPerson
? firstPersonCameraRotation * Vector3.forward
: lookInputVector;
_slideDirection = Vector3.ProjectOnPlane(dir, motor.CharacterUp).normalized;
if (_slideDirection.sqrMagnitude < 0.01f) _slideDirection = motor.CharacterForward;
_initialSpeed = motor.Velocity.magnitude;
if (_initialSpeed < 12f) _initialSpeed = 12f; // fallback
_cooldownTimer = _cooldown;
_slideRequested = false;
}
public void HandleSlide(ref Vector3 currentVelocity, float deltaTime, KinematicCharacterMotor motor)
{
if (!IsSliding) return;
_slideTime += deltaTime;
var t = Mathf.Clamp01(_slideTime / 2.5f);
var speedMult = _velocityCurve.Evaluate(t);
var targetSpeed = _initialSpeed * speedMult;
currentVelocity = _slideDirection * targetSpeed;
currentVelocity += motor.CharacterUp * 1f;
if (targetSpeed < _minVelocityThreshold || !motor.GroundingStatus.IsStableOnGround)
EndSlide();
}
public void EndSlide()
{
IsSliding = false;
_slideTime = 0f;
}
}
}