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

No files matched your search

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