diff --git a/Game/CourierOld/Assets/Code/Configs/CharacterConfig.cs b/Game/CourierOld/Assets/Code/Configs/CharacterConfig.cs index d650184..e600519 100644 --- a/Game/CourierOld/Assets/Code/Configs/CharacterConfig.cs +++ b/Game/CourierOld/Assets/Code/Configs/CharacterConfig.cs @@ -1,4 +1,5 @@ using UnityEngine; +using UnityEngine.Serialization; namespace Code.Configs { @@ -22,18 +23,12 @@ namespace Code.Configs slideSpeed = 20f, // Скорость слайда slideDuration = 0.8f, // Длительность слайда в секундах slideCooldown = 1.5f; // Время перезарядки слайда в секундах - - // Залазание на стены - public float - wallClimbSpeedFactor = 0.8f, // Коэффициент преобразования горизонтальной скорости в вертикальную при залазании на стену - minWallClimbSpeed = 9f, // Минимальная горизонтальная скорость для начала залазания на стену - wallDetectionAngleThreshold = 80f; // Максимальный угол (в градусах) от вертикали, при котором поверхность считается "стеной" // Наклон при залазании на стены - public float - maxWallLeanAngle = 45f, // Максимальный угол наклона от стены (в градусах) - wallLeanSharpness = 50f, // Скорость наклона/выпрямления (чем выше — тем резче) - wallLeanHeightScale = 0.1f; // Множитель: на сколько метров подъёма = 1 единица "наклона" + public float + leanAngle = 25f, + leanThreshold = 0.3f, + leanSmoothSpeed = 10f; // Гравитация public Vector3 gravity = new(0f, -30f, 0f); // Вектор, отвечающий за применение гравитации diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/WallLeanMechanic.cs b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/WallLeanMechanic.cs index 843776c..258088b 100644 --- a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/WallLeanMechanic.cs +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/WallLeanMechanic.cs @@ -4,56 +4,75 @@ namespace Code.Gameplay.Character.Controller.Abilities { public class WallLeanMechanic { + private readonly float _leanAngle; + private readonly float _threshold; + private readonly float _smoothSpeed; + private Transform _model; + public WallLeanMechanic( + float leanAngle, + float threshold, + float smoothSpeed) + { + _leanAngle = leanAngle; + _threshold = threshold; + _smoothSpeed = smoothSpeed; + } + public void SetModel(Transform model) => _model = model; public void Update(bool isWallRunning, Vector3 wallNormal, Vector3 characterForward) { - if (_model == null) + if (!_model) { _model.localRotation = Quaternion.identity; return; } - if (!isWallRunning) + var targetRotation = Quaternion.identity; + + if (isWallRunning) { - _model.localRotation = Quaternion.identity; - return; + var n = new Vector3(wallNormal.x, 0f, wallNormal.z).normalized; + if (n.sqrMagnitude < 0.001f) n = Vector3.forward; + + var bodyRight = Vector3.Cross(Vector3.up, characterForward).normalized; + var side = Vector3.Dot(n, bodyRight); + var front = Vector3.Dot(n, characterForward); + + var axis = Vector3.right; + var angle = 0f; + + if (side > _threshold) + { + axis = Vector3.forward; + angle = -_leanAngle; + } + else if (side < -_threshold) + { + axis = Vector3.forward; + angle = _leanAngle; + } + else if (front > _threshold) + { + axis = Vector3.right; + angle = -_leanAngle; + } + else if (front < -_threshold) + { + axis = Vector3.right; + angle = _leanAngle; + } + + targetRotation = Quaternion.AngleAxis(angle, axis); } - Vector3 n = new Vector3(wallNormal.x, 0f, wallNormal.z).normalized; - if (n.sqrMagnitude < 0.001f) n = Vector3.forward; - - Vector3 bodyRight = Vector3.Cross(Vector3.up, characterForward).normalized; - float side = Vector3.Dot(n, bodyRight); - float front = Vector3.Dot(n, characterForward); - - Vector3 axis = Vector3.right; - float angle = 0f; - - if (side > 0.3f) - { - axis = Vector3.forward; - angle = -25f; - } - else if (side < -0.3f) - { - axis = Vector3.forward; - angle = 25f; - } - else if (front > 0.3f) - { - axis = Vector3.right; - angle = -25f; - } - else if (front < -0.3f) - { - axis = Vector3.right; - angle = 25f; - } - - _model.localRotation = Quaternion.AngleAxis(angle, axis); + _model.localRotation = Quaternion.Slerp( + _model.localRotation, + targetRotation, + 1f - Mathf.Exp(-_smoothSpeed * Time.deltaTime) + ); } } } \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/CustomCharacterController.cs b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/CustomCharacterController.cs index caa2e8e..70ca2d1 100644 --- a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/CustomCharacterController.cs +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/CustomCharacterController.cs @@ -73,6 +73,9 @@ namespace Code.Gameplay.Character.Controller _wallRunningMechanic.WallContactAngleThreshold = 45.0f; _wallLeanMechanic = new WallLeanMechanic( + _characterConfig.leanAngle, + _characterConfig.leanThreshold, + _characterConfig.leanSmoothSpeed ); _groundMovement = new GroundMovementSystem( _characterConfig.maxStableMoveSpeed,