Инишиал залазание на стенку

Нуждается в очень сильной доработке, но по крайней мере у нас есть основа для этого.
This commit is contained in:
MrTorex committed 2025-10-27 13:30:10 +03:00
1 parent bada54c828
commit 487331dc10
2 files changed
+38 -2

No files matched your search

@@ -40,7 +40,9 @@ namespace Code.Gameplay.Player
slideCooldown = 1.5f, // Время перезарядки слайда slideCooldown = 1.5f, // Время перезарядки слайда
stableMovementSharpness = 15f, // Резкость изменения скорости движения (чем выше - тем резче) stableMovementSharpness = 15f, // Резкость изменения скорости движения (чем выше - тем резче)
orientationSharpness = 10f, // Резкость изменения вращения персонажа (чем выше - тем резче) orientationSharpness = 10f, // Резкость изменения вращения персонажа (чем выше - тем резче)
jumpSpeed = 10f; // Скорость прыжка jumpSpeed = 10f, // Скорость прыжка
wallClimbSpeedFactor = 0.8f, // Коэффициент преобразования горизонтальной скорости в вертикальную при залазании на стену
minWallClimbSpeed = 9f; // Минимальная горизонтальная скорость для начала залазания на стену
[SerializeField] [SerializeField]
private Vector3 gravity = new(0, -30f, 0); // Вектор, отвечающий за применение гравитации private Vector3 gravity = new(0, -30f, 0); // Вектор, отвечающий за применение гравитации
@@ -65,6 +67,9 @@ namespace Code.Gameplay.Player
private float _slideCooldownTimer; // Таймер перезарядки слайда private float _slideCooldownTimer; // Таймер перезарядки слайда
private Vector3 _slideDirection; // Направление слайда private Vector3 _slideDirection; // Направление слайда
private bool _slideRequested; // Флаг запроса слайда private bool _slideRequested; // Флаг запроса слайда
// Флаг для предотвращения повторного залазания на стену в один и тот же кадр
private bool _wallClimbAppliedThisFrame;
// Инициализация контроллера // Инициализация контроллера
private void Start() private void Start()
@@ -297,6 +302,9 @@ namespace Code.Gameplay.Player
// Обновление скорости движения персонажа // Обновление скорости движения персонажа
public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime) public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
{ {
// Сбрасываем флаг залазания на стену в начале каждого кадра
_wallClimbAppliedThisFrame = false;
// Проверяем запрос слайда и запускаем его если можно // Проверяем запрос слайда и запускаем его если можно
if (_slideRequested && !_isSliding && motor.GroundingStatus.IsStableOnGround && _slideCooldownTimer <= 0f) if (_slideRequested && !_isSliding && motor.GroundingStatus.IsStableOnGround && _slideCooldownTimer <= 0f)
{ {
@@ -347,12 +355,12 @@ namespace Code.Gameplay.Player
motor.ForceUnground(); motor.ForceUnground();
} }
} }
// Если персонаж не находится на земле // Если персонаж не находится на земле
else else
{ {
// Применяем гравитацию // Применяем гравитацию
currentVelocity += gravity * deltaTime; currentVelocity += gravity * deltaTime;
// Отменяем прыжок (фикс проблемы с двойным прыжком после приземления) // Отменяем прыжок (фикс проблемы с двойным прыжком после приземления)
_jumpRequested = false; _jumpRequested = false;
} }
@@ -393,6 +401,32 @@ namespace Code.Gameplay.Player
public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
ref HitStabilityReport hitStabilityReport) ref HitStabilityReport hitStabilityReport)
{ {
// Игнорируем, если уже залезли на стену в этом кадре или если слайд активен
if (_wallClimbAppliedThisFrame || _isSliding) return;
// Проверяем, что это вертикальная или почти вертикальная поверхность (стена)
var dotWithUp = Vector3.Dot(hitNormal, motor.CharacterUp);
if (Mathf.Abs(dotWithUp) > 0.1f) return; // Не стена — это пол или потолок
// Получаем текущую скорость персонажа
var currentVelocity = motor.Velocity;
// Проекция скорости на направление к стене (отрицательная, если летим в стену)
var velocityIntoWall = Vector3.Dot(currentVelocity, -hitNormal);
// Если движемся в стену с достаточной скоростью
if (velocityIntoWall > minWallClimbSpeed)
{
// Преобразуем часть горизонтальной скорости в вертикальную
var verticalBoost = velocityIntoWall * wallClimbSpeedFactor;
// Добавляем вертикальный импульс через BaseVelocity
motor.BaseVelocity += motor.CharacterUp * verticalBoost;
// Предотвращаем заземление и повторное применение в этом кадре
motor.ForceUnground();
_wallClimbAppliedThisFrame = true;
}
} }
// Обработка отчета о стабильности столкновения // Обработка отчета о стабильности столкновения
@@ -993,6 +993,8 @@ MonoBehaviour:
stableMovementSharpness: 15 stableMovementSharpness: 15
orientationSharpness: 10 orientationSharpness: 10
jumpSpeed: 10 jumpSpeed: 10
wallClimbSpeedFactor: 0.8
minWallClimbSpeed: 9
gravity: {x: 0, y: -30, z: 0} gravity: {x: 0, y: -30, z: 0}
--- !u!1 &1959874989 --- !u!1 &1959874989
GameObject: GameObject: