91 lines
2.9 KiB
C#
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;
|
|
}
|
|
}
|
|
} |