Продолжение багфикса
This commit is contained in:
1 parent
dbabd847c1
commit
0e1c274677
2 files changed
+44
-8
No files matched your search
+37
-2
@@ -16,6 +16,12 @@ namespace Code.Gameplay.Character.Controller.Abilities
|
|||||||
// Пороговый косинус стены
|
// Пороговый косинус стены
|
||||||
public float WallNormalThreshold { get; }
|
public float WallNormalThreshold { get; }
|
||||||
|
|
||||||
|
private bool _hasClimbedThisWallSession;
|
||||||
|
private float _wallClimbCooldownTimer;
|
||||||
|
private readonly float _wallClimbCooldownDuration = 1.5f;
|
||||||
|
public bool IsWallInteractionAllowed =>
|
||||||
|
!_hasClimbedThisWallSession && _wallClimbCooldownTimer <= 0f;
|
||||||
|
|
||||||
// Конструктор механики залазания на стену
|
// Конструктор механики залазания на стену
|
||||||
public WallClimbMechanic(float wallClimbSpeedFactor, float minWallClimbSpeed, float wallDetectionAngleThreshold)
|
public WallClimbMechanic(float wallClimbSpeedFactor, float minWallClimbSpeed, float wallDetectionAngleThreshold)
|
||||||
{
|
{
|
||||||
@@ -26,11 +32,21 @@ namespace Code.Gameplay.Character.Controller.Abilities
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Обработка столкновения при движении (вызывается при ударе о препятствие)
|
// Обработка столкновения при движении (вызывается при ударе о препятствие)
|
||||||
public void OnMovementHit(KinematicCharacterMotor motor, Vector3 hitNormal)
|
public bool TryClimbWall(KinematicCharacterMotor motor, Vector3 hitNormal)
|
||||||
{
|
{
|
||||||
// Проверяем, что это вертикальная или почти вертикальная поверхность (стена)
|
// Проверяем, что это вертикальная или почти вертикальная поверхность (стена)
|
||||||
var dotWithUp = Vector3.Dot(hitNormal, motor.CharacterUp);
|
var dotWithUp = Vector3.Dot(hitNormal, motor.CharacterUp);
|
||||||
if (Mathf.Abs(dotWithUp) > WallNormalThreshold) return; // Не стена — это пол или потолок
|
|
||||||
|
if (Mathf.Abs(dotWithUp) > WallNormalThreshold)
|
||||||
|
{
|
||||||
|
// Сбрасываем сессию, если коснулись пола/потолка → выход из "режима стены"
|
||||||
|
_hasClimbedThisWallSession = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запрещаем повторное залазание в рамках одной сессии
|
||||||
|
if (_hasClimbedThisWallSession || _wallClimbCooldownTimer > 0f)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Получаем текущую скорость персонажа
|
// Получаем текущую скорость персонажа
|
||||||
var currentVelocity = motor.Velocity;
|
var currentVelocity = motor.Velocity;
|
||||||
@@ -41,6 +57,7 @@ namespace Code.Gameplay.Character.Controller.Abilities
|
|||||||
// Если движемся в стену с достаточной скоростью
|
// Если движемся в стену с достаточной скоростью
|
||||||
if (velocityIntoWall > _minWallClimbSpeed)
|
if (velocityIntoWall > _minWallClimbSpeed)
|
||||||
{
|
{
|
||||||
|
_wallClimbCooldownTimer = _wallClimbCooldownDuration;
|
||||||
// Преобразуем часть горизонтальной скорости в вертикальную
|
// Преобразуем часть горизонтальной скорости в вертикальную
|
||||||
var verticalBoost = velocityIntoWall * _wallClimbSpeedFactor;
|
var verticalBoost = velocityIntoWall * _wallClimbSpeedFactor;
|
||||||
|
|
||||||
@@ -49,6 +66,24 @@ namespace Code.Gameplay.Character.Controller.Abilities
|
|||||||
|
|
||||||
// Предотвращаем заземление и повторное применение в этом кадре
|
// Предотвращаем заземление и повторное применение в этом кадре
|
||||||
motor.ForceUnground();
|
motor.ForceUnground();
|
||||||
|
_hasClimbedThisWallSession = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetWallClimbSession()
|
||||||
|
{
|
||||||
|
_hasClimbedThisWallSession = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TickCooldown(float deltaTime)
|
||||||
|
{
|
||||||
|
if (_wallClimbCooldownTimer > 0f)
|
||||||
|
{
|
||||||
|
_wallClimbCooldownTimer -= deltaTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-6
@@ -81,6 +81,7 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
{
|
{
|
||||||
// Обновляем таймер перезарядки слайда
|
// Обновляем таймер перезарядки слайда
|
||||||
_slideMechanic.TickCooldown(Time.deltaTime);
|
_slideMechanic.TickCooldown(Time.deltaTime);
|
||||||
|
_wallClimbMechanic.TickCooldown(Time.deltaTime);
|
||||||
|
|
||||||
// Если активен слайд - игнорируем весь остальной ввод
|
// Если активен слайд - игнорируем весь остальной ввод
|
||||||
if (_slideMechanic.IsSliding)
|
if (_slideMechanic.IsSliding)
|
||||||
@@ -196,6 +197,11 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
{
|
{
|
||||||
_slideMechanic.EndSlide();
|
_slideMechanic.EndSlide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (motor.GroundingStatus.IsStableOnGround)
|
||||||
|
{
|
||||||
|
_wallClimbMechanic.ResetWallClimbSession();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Метод вызывается после обновления персонажа
|
// Метод вызывается после обновления персонажа
|
||||||
@@ -220,13 +226,8 @@ namespace Code.Gameplay.Character.Controller
|
|||||||
public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
|
public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
|
||||||
ref HitStabilityReport hitStabilityReport)
|
ref HitStabilityReport hitStabilityReport)
|
||||||
{
|
{
|
||||||
_wallClimbMechanic.OnMovementHit(motor, hitNormal);
|
if (_wallClimbMechanic.TryClimbWall(motor, hitNormal))
|
||||||
|
|
||||||
var dotWithUp = Vector3.Dot(hitNormal, motor.CharacterUp);
|
|
||||||
if (Mathf.Abs(dotWithUp) <= _wallClimbMechanic.WallNormalThreshold)
|
|
||||||
{
|
|
||||||
_wallLeanMechanic.OnWallContact(motor, hitNormal, motor.TransientPosition.y);
|
_wallLeanMechanic.OnWallContact(motor, hitNormal, motor.TransientPosition.y);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обработка отчета о стабильности столкновения
|
// Обработка отчета о стабильности столкновения
|
||||||
|
|||||||
Reference in new issue
Block a user