From 77fd9af29d0c6e78f986dcfcac6b509870eea935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C5=A1a=20Ceviel?= Date: Thu, 4 Dec 2025 17:14:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BD=20=D0=B1=D0=B5?= =?UTF-8?q?=D0=B3=20(=D0=BF=D1=80=D0=BE=D1=81=D1=82=D0=BE=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=91=D0=BD=20=D0=BD=D0=B0=20=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=D1=8C=D0=B1=D1=83=20=D1=81=20=D1=82=D0=B0=D0=BA=D0=BE?= =?UTF-8?q?=D0=B9=20=D0=B6=D0=B5=20=D1=81=D0=BA=D0=BE=D1=80=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8C=D1=8E),=20=D0=BF=D1=80=D0=BE=D1=88=D0=BB=D1=8B?= =?UTF-8?q?=D0=B9=20=D1=81=D0=BB=D0=B0=D0=B9=D0=B4=20=D0=B7=D0=B0=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=91=D0=BD=20=D0=BD=D0=B0=20=D0=B4=D1=8D=D1=89,?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D1=8B=D0=B9=20=D1=81=D0=BB=D0=B0=D0=B9=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Assets/Code/Configs/CharacterConfig.cs | 36 +++--- .../Controller/Abilities/DashMechanic.cs | 82 +++++++++++++ .../Controller/Abilities/DashMechanic.cs.meta | 3 + .../Controller/Abilities/SlideMechanic.cs | 113 +++++++----------- .../Controller/CustomCharacterController.cs | 50 ++++---- .../Controller/Input/CharacterInputHandler.cs | 19 +-- .../Movement/GroundMovementSystem.cs | 8 +- .../Code/Gameplay/Character/Core/Character.cs | 2 +- .../Character/Core/CharacterInputs.cs | 2 +- .../Character/Core/CharacterProvider.cs | 2 +- .../Assets/Code/Input/IInputService.cs | 2 +- .../Assets/Code/Input/InputService.cs | 44 +++---- .../Configs/App/CharacterConfig.asset | 52 ++++++-- .../Input/InputSystem_Actions.inputactions | 4 +- Game/CourierOld/Packages/packages-lock.json | 6 +- .../ProjectSettings/ProjectVersion.txt | 4 +- 16 files changed, 247 insertions(+), 182 deletions(-) create mode 100644 Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/DashMechanic.cs create mode 100644 Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/DashMechanic.cs.meta diff --git a/Game/CourierOld/Assets/Code/Configs/CharacterConfig.cs b/Game/CourierOld/Assets/Code/Configs/CharacterConfig.cs index dac0a0d..c74d56e 100644 --- a/Game/CourierOld/Assets/Code/Configs/CharacterConfig.cs +++ b/Game/CourierOld/Assets/Code/Configs/CharacterConfig.cs @@ -5,31 +5,31 @@ namespace Code.Configs [CreateAssetMenu(fileName = "CharacterConfig", menuName = "Config/CharacterConfig")] public class CharacterConfig : ScriptableObject { - // Основное движение по земле public float - maxStableMoveSpeed = 8f, // Максимальная скорость движения по устойчивой поверхности - stableMovementSharpness = 15f, // Резкость изменения скорости движения (чем выше - тем резче) - orientationSharpness = 10f, // Резкость изменения вращения персонажа (чем выше - тем резче) - jumpSpeed = 10f; // Скорость прыжка + maxStableMoveSpeed = 12f, + stableMovementSharpness = 15f, + orientationSharpness = 10f, + jumpSpeed = 10f; - // Спринт - public float - sprintMoveSpeed = 12f, // Максимальная скорость спринта - sprintAngleThreshold = 90f; // Максимальный угол (в градусах) от направления вперёд, при котором разрешён спринт + public float + dashSpeed = 20f, + dashDuration = 0.35f, + dashCooldown = 1.2f; + + public AnimationCurve slideVelocityCurve = new( + new Keyframe(0.0f, 1.0f), + new Keyframe(0.3f, 1.4f), + new Keyframe(1.0f, 0.2f) + ); + public float + slideMinVelocityThreshold = 3f, + slideCooldown = 1.5f; - // Слайд - public float - slideSpeed = 20f, // Скорость слайда - slideDuration = 0.8f, // Длительность слайда в секундах - slideCooldown = 1.5f; // Время перезарядки слайда в секундах - - // Наклон при залазании на стены public float leanAngle = 25f, leanThreshold = 0.3f, leanSmoothSpeed = 10f; - // Гравитация - public Vector3 gravity = new(0f, -30f, 0f); // Вектор, отвечающий за применение гравитации + public Vector3 gravity = new(0f, -30f, 0f); } } \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/DashMechanic.cs b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/DashMechanic.cs new file mode 100644 index 0000000..ca91f06 --- /dev/null +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/DashMechanic.cs @@ -0,0 +1,82 @@ +using UnityEngine; +using Code.Gameplay.Camera; +using KinematicCharacterController; + +namespace Code.Gameplay.Character.Controller.Abilities +{ + public class DashMechanic + { + private readonly float _dashSpeed; + private readonly float _dashDuration; + private readonly float _dashCooldown; + + private float _dashTimer; + private float _dashCooldownTimer; + private Vector3 _dashDirection; + private bool _dashRequested; + + public bool IsDashing { get; private set; } + + public DashMechanic(float dashSpeed, float dashDuration, float dashCooldown) + { + _dashSpeed = dashSpeed; + _dashDuration = dashDuration; + _dashCooldown = dashCooldown; + } + + public void TickCooldown(float deltaTime) + { + if (_dashCooldownTimer > 0f) _dashCooldownTimer -= deltaTime; + } + + public void RequestDash(bool dashPressed) + { + if (dashPressed && !_dashRequested && _dashCooldownTimer <= 0f) + _dashRequested = true; + } + + public void TryStartDash(KinematicCharacterMotor motor, + CameraMode currentCameraMode, + Quaternion firstPersonCameraRotation, + Vector3 lookInputVector) + { + if (!_dashRequested || !motor.GroundingStatus.IsStableOnGround || _dashCooldownTimer > 0f) + { + _dashRequested = false; + return; + } + + IsDashing = true; + _dashTimer = _dashDuration; + + var dir = currentCameraMode == CameraMode.FirstPerson + ? firstPersonCameraRotation * Vector3.forward + : lookInputVector; + + _dashDirection = Vector3.ProjectOnPlane(dir, motor.CharacterUp).normalized; + if (_dashDirection.sqrMagnitude < 0.01f) _dashDirection = motor.CharacterForward; + + _dashCooldownTimer = _dashCooldown; + _dashRequested = false; + } + + public void HandleDash(ref Vector3 currentVelocity, float deltaTime, KinematicCharacterMotor motor) + { + _dashTimer -= deltaTime; + if (_dashTimer <= 0f || !motor.GroundingStatus.IsStableOnGround) + { + EndDash(); + return; + } + + currentVelocity = _dashDirection * _dashSpeed; + currentVelocity += motor.CharacterUp * 1.5f; + } + + public void EndDash() + { + IsDashing = false; + _dashTimer = 0f; + } + } +} \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/DashMechanic.cs.meta b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/DashMechanic.cs.meta new file mode 100644 index 0000000..60f4fdf --- /dev/null +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/DashMechanic.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6d62efb53e0c4d49be9fc658484e2575 +timeCreated: 1764856437 \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/SlideMechanic.cs b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/SlideMechanic.cs index 8363653..46bb78f 100644 --- a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/SlideMechanic.cs +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Abilities/SlideMechanic.cs @@ -1,122 +1,91 @@ +using UnityEngine; using Code.Gameplay.Camera; using KinematicCharacterController; -using UnityEngine; namespace Code.Gameplay.Character.Controller.Abilities { - /* - * Механика слайда для персонажа - * Отвечает за управление состоянием, таймерами и скоростью слайда - */ public class SlideMechanic { - // Скорость слайда - private readonly float _slideSpeed; - // Длительность слайда в секундах - private readonly float _slideDuration; - // Время перезарядки слайда - private readonly float _slideCooldown; + private readonly AnimationCurve _velocityCurve; + private readonly float _minVelocityThreshold; + private readonly float _cooldown; - // Таймер слайда - private float _slideTimer; - // Таймер перезарядки слайда - private float _slideCooldownTimer; - // Направление слайда + private float _slideTime; + private float _cooldownTimer; private Vector3 _slideDirection; - // Флаг запроса слайда private bool _slideRequested; - - // Свойство-флаг, активен ли слайд + private float _initialSpeed; + public bool IsSliding { get; private set; } - - // Конструктор механики слайда - public SlideMechanic(float slideSpeed, float slideDuration, float slideCooldown) + + public SlideMechanic(AnimationCurve velocityCurve, float minVelocityThreshold, float cooldown) { - _slideSpeed = slideSpeed; - _slideDuration = slideDuration; - _slideCooldown = slideCooldown; + _velocityCurve = velocityCurve; + _minVelocityThreshold = minVelocityThreshold; + _cooldown = cooldown; } - // Обновляем таймер перезарядки слайда public void TickCooldown(float deltaTime) { - if (_slideCooldownTimer > 0f) - { - _slideCooldownTimer -= deltaTime; - } + if (_cooldownTimer > 0f) _cooldownTimer -= deltaTime; } - // Обработка слайда public void RequestSlide(bool slidePressed) { - if (slidePressed && !_slideRequested && _slideCooldownTimer <= 0f) - { + if (slidePressed && !_slideRequested && _cooldownTimer <= 0f) _slideRequested = true; - } } - // Начало слайда public void TryStartSlide(KinematicCharacterMotor motor, CameraMode currentCameraMode, Quaternion firstPersonCameraRotation, Vector3 lookInputVector) { - // Проверяем условия для старта слайда - if (!_slideRequested || !motor.GroundingStatus.IsStableOnGround || _slideCooldownTimer > 0f) + if (!_slideRequested || !motor.GroundingStatus.IsStableOnGround || _cooldownTimer > 0f) { _slideRequested = false; return; } IsSliding = true; - _slideTimer = _slideDuration; - - // НАПРАВЛЕНИЕ СЛАЙДА - ВСЕГДА ВПЕРЕД ПО КАМЕРЕ - // Используем направление камеры, но проецируем на горизонтальную плоскость - var slideDir = currentCameraMode == CameraMode.FirstPerson ? - firstPersonCameraRotation * Vector3.forward : - lookInputVector; - - // Проецируем на горизонтальную плоскость и нормализуем - _slideDirection = Vector3.ProjectOnPlane(slideDir, motor.CharacterUp).normalized; - - // Если направление нулевое (персонаж стоит на месте), используем направление вперед - if (_slideDirection.sqrMagnitude < 0.01f) - { - _slideDirection = motor.CharacterForward; - } + _slideTime = 0f; - // Устанавливаем перезарядку - _slideCooldownTimer = _slideCooldown; + 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 < 0.1f) _initialSpeed = 12f; // fallback + + _cooldownTimer = _cooldown; _slideRequested = false; } - // Обработка слайда public void HandleSlide(ref Vector3 currentVelocity, float deltaTime, KinematicCharacterMotor motor) { - // Уменьшаем таймер слайда - _slideTimer -= deltaTime; + if (!IsSliding) return; + + _slideTime += deltaTime; - // Если время слайда вышло, персонаж в воздухе - заканчиваем слайд - if (_slideTimer <= 0f || !motor.GroundingStatus.IsStableOnGround) - { + 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(); - return; - } - - // Устанавливаем скорость слайда вперед - // Используем прямую установку скорости вместо сложных вычислений - currentVelocity = _slideDirection * _slideSpeed; - - // Добавляем небольшую вертикальную компоненту для лучшего скольжения по неровностям - currentVelocity += motor.CharacterUp * 2f; } - // Завершение слайда public void EndSlide() { IsSliding = false; - _slideTimer = 0f; + _slideTime = 0f; } } } \ 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 c25e49b..4bf2a40 100644 --- a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/CustomCharacterController.cs +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/CustomCharacterController.cs @@ -27,6 +27,7 @@ namespace Code.Gameplay.Character.Controller // Подсистемы private CharacterInputHandler _inputHandler; + private DashMechanic _dashMechanic; private SlideMechanic _slideMechanic; // private WallClimbMechanic _wallClimbMechanic; private WallRunningMechanic _wallRunningMechanic; @@ -50,21 +51,20 @@ namespace Code.Gameplay.Character.Controller { _characterConfig = characterConfig; // Инициализация подсистем с параметрами из конфига - _inputHandler = new CharacterInputHandler( - _characterConfig.sprintAngleThreshold + _inputHandler = new CharacterInputHandler(); + _dashMechanic = new DashMechanic( + _characterConfig.dashSpeed, + _characterConfig.dashDuration, + _characterConfig.dashCooldown ); _slideMechanic = new SlideMechanic( - _characterConfig.slideSpeed, - _characterConfig.slideDuration, + _characterConfig.slideVelocityCurve, + _characterConfig.slideMinVelocityThreshold, _characterConfig.slideCooldown ); - // _wallClimbMechanic = new WallClimbMechanic( - // _characterConfig.wallClimbSpeedFactor, - // _characterConfig.minWallClimbSpeed, - // _characterConfig.wallDetectionAngleThreshold - // ); _wallRunningMechanic = new WallRunningMechanic(); - // Настройка параметров WallRunningMechanic (можно вынести в конфиг позже) + + // TODO: WallRunningMechanic (можно вынести в конфиг позже) _wallRunningMechanic.MaxWallRunTime = 1.75f; _wallRunningMechanic.WallRunSpeed = 15.0f; _wallRunningMechanic.WallRunAcceleration = 25.0f; @@ -79,7 +79,6 @@ namespace Code.Gameplay.Character.Controller ); _groundMovement = new GroundMovementSystem( _characterConfig.maxStableMoveSpeed, - _characterConfig.sprintMoveSpeed, _characterConfig.stableMovementSharpness, _characterConfig.jumpSpeed ); @@ -99,17 +98,15 @@ namespace Code.Gameplay.Character.Controller public void SetInputs(ref CharacterInputs inputs) { _lastInputs = inputs; - // Обновляем таймеры механик + _dashMechanic.TickCooldown(Time.deltaTime); _slideMechanic.TickCooldown(Time.deltaTime); - // _wallClimbMechanic.TickCooldown(Time.deltaTime); _wallRunningMechanic.Tick(Time.deltaTime); // Если активен слайд - игнорируем весь остальной ввод - if (_slideMechanic.IsSliding) + if (_dashMechanic.IsDashing || _slideMechanic.IsSliding) { _inputHandler.MoveInputVector = Vector3.zero; _inputHandler.LookInputVector = Vector3.one; - _inputHandler.IsSprinting = false; _groundMovement.RequestJump(inputs.JumpPressed); return; } @@ -125,12 +122,12 @@ namespace Code.Gameplay.Character.Controller } else { - inputs.SprintPressed = false; + inputs.DashPressed = false; inputs.SlidePressed = false; } } - // Обработка слайда + _dashMechanic.RequestDash(inputs.DashPressed); _slideMechanic.RequestSlide(inputs.SlidePressed); // Обработка остального ввода @@ -172,16 +169,21 @@ namespace Code.Gameplay.Character.Controller public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime) { + if (_dashMechanic.IsDashing && _groundMovement.JumpRequested) + _dashMechanic.EndDash(); if (_slideMechanic.IsSliding && _groundMovement.JumpRequested) - { _slideMechanic.EndSlide(); + + if (!_dashMechanic.IsDashing) + _dashMechanic.TryStartDash(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation, _inputHandler.LookInputVector); + else + { + _dashMechanic.HandleDash(ref currentVelocity, deltaTime, motor); + return; } if (!_slideMechanic.IsSliding) - { - _slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation, - _inputHandler.LookInputVector); - } + _slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation, _inputHandler.LookInputVector); else { _slideMechanic.HandleSlide(ref currentVelocity, deltaTime, motor); @@ -229,10 +231,10 @@ namespace Code.Gameplay.Character.Controller public void PostGroundingUpdate(float deltaTime) { + if (_dashMechanic.IsDashing && !motor.GroundingStatus.IsStableOnGround) + _dashMechanic.EndDash(); if (_slideMechanic.IsSliding && !motor.GroundingStatus.IsStableOnGround) - { _slideMechanic.EndSlide(); - } } public void AfterCharacterUpdate(float deltaTime) diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Input/CharacterInputHandler.cs b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Input/CharacterInputHandler.cs index e2ac576..dfd3fc5 100644 --- a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Input/CharacterInputHandler.cs +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Input/CharacterInputHandler.cs @@ -11,40 +11,23 @@ namespace Code.Gameplay.Character.Controller.Input */ public class CharacterInputHandler { - // Косинус порогового угла для спринта (предвычислен) - private readonly float _sprintAngleThresholdCos; // Векторы движения и направления взгляда public Vector3 MoveInputVector { get; set; } public Vector3 LookInputVector { get; set; } - // Флаг-свойство указывающий, что активен режим спринта - public bool IsSprinting { get; set; } - // Вращение камеры в FirstPerson режиме для синхронизации (только горизонтальная компонента) public Quaternion FirstPersonCameraRotation { get; set; } // Флаг-свойство указывающий, что нужно применить вращение камеры к персонажу public bool ShouldApplyCameraRotation { get; private set; } - - // Конструктор с пороговым углом - public CharacterInputHandler(float sprintAngleThreshold) - { - // Предвычисляем косинус порогового угла для эффективности - // Угол в градусах → радианы → косинус - // Чем меньше угол — тем строже условие - _sprintAngleThresholdCos = Mathf.Cos(Mathf.Deg2Rad * sprintAngleThreshold); - } - + // Обработка и преобразование входных данных от персонажа public void ProcessInputs(ref CharacterInputs inputs, KinematicCharacterMotor motor) { // Сохраняем текущий режим камеры var currentCameraMode = inputs.CameraMode; - // Обработка спринта - IsSprinting = inputs.SprintPressed && inputs.MoveAxisForward > _sprintAngleThresholdCos; // Спринт только при движении на заданный в конфиге угол - // Нормализация вектора движения и ограничение его величины до 1 var moveInputVector = Vector3.ClampMagnitude(new Vector3(inputs.MoveAxisRight, 0, inputs.MoveAxisForward), 1f); diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Movement/GroundMovementSystem.cs b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Movement/GroundMovementSystem.cs index 9d95784..cba1a52 100644 --- a/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Movement/GroundMovementSystem.cs +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Controller/Movement/GroundMovementSystem.cs @@ -11,8 +11,6 @@ namespace Code.Gameplay.Character.Controller.Movement { // Максимальная скорость движения по устойчивой поверхности private readonly float _maxStableMoveSpeed; - // Максимальная скорость спринта - private readonly float _sprintMoveSpeed; // Резкость изменения скорости движения (чем выше - тем резче) private readonly float _stableMovementSharpness; // Скорость прыжка @@ -22,10 +20,9 @@ namespace Code.Gameplay.Character.Controller.Movement public bool JumpRequested { get; private set; } // Конструктор системы движения на земле - public GroundMovementSystem(float maxStableMoveSpeed, float sprintMoveSpeed, float stableMovementSharpness, float jumpSpeed) + public GroundMovementSystem(float maxStableMoveSpeed, float stableMovementSharpness, float jumpSpeed) { _maxStableMoveSpeed = maxStableMoveSpeed; - _sprintMoveSpeed = sprintMoveSpeed; _stableMovementSharpness = stableMovementSharpness; _jumpSpeed = jumpSpeed; } @@ -66,8 +63,7 @@ namespace Code.Gameplay.Character.Controller.Movement inputHandler.MoveInputVector.magnitude; // Расчет целевой скорости движения с учетом ограничения максимальной скорости и спринта - var targetSpeed = inputHandler.IsSprinting ? _sprintMoveSpeed : _maxStableMoveSpeed; - var targetMovementVelocity = reorientedInput * targetSpeed; + var targetMovementVelocity = reorientedInput * _maxStableMoveSpeed; // Плавная интерполяция текущей скорости к целевой с экспоненциальным сглаживанием currentVelocity = Vector3.Lerp( diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Core/Character.cs b/Game/CourierOld/Assets/Code/Gameplay/Character/Core/Character.cs index 1d9a536..8943222 100644 --- a/Game/CourierOld/Assets/Code/Gameplay/Character/Core/Character.cs +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Core/Character.cs @@ -45,8 +45,8 @@ namespace Code.Gameplay.Character.Core inputs.MoveAxisForward = moveInput.y; // Vertical ось (W/S или Up/Down) inputs.MoveAxisRight = moveInput.x; // Horizontal ось (A/D или Left/Right) inputs.JumpPressed = _inputService.JumpPressed; // Прыжки (Space) - inputs.SprintPressed = _inputService.SprintPressed; // Спринт (Shift) inputs.SlidePressed = _inputService.SlidePressed; // Слайд (Ctrl) + inputs.DashPressed = _inputService.DashPressed; // Слайд (Ctrl) inputs.CameraMode = ((ICameraState)_cameraStateMachine.CurrentBaseState).GetCameraMode(); // Передаем информацию о камере для адаптивного поведения diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Core/CharacterInputs.cs b/Game/CourierOld/Assets/Code/Gameplay/Character/Core/CharacterInputs.cs index 74b1561..ecdac13 100644 --- a/Game/CourierOld/Assets/Code/Gameplay/Character/Core/CharacterInputs.cs +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Core/CharacterInputs.cs @@ -15,7 +15,7 @@ namespace Code.Gameplay.Character.Core public CameraMode CameraMode; // Текущий режим камеры для адаптации поведения public Vector3 CameraPlanarDirection; // Направление камеры в горизонтальной плоскости public bool JumpPressed; // Флаг указывающий, нажата ли кнопка прыжка - public bool SprintPressed; // Флаг указывающий, нажата ли кнопка спринта + public bool DashPressed; public bool SlidePressed; // Флаг указывающий, нажата ли кнопка слайда } } \ No newline at end of file diff --git a/Game/CourierOld/Assets/Code/Gameplay/Character/Core/CharacterProvider.cs b/Game/CourierOld/Assets/Code/Gameplay/Character/Core/CharacterProvider.cs index e40502d..3dc2870 100644 --- a/Game/CourierOld/Assets/Code/Gameplay/Character/Core/CharacterProvider.cs +++ b/Game/CourierOld/Assets/Code/Gameplay/Character/Core/CharacterProvider.cs @@ -38,7 +38,7 @@ namespace Code.Gameplay.Character.Core inputs.MoveAxisForward = moveInput.y; // Vertical ось (W/S или Up/Down) inputs.MoveAxisRight = moveInput.x; // Horizontal ось (A/D или Left/Right) inputs.JumpPressed = _inputService.JumpPressed; // Прыжки (Space) - inputs.SprintPressed = true;//_inputService.SprintPressed; // Спринт (Shift) + inputs.DashPressed = _inputService.DashPressed; inputs.SlidePressed = _inputService.SlidePressed; // Слайд (Ctrl) inputs.CameraMode = ((ICameraState)_cameraStateMachine.CurrentBaseState).GetCameraMode(); diff --git a/Game/CourierOld/Assets/Code/Input/IInputService.cs b/Game/CourierOld/Assets/Code/Input/IInputService.cs index adcc56c..718c11f 100644 --- a/Game/CourierOld/Assets/Code/Input/IInputService.cs +++ b/Game/CourierOld/Assets/Code/Input/IInputService.cs @@ -16,8 +16,8 @@ namespace Code.Input // Для управления движением персонажа Vector2 MoveInput { get; } bool JumpPressed { get; } - bool SprintPressed { get; } bool SlidePressed { get; } + bool DashPressed { get; } // Для переключения режима камеры bool ToggleCameraModePressed { get; } diff --git a/Game/CourierOld/Assets/Code/Input/InputService.cs b/Game/CourierOld/Assets/Code/Input/InputService.cs index fbe902f..8235169 100644 --- a/Game/CourierOld/Assets/Code/Input/InputService.cs +++ b/Game/CourierOld/Assets/Code/Input/InputService.cs @@ -13,8 +13,8 @@ namespace Code.Input public float ZoomInput { get; private set; } public Vector2 MoveInput { get; private set; } public bool JumpPressed { get; private set; } - public bool SprintPressed { get; private set; } public bool SlidePressed { get; private set; } + public bool DashPressed { get; private set; } public bool ToggleCameraModePressed { get; private set; } public InputService(InputActionAsset inputActionAsset) @@ -69,14 +69,6 @@ namespace Code.Input jumpAction.canceled += OnJumpCanceled; } - // Обработка спринта (персонаж) - var sprintAction = gameplayMap.FindAction("Sprint"); - if (sprintAction != null) - { - sprintAction.performed += OnSprintPerformed; - sprintAction.canceled += OnSprintCanceled; - } - // Обработка слайда (персонаж) var slideAction = gameplayMap.FindAction("Slide"); if (slideAction != null) @@ -85,6 +77,14 @@ namespace Code.Input slideAction.canceled += OnSlideCanceled; } + // Обработка слайда (персонаж) + var dashAction = gameplayMap.FindAction("Dash"); + if (dashAction != null) + { + dashAction.performed += OnDashPerformed; + dashAction.canceled += OnDashCanceled; + } + // Обработка переключения режима камеры var toggleCameraModeAction = gameplayMap.FindAction("ToggleCameraMode"); if (toggleCameraModeAction != null) @@ -134,16 +134,6 @@ namespace Code.Input JumpPressed = false; } - private void OnSprintPerformed(InputAction.CallbackContext context) - { - SprintPressed = true; - } - - private void OnSprintCanceled(InputAction.CallbackContext context) - { - SprintPressed = false; - } - private void OnSlidePerformed(InputAction.CallbackContext context) { SlidePressed = true; @@ -154,6 +144,16 @@ namespace Code.Input SlidePressed = false; } + private void OnDashPerformed(InputAction.CallbackContext context) + { + DashPressed = true; + } + + private void OnDashCanceled(InputAction.CallbackContext context) + { + DashPressed = false; + } + private void OnToggleCameraModePerformed(InputAction.CallbackContext context) { ToggleCameraModePressed = true; @@ -189,12 +189,12 @@ namespace Code.Input gameplayMap.FindAction("Jump").performed -= OnJumpPerformed; gameplayMap.FindAction("Jump").canceled -= OnJumpCanceled; - gameplayMap.FindAction("Sprint").performed -= OnSprintPerformed; - gameplayMap.FindAction("Sprint").canceled -= OnSprintCanceled; - gameplayMap.FindAction("Slide").performed -= OnSlidePerformed; gameplayMap.FindAction("Slide").canceled -= OnSlideCanceled; + gameplayMap.FindAction("Dash").performed -= OnDashPerformed; + gameplayMap.FindAction("Dash").canceled -= OnDashCanceled; + gameplayMap.FindAction("ToggleCameraMode").performed -= OnToggleCameraModePerformed; gameplayMap.FindAction("ToggleCameraMode").canceled -= OnToggleCameraModeCanceled; } diff --git a/Game/CourierOld/Assets/Resources/Configs/App/CharacterConfig.asset b/Game/CourierOld/Assets/Resources/Configs/App/CharacterConfig.asset index d89d157..e400ce5 100644 --- a/Game/CourierOld/Assets/Resources/Configs/App/CharacterConfig.asset +++ b/Game/CourierOld/Assets/Resources/Configs/App/CharacterConfig.asset @@ -12,19 +12,49 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 10cfaf8e57f64eddb8c2eda147e4739a, type: 3} m_Name: CharacterConfig m_EditorClassIdentifier: Assembly-CSharp::Code.Configs.CharacterConfig - maxStableMoveSpeed: 8 + maxStableMoveSpeed: 12 stableMovementSharpness: 15 orientationSharpness: 10 jumpSpeed: 10 - sprintMoveSpeed: 12 - sprintAngleThreshold: 90 - slideSpeed: 20 - slideDuration: 0.8 + dashSpeed: 20 + dashDuration: 0.35 + dashCooldown: 1.2 + slideVelocityCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 0.3 + value: 1.4 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 1 + value: 0.2 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + slideMinVelocityThreshold: 3 slideCooldown: 1.5 - wallClimbSpeedFactor: 0.8 - minWallClimbSpeed: 9 - wallDetectionAngleThreshold: 80 - maxWallLeanAngle: 90 - wallLeanSharpness: 100 - wallLeanHeightScale: 0.1 + leanAngle: 25 + leanThreshold: 0.3 + leanSmoothSpeed: 10 gravity: {x: 0, y: -30, z: 0} diff --git a/Game/CourierOld/Assets/Settings/Input/InputSystem_Actions.inputactions b/Game/CourierOld/Assets/Settings/Input/InputSystem_Actions.inputactions index eacaeec..a718716 100644 --- a/Game/CourierOld/Assets/Settings/Input/InputSystem_Actions.inputactions +++ b/Game/CourierOld/Assets/Settings/Input/InputSystem_Actions.inputactions @@ -95,7 +95,7 @@ "initialStateCheck": false }, { - "name": "Sprint", + "name": "Dash", "type": "Button", "id": "641cd816-40e6-41b4-8c3d-04687c349290", "expectedControlType": "", @@ -231,7 +231,7 @@ "interactions": "", "processors": "", "groups": "Keyboard&Mouse", - "action": "Sprint", + "action": "Dash", "isComposite": false, "isPartOfComposite": false }, diff --git a/Game/CourierOld/Packages/packages-lock.json b/Game/CourierOld/Packages/packages-lock.json index dbbfa91..d3dcd3d 100644 --- a/Game/CourierOld/Packages/packages-lock.json +++ b/Game/CourierOld/Packages/packages-lock.json @@ -24,7 +24,7 @@ "hash": "e644f1bb8ea190157aaea9c386f85cee4cd03bd9" }, "com.unity.addressables": { - "version": "2.7.4", + "version": "2.7.6", "depth": 2, "source": "registry", "dependencies": { @@ -34,7 +34,7 @@ "com.unity.modules.jsonserialize": "1.0.0", "com.unity.modules.imageconversion": "1.0.0", "com.unity.modules.unitywebrequest": "1.0.0", - "com.unity.scriptablebuildpipeline": "2.4.3", + "com.unity.scriptablebuildpipeline": "2.5.0", "com.unity.modules.unitywebrequestassetbundle": "1.0.0" }, "url": "https://packages.unity.com" @@ -201,7 +201,7 @@ } }, "com.unity.scriptablebuildpipeline": { - "version": "2.4.3", + "version": "2.5.0", "depth": 3, "source": "registry", "dependencies": { diff --git a/Game/CourierOld/ProjectSettings/ProjectVersion.txt b/Game/CourierOld/ProjectSettings/ProjectVersion.txt index 7c2a266..cea442d 100644 --- a/Game/CourierOld/ProjectSettings/ProjectVersion.txt +++ b/Game/CourierOld/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 6000.2.14f1 -m_EditorVersionWithRevision: 6000.2.14f1 (589824c1fc31) +m_EditorVersion: 6000.2.15f1 +m_EditorVersionWithRevision: 6000.2.15f1 (0707b6d1e918)