Соединение всё со всем что имеется, дописывание стейт-машины

Теперь мне удобно кастить и получать тип камеры, всё вроде работает нормисно
This commit is contained in:
MrTorex committed 2025-10-29 01:02:02 +03:00
1 parent 4549617275
commit 665114b7dc
28 files changed
+292 -598

No files matched your search

@@ -1,153 +1,43 @@
using System;
using Code.Input;
using Code.StateMachine;
using UnityEngine;
namespace Code.Gameplay.Camera.CameraStates
{
public class FirstPersonState : BaseState<CameraStateMachineContext>
/*
* Состояние камеры от первого лица
* Камера размещается непосредственно на позиции цели (например, на уровне глаз персонажа)
* Дистанция до цели принудительно устанавливается в 0
* Вращение управляется мышью, позиция следует за целью без отступа
*/
public class FirstPersonState : BaseCameraState, ICameraState
{
// Параметры загружаются из CameraConfig
private float
_defaultDistance,
_minDistance,
_maxDistance,
_distanceMovementSpeed,
_rotationSpeed,
_rotationSharpness,
_followSharpness,
_minVerticalAngle,
_maxVerticalAngle,
_defaultVerticalAngle;
// Трансформ объекта, за которым следует камера (для 1st-person: уровень глаз)
private Transform _followTransform;
// Позиция следования: текущая сглаженная позиция и горизонтальное направление камеры
private Vector3 _currentFollowPosition;
// Fallback-позиция для режимов без цели (например, MainMenu)
private Vector3 _defaultFollowPosition;
// Целевой вертикальный угол камеры (наклон вверх/вниз)
private float _targetVerticalAngle;
// Текущая и целевая дистанция камеры от цели
private float _currentDistance, _targetDistance;
// Исходные значения дистанции для восстановления после FirstPerson режима
private float _originalDefaultDistance, _originalMinDistance, _originalMaxDistance;
// Горизонтальное направление камеры (проекция forward на плоскость)
public Vector3 PlanarDirection { get; private set; }
public FirstPersonState(CameraStateMachineContext context) : base(context) { }
private IInputService _inputService;
private UnityEngine.Camera _camera;
public FirstPersonState(CameraStateMachineContext context) : base(context)
{
_inputService = context.InputService;
// Загрузка значений из конфига
_defaultDistance = context.Config.defaultDistance;
_minDistance = context.Config.minDistance;
_maxDistance = context.Config.maxDistance;
_distanceMovementSpeed = context.Config.distanceMovementSpeed;
_rotationSpeed = context.Config.rotationSpeed;
_rotationSharpness = context.Config.rotationSharpness;
_followSharpness = context.Config.followSharpness;
_minVerticalAngle = context.Config.minVerticalAngle;
_maxVerticalAngle = context.Config.maxVerticalAngle;
_defaultVerticalAngle = context.Config.defaultVerticalAngle;
_defaultFollowPosition = context.Config.defaultFollowPosition;
// Валидация значений (на случай ручного редактирования конфига)
_defaultDistance = Mathf.Clamp(_defaultDistance, _minDistance, _maxDistance);
_defaultVerticalAngle = Mathf.Clamp(_defaultVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
// Сохраняем оригинальные значения для восстановления
_originalDefaultDistance = _defaultDistance;
_originalMinDistance = _minDistance;
_originalMaxDistance = _maxDistance;
// Инициализация состояния камеры
_currentDistance = _defaultDistance;
_targetDistance = _currentDistance;
_targetVerticalAngle = _defaultVerticalAngle;
PlanarDirection = Vector3.forward; // Начальное направление - вперед по оси Z
_currentFollowPosition = _defaultFollowPosition;
}
public override void EnterState()
{
// В FirstPerson режиме дистанция всегда равна 0
_minDistance = 0f;
_maxDistance = 0f;
_defaultDistance = 0f;
_targetDistance = 0f;
_currentDistance = 0f;
MinDistance = 0f;
MaxDistance = 0f;
DefaultDistance = 0f;
TargetDistance = 0f;
CurrentDistance = 0f;
_camera = Context.Camera;
base.EnterState();
}
public override void LateTick()
{
UpdateWithInput(Time.deltaTime,_inputService.ZoomInput, _inputService.LookInput);
}
// Обработка вращения камеры на основе пользовательского ввода
private void HandleRotationInput(float deltaTime, Vector3 rotationInput, out Quaternion targetRotation)
{
// Вращение вокруг вертикальной оси (горизонтальный поворот)
var rotationFromInput = Quaternion.Euler(_followTransform.up * (rotationInput.x * _rotationSpeed));
PlanarDirection = rotationFromInput * PlanarDirection;
var planarRotation = Quaternion.LookRotation(PlanarDirection, _followTransform.up);
// Вращение вокруг горизонтальной оси (вертикальный наклон)
_targetVerticalAngle -= rotationInput.y * _rotationSpeed;
_targetVerticalAngle = Math.Clamp(_targetVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
var verticalRotation = Quaternion.Euler(_targetVerticalAngle, 0, 0);
// Интерполяция к целевому вращению для плавности
targetRotation = Quaternion.Slerp(_camera.transform.rotation, planarRotation * verticalRotation, deltaTime * _rotationSharpness);
Debug.Log(_camera.transform.rotation.eulerAngles);
// Применение финального вращения
_camera.transform.rotation = targetRotation;
Debug.Log(_camera.transform.rotation.eulerAngles);
}
// Обработка позиционирования камеры и зума с учетом текущего режима
private void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
protected override void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
{
// Плавное следование за целью с использованием экспоненциального сглаживания
_currentFollowPosition = Vector3.Lerp(_currentFollowPosition, _followTransform.position, 1f - Mathf.Exp(-_followSharpness * deltaTime));
CurrentFollowPosition = Vector3.Lerp(CurrentFollowPosition, FollowTransform.position, 1f - Mathf.Exp(-FollowSharpness * deltaTime));
// Вычисление целевой позиции камеры с учетом текущего режима
Vector3 targetPosition;
// В FirstPerson режиме камера находится прямо на позиции цели
targetPosition = _currentFollowPosition;
// В FirstPerson режиме камера находится прямо на позиции цели
var targetPosition = CurrentFollowPosition;
// Установка финальной позиции камеры
_camera.transform.position = targetPosition;
Camera.transform.position = targetPosition;
}
// Основной метод обновления камеры, вызываемый извне каждый кадр
public void UpdateWithInput(float deltaTime, float zoomInput, Vector3 rotationInput)
public CameraMode GetCameraMode()
{
// Проверка наличия цели для следования и проверка на режим главного меню
if (!_followTransform) return;
// Обработка ввода и позиционирования
HandleRotationInput(deltaTime, rotationInput, out var targetRotation);
HandlePosition(deltaTime, zoomInput, targetRotation);
}
// Установка цели для следования камеры
public void SetFollowTransform(Transform t)
{
_followTransform = t;
_currentFollowPosition = t.position;
PlanarDirection = t.forward; // Начальное направление совпадает с направлением цели
return CameraMode.FirstPerson;
}
}
}