111 lines
6.3 KiB
C#
111 lines
6.3 KiB
C#
using Code.Gameplay.Camera;
|
||
using UnityEngine;
|
||
using Code.Gameplay.Character.Core;
|
||
using KinematicCharacterController;
|
||
|
||
namespace Code.Gameplay.Character.Controller.Input
|
||
{
|
||
/*
|
||
* Обработчик входных данных для персонажа
|
||
* Преобразует сырые данные ввода в векторы движения и направления взгляда
|
||
*/
|
||
public class CharacterInputHandler
|
||
{
|
||
|
||
// Векторы движения и направления взгляда
|
||
public Vector3 MoveInputVector { get; set; }
|
||
public Vector3 LookInputVector { get; set; }
|
||
|
||
// Вращение камеры в FirstPerson режиме для синхронизации (только горизонтальная компонента)
|
||
public Quaternion FirstPersonCameraRotation { get; set; }
|
||
|
||
// Флаг-свойство указывающий, что нужно применить вращение камеры к персонажу
|
||
public bool ShouldApplyCameraRotation { get; private set; }
|
||
|
||
// Обработка и преобразование входных данных от персонажа
|
||
public void ProcessInputs(ref CharacterInputs inputs, KinematicCharacterMotor motor)
|
||
{
|
||
// Сохраняем текущий режим камеры
|
||
var currentCameraMode = inputs.CameraMode;
|
||
|
||
// Нормализация вектора движения и ограничение его величины до 1
|
||
var moveInputVector =
|
||
Vector3.ClampMagnitude(new Vector3(inputs.MoveAxisRight, 0, inputs.MoveAxisForward), 1f);
|
||
|
||
// Раздельная обработка в зависимости от режима камеры
|
||
if (currentCameraMode == CameraMode.FirstPerson)
|
||
{
|
||
HandleFirstPersonInputs(ref inputs, moveInputVector, motor);
|
||
}
|
||
else
|
||
{
|
||
HandleThirdPersonInputs(ref inputs, moveInputVector, motor);
|
||
}
|
||
}
|
||
|
||
// Обработка ввода для FirstPerson режима
|
||
private void HandleFirstPersonInputs(ref CharacterInputs inputs, Vector3 moveInputVector, KinematicCharacterMotor motor)
|
||
{
|
||
// Сохраняем вращение камеры для применения в UpdateRotation (только горизонтальная компонента)
|
||
FirstPersonCameraRotation = ExtractHorizontalRotation(inputs.CameraRotation, motor);
|
||
ShouldApplyCameraRotation = true;
|
||
|
||
// В FirstPerson режиме движение всегда относительно направления камеры
|
||
// Получаем направление камеры в горизонтальной плоскости
|
||
var cameraPlanarDirection = inputs.CameraPlanarDirection;
|
||
|
||
// Создание вращения на основе направления камеры
|
||
var cameraPlanarRotation = Quaternion.LookRotation(cameraPlanarDirection, motor.CharacterUp);
|
||
|
||
// Преобразование локального ввода в мировые координаты относительно камеры
|
||
MoveInputVector = cameraPlanarRotation * moveInputVector;
|
||
|
||
// В FirstPerson режиме направление взгляда всегда совпадает с направлением камеры (горизонтально)
|
||
LookInputVector = cameraPlanarDirection;
|
||
}
|
||
|
||
// Обработка ввода для ThirdPerson режима
|
||
private void HandleThirdPersonInputs(ref CharacterInputs inputs, Vector3 moveInputVector, KinematicCharacterMotor motor)
|
||
{
|
||
// Сбрасываем флаг применения вращения камеры
|
||
ShouldApplyCameraRotation = false;
|
||
|
||
// Получение направления камеры в горизонтальной плоскости (игнорируя наклон)
|
||
var cameraPlanarDirection = inputs.CameraPlanarDirection;
|
||
|
||
// Резервный расчет направления, если основное направление параллельно вертикали
|
||
if (cameraPlanarDirection.sqrMagnitude == 0f)
|
||
{
|
||
cameraPlanarDirection = Vector3.ProjectOnPlane(inputs.CameraRotation * Vector3.up, motor.CharacterUp);
|
||
}
|
||
|
||
// Создание вращения на основе направления камеры
|
||
var cameraPlanarRotation = Quaternion.LookRotation(cameraPlanarDirection, motor.CharacterUp);
|
||
|
||
// Преобразование локального ввода в мировые координаты относительно камеры
|
||
MoveInputVector = cameraPlanarRotation * moveInputVector;
|
||
|
||
// Направление взгляда совпадает с направлением движения (нормализованное)
|
||
LookInputVector = MoveInputVector.normalized;
|
||
}
|
||
|
||
// Извлечение только горизонтальной компоненты вращения (игнорируя наклон камеры)
|
||
private static Quaternion ExtractHorizontalRotation(Quaternion cameraRotation, KinematicCharacterMotor motor)
|
||
{
|
||
// Получаем вектор направления камеры
|
||
var cameraForward = cameraRotation * Vector3.forward;
|
||
|
||
// Проецируем на горизонтальную плоскость
|
||
var horizontalForward = Vector3.ProjectOnPlane(cameraForward, Vector3.up).normalized;
|
||
|
||
// Если проекция вырождена, используем текущее направление персонажа
|
||
if (horizontalForward.sqrMagnitude < 0.01f)
|
||
{
|
||
horizontalForward = motor.CharacterForward;
|
||
}
|
||
|
||
// Создаем вращение только по горизонтали
|
||
return Quaternion.LookRotation(horizontalForward, motor.CharacterUp);
|
||
}
|
||
}
|
||
} |