Инишиал механика наклона при залазании на стены

Нуждается в доработке (как минимум чтобы вращалось в правильную сторону), но вроде-как выглядит прикольно
This commit is contained in:
MrTorex committed 2025-10-29 15:00:25 +03:00
1 parent 07ce27618c
commit 0e188efe59
7 files changed
+170 -38

No files matched your search

@@ -20,14 +20,16 @@ namespace Code.Gameplay.Character.Controller
public class CustomCharacterController : MonoBehaviour, ICharacterController
{
[Inject] private CharacterConfig _characterConfig; // Конфиг персонажа через DI
[SerializeField]
private KinematicCharacterMotor motor; // Движок физического перемещения персонажа
[SerializeField] private KinematicCharacterMotor motor; // Движок физического перемещения персонажа
[SerializeField] private Transform characterTransform; // Трансформ персонажа (с точкой отслеживания камеры)
// Подсистемы
private CharacterInputHandler _inputHandler;
private SlideMechanic _slideMechanic;
private WallClimbMechanic _wallClimbMechanic;
private WallLeanMechanic _wallLeanMechanic;
private GroundMovementSystem _groundMovement;
private AirMovementSystem _airMovement;
@@ -48,6 +50,11 @@ namespace Code.Gameplay.Character.Controller
_characterConfig.minWallClimbSpeed,
_characterConfig.wallDetectionAngleThreshold
);
_wallLeanMechanic = new WallLeanMechanic(
_characterConfig.maxWallLeanAngle,
_characterConfig.wallLeanSharpness,
_characterConfig.wallLeanHeightScale
);
_groundMovement = new GroundMovementSystem(
_characterConfig.maxStableMoveSpeed,
_characterConfig.sprintMoveSpeed,
@@ -56,7 +63,7 @@ namespace Code.Gameplay.Character.Controller
);
_airMovement = new AirMovementSystem(_characterConfig.gravity);
}
// Текущий режим камеры для адаптации поведения
private CameraMode _currentCameraMode = CameraMode.FirstPerson;
@@ -64,7 +71,9 @@ namespace Code.Gameplay.Character.Controller
private void Start()
{
motor.CharacterController = this; // Регистрация этого контроллера в движке
_inputHandler.FirstPersonCameraRotation = motor.Transform.rotation; // Начальное вращение совпадает с персонажем
_inputHandler.FirstPersonCameraRotation =
motor.Transform.rotation; // Начальное вращение совпадает с персонажемс
_wallLeanMechanic.SetCharacterTransform(characterTransform);
}
// Обработка и преобразование входных данных от персонажа
@@ -72,7 +81,7 @@ namespace Code.Gameplay.Character.Controller
{
// Обновляем таймер перезарядки слайда
_slideMechanic.TickCooldown(Time.deltaTime);
// Если активен слайд - игнорируем весь остальной ввод
if (_slideMechanic.IsSliding)
{
@@ -83,16 +92,16 @@ namespace Code.Gameplay.Character.Controller
_groundMovement.RequestJump(inputs.JumpPressed);
return;
}
// Сохраняем текущий режим камеры
_currentCameraMode = inputs.CameraMode;
// Обработка слайда
_slideMechanic.RequestSlide(inputs.SlidePressed);
// Обработка остального ввода
_inputHandler.ProcessInputs(ref inputs, motor);
// Передаём запрос прыжка напрямую в систему движения по земле
_groundMovement.RequestJump(inputs.JumpPressed);
}
@@ -118,8 +127,8 @@ namespace Code.Gameplay.Character.Controller
{
// Плавная интерполяция текущего направления к целевому с экспоненциальным сглаживанием
var smoothedLookInputDirection = Vector3.Slerp(
motor.CharacterForward,
_inputHandler.LookInputVector,
motor.CharacterForward,
_inputHandler.LookInputVector,
1f - Mathf.Exp(-_characterConfig.orientationSharpness * deltaTime)
).normalized;
@@ -146,11 +155,12 @@ namespace Code.Gameplay.Character.Controller
{
_slideMechanic.EndSlide();
}
// Проверяем запрос слайда и запускаем его если можно
if (!_slideMechanic.IsSliding)
{
_slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation, _inputHandler.LookInputVector);
_slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation,
_inputHandler.LookInputVector);
}
// Если активен слайд - обрабатываем отдельно
else
@@ -158,7 +168,7 @@ namespace Code.Gameplay.Character.Controller
_slideMechanic.HandleSlide(ref currentVelocity, deltaTime, motor);
return;
}
// Если персонаж находится на земле
if (motor.GroundingStatus.IsStableOnGround)
{
@@ -188,9 +198,10 @@ namespace Code.Gameplay.Character.Controller
}
}
// Метод вызывается после обновления персонажа (можно использовать для пост-обработки)
// Метод вызывается после обновления персонажа
public void AfterCharacterUpdate(float deltaTime)
{
_wallLeanMechanic.UpdateLean(motor, deltaTime);
}
// Проверка валидности коллайдера для обработки столкновений
@@ -200,7 +211,8 @@ namespace Code.Gameplay.Character.Controller
}
// Обработка столкновения с землей (вызывается при приземлении)
public void OnGroundHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, ref HitStabilityReport hitStabilityReport)
public void OnGroundHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
ref HitStabilityReport hitStabilityReport)
{
}
@@ -209,10 +221,17 @@ namespace Code.Gameplay.Character.Controller
ref HitStabilityReport hitStabilityReport)
{
_wallClimbMechanic.OnMovementHit(motor, hitNormal);
var dotWithUp = Vector3.Dot(hitNormal, motor.CharacterUp);
if (Mathf.Abs(dotWithUp) <= _wallClimbMechanic.WallNormalThreshold)
{
_wallLeanMechanic.OnWallContact(hitNormal, motor.TransientPosition.y);
}
}
// Обработка отчета о стабильности столкновения
public void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, Vector3 atCharacterPosition,
public void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint,
Vector3 atCharacterPosition,
Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport)
{
}