1 Commits
Author SHA1 Message Date
MrTorex c41d7f2d99 Фикс слайда, воллрана и т.п. 2025-12-06 14:37:01 +03:00
4 changed files with 28 additions and 19 deletions

No files matched your search

@@ -26,6 +26,7 @@ namespace Code.Configs
);
public float
slideMinVelocityThreshold = 3f,
slideInitialSpeed = 16f,
slideCooldown = 1.5f,
slideColliderHeightScale = 0.5f,
slideCameraOffsetY = -0.5f,
@@ -44,6 +45,7 @@ namespace Code.Configs
public float
wallRunMaxTime = 1.75f,
wallRunMaxNoMoveTime = 0.3f,
wallRunSpeed = 15f,
wallRunAcceleration = 25f,
wallRunGravityScale = 0.25f,
@@ -18,9 +18,10 @@ namespace Code.Gameplay.Character.Controller.Abilities
public bool IsSliding { get; private set; }
public SlideMechanic(AnimationCurve velocityCurve, float minVelocityThreshold, float cooldown)
public SlideMechanic(AnimationCurve velocityCurve, float slideInitialSpeed, float minVelocityThreshold, float cooldown)
{
_velocityCurve = velocityCurve;
_initialSpeed = slideInitialSpeed;
_minVelocityThreshold = minVelocityThreshold;
_cooldown = cooldown;
}
@@ -56,9 +57,6 @@ namespace Code.Gameplay.Character.Controller.Abilities
_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;
@@ -7,6 +7,7 @@ namespace Code.Gameplay.Character.Controller.Abilities
public class WallRunningMechanic
{
private readonly float _maxWallRunTime;
private readonly float _maxWallRunNoMoveTime;
private readonly float _wallRunSpeed;
private readonly float _wallRunAcceleration;
private readonly float _wallRunGravityScale;
@@ -14,9 +15,9 @@ namespace Code.Gameplay.Character.Controller.Abilities
private readonly float _wallContactAngleThreshold;
private float _wallRunTimer;
private float _wallRunNoMoveTimer;
private Vector3 _wallNormal;
private Vector3 _wallTangentRight;
private Vector3 _wallTangentUp;
private Vector3 _wallContactPoint;
private Vector3 _lastMoveInputInWallSpace;
@@ -29,6 +30,7 @@ namespace Code.Gameplay.Character.Controller.Abilities
public WallRunningMechanic(
float maxWallRunTime,
float maxWallRunNoMoveTime,
float wallRunSpeed,
float wallRunAcceleration,
float wallRunGravityScale,
@@ -36,6 +38,7 @@ namespace Code.Gameplay.Character.Controller.Abilities
float wallContactAngleThreshold)
{
_maxWallRunTime = maxWallRunTime;
_maxWallRunNoMoveTime = maxWallRunNoMoveTime;
_wallRunSpeed = wallRunSpeed;
_wallRunAcceleration = wallRunAcceleration;
_wallRunGravityScale = wallRunGravityScale;
@@ -54,15 +57,19 @@ namespace Code.Gameplay.Character.Controller.Abilities
if (!IsWallRunning) return;
_wallRunTimer += deltaTime;
if (_wallRunTimer > _maxWallRunTime)
{
DetachFromWall(false);
}
_wallRunNoMoveTimer += deltaTime;
if (!(_wallRunTimer > _maxWallRunTime) && !(_wallRunNoMoveTimer > _maxWallRunNoMoveTime)) return;
DetachFromWall(false);
_wallRunNoMoveTimer = 0;
}
public bool TryStartWallRun(Vector3 hitNormal, Vector3 hitPoint)
{
if (IsWallRunning) return false;
if (_motor.CharacterController is not CustomCharacterController { IsAbilitiesBlocked: false }) return false;
var dotWithUp = Vector3.Dot(hitNormal, _motor.CharacterUp);
var isWall = Mathf.Abs(dotWithUp) < _surfaceAngleCos;
@@ -107,7 +114,6 @@ namespace Code.Gameplay.Character.Controller.Abilities
}
_wallTangentRight = forwardInWallPlane.normalized;
_wallTangentUp = Vector3.Cross(_wallTangentRight, -_wallNormal).normalized;
_motor.ForceUnground();
}
@@ -118,6 +124,7 @@ namespace Code.Gameplay.Character.Controller.Abilities
if (!IsWallStillPresent()) { DetachFromWall(false); return; }
var forwardInput = inputs.MoveAxisForward;
if (forwardInput != 0) _wallRunNoMoveTimer = 0f;
var moveDirection = _wallTangentRight * forwardInput;
var targetSpeed = moveDirection.sqrMagnitude > 0.01f ? _wallRunSpeed : currentVelocity.magnitude;
@@ -202,7 +209,7 @@ namespace Code.Gameplay.Character.Controller.Abilities
{
if (!IsWallRunning || !_motor) return;
if (_motor.CharacterController is not CustomCharacterController { CanJump: true } controller)
if (_motor.CharacterController is not CustomCharacterController { IsAbilitiesBlocked: false } controller)
return;
IsWallRunning = false;
@@ -40,9 +40,9 @@ namespace Code.Gameplay.Character.Controller
private bool _wasSlidingLastFrame;
private float _jumpCooldownTimer;
private float _jumpCooldownDuration => _characterConfig.jumpCooldown;
private float JumpCooldownDuration => _characterConfig.jumpCooldown;
public bool CanJump => !isAbilitiesBlocked && _jumpCooldownTimer <= 0f;
public bool CanJump => _jumpCooldownTimer <= 0f;
// Подсистемы
private CharacterInputHandler _inputHandler;
@@ -59,8 +59,8 @@ namespace Code.Gameplay.Character.Controller
public bool IsWallRunning => _wallRunningMechanic.IsWallRunning;
private float abilityBlockTimer;
private bool isAbilitiesBlocked;
public bool IsAbilitiesBlocked { get; private set; }
private CharacterInputs _lastInputs;
public void SetPosition(Vector3 position) => motor.SetPosition(position);
@@ -79,11 +79,13 @@ namespace Code.Gameplay.Character.Controller
);
_slideMechanic = new SlideMechanic(
_characterConfig.slideVelocityCurve,
_characterConfig.slideInitialSpeed,
_characterConfig.slideMinVelocityThreshold,
_characterConfig.slideCooldown
);
_wallRunningMechanic = new WallRunningMechanic(
_characterConfig.wallRunMaxTime,
_characterConfig.wallRunMaxNoMoveTime,
_characterConfig.wallRunSpeed,
_characterConfig.wallRunAcceleration,
_characterConfig.wallRunGravityScale,
@@ -142,12 +144,12 @@ namespace Code.Gameplay.Character.Controller
_currentCameraMode = inputs.CameraMode;
if (isAbilitiesBlocked)
if (IsAbilitiesBlocked)
{
abilityBlockTimer -= Time.deltaTime;
if (abilityBlockTimer <= 0)
{
isAbilitiesBlocked = false;
IsAbilitiesBlocked = false;
}
else
{
@@ -277,7 +279,7 @@ namespace Code.Gameplay.Character.Controller
public void BlockAbilities(float duration)
{
isAbilitiesBlocked = true;
IsAbilitiesBlocked = true;
abilityBlockTimer = duration;
}
@@ -380,7 +382,7 @@ namespace Code.Gameplay.Character.Controller
public void TriggerJump()
{
_jumpCooldownTimer = _jumpCooldownDuration;
_jumpCooldownTimer = JumpCooldownDuration;
}
public void BeforeCharacterUpdate(float deltaTime)