Revert "Добавлено нормальное переключение между FirstPerson и ThirdPerson камерами, правильная логика работы FirstPerson камеры (игрок поворачивается вместе с ней), добавлены заготовки для других камер, стабилизированы настройки камеры. Перехожу к движению"
This reverts commit bd0cee77a6.
This commit is contained in:
1 parent
95ceaaa680
commit
eb3be451b3
11 files changed
+87
-760
No files matched your search
@@ -3,26 +3,22 @@ using UnityEngine;
|
||||
|
||||
namespace Code.Gameplay.Player
|
||||
{
|
||||
/*
|
||||
* Структура для хранения входных данных от игрока
|
||||
* Содержит информацию о движении и состоянии камеры
|
||||
*/
|
||||
public struct PlayerInputs
|
||||
{
|
||||
public float MoveAxisForward; // Ввод движения вперед/назад (W/S или Up/Down)
|
||||
public float MoveAxisRight; // Ввод движения влево/вправо (A/D или Left/Right)
|
||||
public Quaternion CameraRotation; // Текущее вращение камеры для определения направления движения
|
||||
public CameraMode CameraMode; // Текущий режим камеры для адаптации поведения
|
||||
public Vector3 CameraPlanarDirection; // Направление камеры в горизонтальной плоскости
|
||||
}
|
||||
|
||||
/*
|
||||
* Скрипт, отвечающий за передвижения игрока
|
||||
* Реализует физическое движение персонажа с использованием Kinematic Character Controller
|
||||
* Обрабатывает ввод пользователя, применяет движение и вращение с учетом поверхности
|
||||
*
|
||||
* Источник: Tvtig, https://www.youtube.com/watch?v=9ibpY64wBYM
|
||||
*/
|
||||
*/
|
||||
|
||||
// Структура для хранения входных данных от игрока
|
||||
public struct PlayerInputs
|
||||
{
|
||||
public float MoveAxisForward; // Ввод движения вперед/назад (W/S или Up/Down)
|
||||
public float MoveAxisRight; // Ввод движения влево/вправо (A/D или Left/Right)
|
||||
public Quaternion CameraRotation; // Текущее вращение камеры для определения направления движения
|
||||
}
|
||||
|
||||
public class CharacterController : MonoBehaviour, ICharacterController
|
||||
{
|
||||
[SerializeField]
|
||||
@@ -37,143 +33,54 @@ namespace Code.Gameplay.Player
|
||||
// Векторы движения и направления взгляда
|
||||
private Vector3 _moveInputVector, _lookInputVector;
|
||||
|
||||
// Текущий режим камеры для адаптации поведения
|
||||
private CameraMode _currentCameraMode = CameraMode.ThirdPerson;
|
||||
|
||||
// Вращение камеры в FirstPerson режиме для синхронизации (только горизонтальная компонента)
|
||||
private Quaternion _firstPersonCameraRotation;
|
||||
|
||||
// Флаг указывающий, что нужно применить вращение камеры к персонажу
|
||||
private bool _shouldApplyCameraRotation;
|
||||
|
||||
// Инициализация контроллера
|
||||
private void Start()
|
||||
{
|
||||
motor.CharacterController = this; // Регистрация этого контроллера в движке
|
||||
_firstPersonCameraRotation = motor.Transform.rotation; // Начальное вращение совпадает с персонажем
|
||||
}
|
||||
|
||||
// Обработка и преобразование входных данных от игрока
|
||||
public void SetInputs(ref PlayerInputs inputs)
|
||||
{
|
||||
// Сохраняем текущий режим камеры
|
||||
_currentCameraMode = inputs.CameraMode;
|
||||
|
||||
// Нормализация вектора движения и ограничение его величины до 1
|
||||
var moveInputVector =
|
||||
Vector3 moveInputVector =
|
||||
Vector3.ClampMagnitude(new Vector3(inputs.MoveAxisRight, 0, inputs.MoveAxisForward), 1f);
|
||||
|
||||
// Раздельная обработка в зависимости от режима камеры
|
||||
if (_currentCameraMode == CameraMode.FirstPerson)
|
||||
{
|
||||
HandleFirstPersonInputs(ref inputs, moveInputVector);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleThirdPersonInputs(ref inputs, moveInputVector);
|
||||
}
|
||||
}
|
||||
|
||||
// Обработка ввода для FirstPerson режима
|
||||
private void HandleFirstPersonInputs(ref PlayerInputs inputs, Vector3 moveInputVector)
|
||||
{
|
||||
// Сохраняем вращение камеры для применения в UpdateRotation (только горизонтальная компонента)
|
||||
_firstPersonCameraRotation = ExtractHorizontalRotation(inputs.CameraRotation);
|
||||
_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 PlayerInputs inputs, Vector3 moveInputVector)
|
||||
{
|
||||
// Сбрасываем флаг применения вращения камеры
|
||||
_shouldApplyCameraRotation = false;
|
||||
|
||||
|
||||
// Получение направления камеры в горизонтальной плоскости (игнорируя наклон)
|
||||
var cameraPlanarDirection = inputs.CameraPlanarDirection;
|
||||
Vector3 cameraPlanarDirection =
|
||||
Vector3.ProjectOnPlane(inputs.CameraRotation * Vector3.forward, motor.CharacterUp).normalized;
|
||||
|
||||
// Резервный расчет направления, если основное направление параллельно вертикали
|
||||
if (cameraPlanarDirection.sqrMagnitude == 0f)
|
||||
{
|
||||
cameraPlanarDirection = Vector3.ProjectOnPlane(inputs.CameraRotation * Vector3.up, motor.CharacterUp);
|
||||
}
|
||||
|
||||
|
||||
// Создание вращения на основе направления камеры
|
||||
var cameraPlanarRotation = Quaternion.LookRotation(cameraPlanarDirection, motor.CharacterUp);
|
||||
|
||||
Quaternion cameraPlanarRotation = Quaternion.LookRotation(cameraPlanarDirection, motor.CharacterUp);
|
||||
|
||||
// Преобразование локального ввода в мировые координаты относительно камеры
|
||||
_moveInputVector = cameraPlanarRotation * moveInputVector;
|
||||
|
||||
|
||||
// Направление взгляда совпадает с направлением движения (нормализованное)
|
||||
_lookInputVector = _moveInputVector.normalized;
|
||||
}
|
||||
|
||||
// Извлечение только горизонтальной компоненты вращения (игнорируя наклон камеры)
|
||||
private Quaternion ExtractHorizontalRotation(Quaternion cameraRotation)
|
||||
{
|
||||
// Получаем вектор направления камеры
|
||||
var cameraForward = cameraRotation * Vector3.forward;
|
||||
|
||||
// Проецируем на горизонтальную плоскость
|
||||
var horizontalForward = Vector3.ProjectOnPlane(cameraForward, motor.CharacterUp).normalized;
|
||||
|
||||
// Если проекция вырождена, используем текущее направление персонажа
|
||||
if (horizontalForward.sqrMagnitude < 0.01f)
|
||||
{
|
||||
horizontalForward = motor.CharacterForward;
|
||||
}
|
||||
|
||||
// Создаем вращение только по горизонтали
|
||||
return Quaternion.LookRotation(horizontalForward, motor.CharacterUp);
|
||||
}
|
||||
|
||||
// Обновление вращения персонажа на основе входных данных
|
||||
public void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
|
||||
{
|
||||
switch (_currentCameraMode)
|
||||
// Вращение применяется только если есть направление движения и разрешена резкость вращения
|
||||
if (_lookInputVector.sqrMagnitude > 0 && orientationSharpness > 0)
|
||||
{
|
||||
// В FirstPerson режиме применяем вращение камеры напрямую к персонажу (только горизонталь)
|
||||
case CameraMode.FirstPerson when _shouldApplyCameraRotation:
|
||||
// Немедленно применяем горизонтальное вращение камеры к персонажу
|
||||
currentRotation = _firstPersonCameraRotation;
|
||||
_shouldApplyCameraRotation = false;
|
||||
break;
|
||||
// В ThirdPerson режиме плавно поворачиваем персонаж в направлении движения
|
||||
case CameraMode.ThirdPerson:
|
||||
{
|
||||
// Вращение применяется только если есть направление движения и разрешена резкость вращения
|
||||
if (_lookInputVector.sqrMagnitude > 0 && orientationSharpness > 0)
|
||||
{
|
||||
// Плавная интерполяция текущего направления к целевому с экспоненциальным сглаживанием
|
||||
var smoothedLookInputDirection = Vector3.Slerp(
|
||||
motor.CharacterForward,
|
||||
_lookInputVector,
|
||||
1f - Mathf.Exp(-orientationSharpness * deltaTime)
|
||||
).normalized;
|
||||
|
||||
// Установка нового вращения смотря в сглаженном направлении
|
||||
currentRotation = Quaternion.LookRotation(smoothedLookInputDirection, motor.CharacterUp);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// Заготовка на будущее (если понадобится)
|
||||
case CameraMode.Static:
|
||||
case CameraMode.Cinematic:
|
||||
default:
|
||||
break;
|
||||
// Плавная интерполяция текущего направления к целевому с экспоненциальным сглаживанием
|
||||
Vector3 smoothedLookInputDirection = Vector3.Slerp(
|
||||
motor.CharacterForward,
|
||||
_lookInputVector,
|
||||
1f - Mathf.Exp(-orientationSharpness * deltaTime)
|
||||
).normalized;
|
||||
|
||||
// Установка нового вращения смотря в сглаженном направлении
|
||||
currentRotation = Quaternion.LookRotation(smoothedLookInputDirection, motor.CharacterUp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,20 +88,20 @@ namespace Code.Gameplay.Player
|
||||
public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
|
||||
{
|
||||
// Сохранение текущей величины скорости
|
||||
var currentVelocityMagnitude = currentVelocity.magnitude;
|
||||
float currentVelocityMagnitude = currentVelocity.magnitude;
|
||||
|
||||
// Получение нормали поверхности для корректного движения по наклонным плоскостям
|
||||
var effectiveGroundNormal = motor.GroundingStatus.GroundNormal;
|
||||
Vector3 effectiveGroundNormal = motor.GroundingStatus.GroundNormal;
|
||||
|
||||
// Переориентация текущей скорости вдоль поверхности
|
||||
currentVelocity = motor.GetDirectionTangentToSurface(currentVelocity, effectiveGroundNormal) * currentVelocityMagnitude;
|
||||
|
||||
// Переориентация входного вектора движения вдоль поверхности
|
||||
var inputRight = Vector3.Cross(_moveInputVector, motor.CharacterUp);
|
||||
var reorientedInput = Vector3.Cross(effectiveGroundNormal, inputRight).normalized * _moveInputVector.magnitude;
|
||||
Vector3 inputRight = Vector3.Cross(_moveInputVector, motor.CharacterUp);
|
||||
Vector3 reorientedInput = Vector3.Cross(effectiveGroundNormal, inputRight).normalized * _moveInputVector.magnitude;
|
||||
|
||||
// Расчет целевой скорости движения с учетом ограничения максимальной скорости
|
||||
var targetMovementVelocity = reorientedInput * maxStableMoveSpeed;
|
||||
Vector3 targetMovementVelocity = reorientedInput * maxStableMoveSpeed;
|
||||
|
||||
// Плавная интерполяция текущей скорости к целевой с экспоненциальным сглаживанием
|
||||
currentVelocity = Vector3.Lerp(
|
||||
|
||||
@@ -4,113 +4,52 @@ using Reflex.Attributes;
|
||||
using UnityEngine;
|
||||
using CharacterController = Code.Gameplay.Player.CharacterController;
|
||||
|
||||
/*
|
||||
* Главный скрипт игрока, объединяющий камеру и контроллер персонажа
|
||||
* Обрабатывает ввод пользователя и распределяет его между компонентами
|
||||
* Синхронизирует состояние камеры и персонажа
|
||||
* Управляет переключением режимов камеры через Input System
|
||||
*/
|
||||
public class Player : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private PlayerCamera playerCamera; // Компонент камеры игрока
|
||||
private PlayerCamera playerCamera;
|
||||
[SerializeField]
|
||||
private CharacterController characterController; // Компонент управления персонажем
|
||||
private CharacterController characterController;
|
||||
[SerializeField]
|
||||
private Transform cameraFollowPoint; // Точка следования камеры (уровень глаз для FirstPerson)
|
||||
private Transform cameraFollowPoint;
|
||||
[Inject] private IInputService _inputService;
|
||||
|
||||
[Inject]
|
||||
private IInputService _inputService; // Сервис ввода через DI
|
||||
private Vector3 _lookInputVector;
|
||||
|
||||
// Флаг для отслеживания переключения режима камеры (чтобы избежать многократных срабатываний)
|
||||
private bool _cameraModeToggleHandled;
|
||||
|
||||
// Инициализация игрока
|
||||
private void Start()
|
||||
{
|
||||
// Настройка камеры для следования за точкой камеры
|
||||
playerCamera.SetFollowTransform(cameraFollowPoint);
|
||||
|
||||
// Включение Gameplay мапа ввода
|
||||
_inputService.EnableMap(ActionMappings.Gameplay);
|
||||
}
|
||||
|
||||
// Обработка ввода для камеры (вращение и зум)
|
||||
|
||||
private void HandleCameraInput()
|
||||
{
|
||||
// Получаем данные ввода из Input System
|
||||
var lookInput = _inputService.LookInput;
|
||||
var scrollInput = _inputService.ZoomInput;
|
||||
|
||||
// Передаем данные в камеру
|
||||
|
||||
playerCamera.UpdateWithInput(Time.deltaTime, scrollInput,
|
||||
new Vector3(lookInput.x, lookInput.y, 0));
|
||||
}
|
||||
|
||||
// Обработка ввода для движения персонажа
|
||||
private void HandleCharacterInput()
|
||||
{
|
||||
// Создаем структуру ввода с полной информацией о камере
|
||||
var inputs = new PlayerInputs();
|
||||
PlayerInputs inputs = new PlayerInputs();
|
||||
|
||||
// Получаем данные движения из Input System
|
||||
var moveInput = _inputService.MoveInput;
|
||||
inputs.MoveAxisForward = moveInput.y; // Vertical ось (W/S или Up/Down)
|
||||
inputs.MoveAxisRight = moveInput.x; // Horizontal ось (A/D или Left/Right)
|
||||
Vector2 moveInput = _inputService.MoveInput;
|
||||
inputs.MoveAxisForward = moveInput.y;
|
||||
inputs.MoveAxisRight = moveInput.x;
|
||||
|
||||
// Передаем информацию о камере для адаптивного поведения
|
||||
inputs.CameraRotation = playerCamera.transform.rotation;
|
||||
inputs.CameraMode = playerCamera.CurrentMode;
|
||||
inputs.CameraPlanarDirection = playerCamera.PlanarDirection;
|
||||
|
||||
// Передаем ввод в контроллер персонажа
|
||||
characterController.SetInputs(ref inputs);
|
||||
}
|
||||
|
||||
// Обработка переключения режима камеры через Input System
|
||||
private void HandleCameraModeInput()
|
||||
{
|
||||
// Получаем состояние переключения режима камеры из Input System
|
||||
var togglePressed = _inputService.ToggleCameraModePressed;
|
||||
|
||||
switch (togglePressed)
|
||||
{
|
||||
// Обрабатываем нажатие только один раз при первом обнаружении
|
||||
case true when !_cameraModeToggleHandled:
|
||||
ToggleCameraMode();
|
||||
_cameraModeToggleHandled = true;
|
||||
break;
|
||||
// Сбрасываем флаг когда кнопка отпущена
|
||||
case false:
|
||||
_cameraModeToggleHandled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Метод для переключения режимов камеры
|
||||
private void ToggleCameraMode()
|
||||
{
|
||||
var currentMode = playerCamera.CurrentMode;
|
||||
var newMode = currentMode == CameraMode.FirstPerson ?
|
||||
CameraMode.ThirdPerson : CameraMode.FirstPerson;
|
||||
|
||||
playerCamera.SetCameraMode(newMode);
|
||||
}
|
||||
|
||||
// Обновление логики каждый кадр
|
||||
private void Update()
|
||||
{
|
||||
// Обработка ввода для движения в Update (физика)
|
||||
HandleCharacterInput();
|
||||
|
||||
// Обработка переключения режима камеры
|
||||
HandleCameraModeInput();
|
||||
}
|
||||
|
||||
// Обновление после всех вычислений (идеально для камеры)
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
// Обработка ввода для камеры в LateUpdate (после движения персонажа)
|
||||
HandleCameraInput();
|
||||
}
|
||||
}
|
||||
@@ -3,21 +3,6 @@ using UnityEngine;
|
||||
|
||||
namespace Code.Gameplay.Player
|
||||
{
|
||||
/*
|
||||
* Перечисление режимов работы камеры
|
||||
* Static - статичная камера без следования за целью
|
||||
* FirstPerson - камера от первого лица (встроена в модель персонажа)
|
||||
* ThirdPerson - камера от третьего лица (следует за персонажем на расстоянии)
|
||||
* Cinematic - кинематографическая камера для скриптовых сцен
|
||||
*/
|
||||
public enum CameraMode
|
||||
{
|
||||
Static,
|
||||
FirstPerson,
|
||||
ThirdPerson,
|
||||
Cinematic
|
||||
}
|
||||
|
||||
/*
|
||||
* Скрипт, отвечающий за поведение камеры при передвижении
|
||||
* Поддерживает как 3rd-person, так и 1st-person режимы камеры
|
||||
@@ -38,29 +23,27 @@ namespace Code.Gameplay.Player
|
||||
distanceMovementSpeed = 5f, // Множитель скорости изменения дистанции при зуме
|
||||
|
||||
// Скорость интерполяции текущая -> целевая позиция зума
|
||||
distanceMovementSharpness = 100f, // Коэффициент плавности изменения дистанции (чем выше - тем резче)
|
||||
distanceMovementSharpness = 10000f, // Коэффициент плавности изменения дистанции (чем выше - тем резче)
|
||||
|
||||
// Скорость поворота камеры
|
||||
rotationSpeed = 0.3f, // Множитель скорости вращения камеры
|
||||
rotationSpeed = 1f, // Множитель скорости вращения камеры
|
||||
|
||||
// Скорость интерполяции текущее -> целевое вращение
|
||||
rotationSharpness = 100f, // Коэффициент плавности вращения камеры (чем выше - тем резче)
|
||||
rotationSharpness = 10000f, // Коэффициент плавности вращения камеры (чем выше - тем резче)
|
||||
|
||||
// Резкость следования камеры за целью
|
||||
followSharpness = 100f, // Коэффициент плавности следования за движущейся целью (чем выше - тем резче)
|
||||
followSharpness = 10000f, // Коэффициент плавности следования за движущейся целью (чем выше - тем резче)
|
||||
|
||||
// Углы наклона камеры
|
||||
minVerticalAngle = -70f, // Минимальный угол наклона камеры (вниз)
|
||||
maxVerticalAngle = 70f, // Максимальный угол наклона камеры (вверх)
|
||||
minVerticalAngle = -45f, // Минимальный угол наклона камеры (вниз)
|
||||
maxVerticalAngle = 45f, // Максимальный угол наклона камеры (вверх)
|
||||
defaultVerticalAngle = 10f; // Стандартный угол наклона камеры
|
||||
|
||||
// Текущий режим работы камеры
|
||||
|
||||
// Трансформ объекта, за которым следует камера (для 1st-person: уровень глаз)
|
||||
private Transform _followTransform;
|
||||
|
||||
// Позиция следования: текущая сглаженная позиция и горизонтальное направление камеры
|
||||
private Vector3 _currentFollowPosition;
|
||||
private Vector3 _currentFollowPosition, _planarDirection;
|
||||
|
||||
// Целевой вертикальный угол камеры (наклон вверх/вниз)
|
||||
private float _targetVerticalAngle;
|
||||
@@ -68,26 +51,13 @@ namespace Code.Gameplay.Player
|
||||
// Текущая и целевая дистанция камеры от цели
|
||||
private float _currentDistance, _targetDistance;
|
||||
|
||||
// Исходные значения дистанции для восстановления после FirstPerson режима
|
||||
private float _originalDefaultDistance, _originalMinDistance, _originalMaxDistance;
|
||||
|
||||
// Свойства для доступа к важным данным камеры извне
|
||||
public Vector3 PlanarDirection { get; private set; } // Горизонтальное направление камеры
|
||||
|
||||
public CameraMode CurrentMode { get; private set; } = CameraMode.ThirdPerson; // Текущий режим камеры
|
||||
|
||||
// Инициализация камеры при создании
|
||||
private void Awake()
|
||||
{
|
||||
// Сохраняем исходные значения дистанции для восстановления
|
||||
_originalDefaultDistance = defaultDistance;
|
||||
_originalMinDistance = minDistance;
|
||||
_originalMaxDistance = maxDistance;
|
||||
|
||||
_currentDistance = defaultDistance;
|
||||
_targetDistance = _currentDistance;
|
||||
_targetVerticalAngle = 0f;
|
||||
PlanarDirection = Vector3.forward; // Начальное направление - вперед по оси Z
|
||||
_planarDirection = Vector3.forward; // Начальное направление - вперед по оси Z
|
||||
}
|
||||
|
||||
// Установка цели для следования камеры
|
||||
@@ -95,7 +65,7 @@ namespace Code.Gameplay.Player
|
||||
{
|
||||
_followTransform = t;
|
||||
_currentFollowPosition = t.position;
|
||||
PlanarDirection = t.forward; // Начальное направление совпадает с направлением цели
|
||||
_planarDirection = t.forward; // Начальное направление совпадает с направлением цели
|
||||
}
|
||||
|
||||
// Валидация параметров в редакторе Unity
|
||||
@@ -111,8 +81,8 @@ namespace Code.Gameplay.Player
|
||||
{
|
||||
// Вращение вокруг вертикальной оси (горизонтальный поворот)
|
||||
var rotationFromInput = Quaternion.Euler(_followTransform.up * (rotationInput.x * rotationSpeed));
|
||||
PlanarDirection = rotationFromInput * PlanarDirection;
|
||||
var planarRotation = Quaternion.LookRotation(PlanarDirection, _followTransform.up);
|
||||
_planarDirection = rotationFromInput * _planarDirection;
|
||||
var planarRotation = Quaternion.LookRotation(_planarDirection, _followTransform.up);
|
||||
|
||||
// Вращение вокруг горизонтальной оси (вертикальный наклон)
|
||||
_targetVerticalAngle -= rotationInput.y * rotationSpeed;
|
||||
@@ -126,38 +96,21 @@ namespace Code.Gameplay.Player
|
||||
transform.rotation = targetRotation;
|
||||
}
|
||||
|
||||
// Обработка позиционирования камеры и зума с учетом текущего режима
|
||||
// Обработка позиционирования камеры и зума
|
||||
private void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
|
||||
{
|
||||
// В FirstPerson режиме зум отключается
|
||||
if (CurrentMode != CameraMode.FirstPerson)
|
||||
{
|
||||
// Обновление целевой дистанции на основе ввода зума
|
||||
_targetDistance += zoomInput * distanceMovementSpeed;
|
||||
_targetDistance = Mathf.Clamp(_targetDistance, minDistance, maxDistance);
|
||||
}
|
||||
// Обновление целевой дистанции на основе ввода зума
|
||||
_targetDistance += zoomInput * distanceMovementSpeed;
|
||||
_targetDistance = Mathf.Clamp(_targetDistance, minDistance, maxDistance);
|
||||
|
||||
// Плавное следование за целью с использованием экспоненциального сглаживания
|
||||
_currentFollowPosition = Vector3.Lerp(_currentFollowPosition, _followTransform.position, 1f - Mathf.Exp(-followSharpness * deltaTime));
|
||||
|
||||
// Вычисление целевой позиции камеры с учетом текущего режима
|
||||
Vector3 targetPosition;
|
||||
if (CurrentMode == CameraMode.FirstPerson)
|
||||
{
|
||||
// В FirstPerson режиме камера находится прямо на позиции цели
|
||||
targetPosition = _currentFollowPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
// В ThirdPerson режиме камера отодвинута на расстояние от цели
|
||||
targetPosition = _currentFollowPosition - targetRotation * Vector3.forward * _currentDistance;
|
||||
}
|
||||
// Вычисление целевой позиции камеры за вычетом дистанции по направлению взгляда
|
||||
var targetPosition = _currentFollowPosition - targetRotation * Vector3.forward * _currentDistance;
|
||||
|
||||
// Плавное изменение текущей дистанции к целевой (только для ThirdPerson)
|
||||
if (CurrentMode != CameraMode.FirstPerson)
|
||||
{
|
||||
_currentDistance = Mathf.Lerp(_currentDistance, _targetDistance, 1f - Mathf.Exp(-distanceMovementSpeed * deltaTime));
|
||||
}
|
||||
// Плавное изменение текущей дистанции к целевой
|
||||
_currentDistance = Mathf.Lerp(_currentDistance, _targetDistance, 1f - Mathf.Exp(-distanceMovementSpeed * deltaTime));
|
||||
|
||||
// Установка финальной позиции камеры
|
||||
transform.position = targetPosition;
|
||||
@@ -168,48 +121,8 @@ namespace Code.Gameplay.Player
|
||||
{
|
||||
// Проверка наличия цели для следования
|
||||
if (!_followTransform) return;
|
||||
|
||||
// Обработка ввода и позиционирования
|
||||
HandleRotationInput(deltaTime, rotationInput, out Quaternion targetRotation);
|
||||
HandlePosition(deltaTime, zoomInput, targetRotation);
|
||||
}
|
||||
|
||||
// Смена режима камеры
|
||||
public void SetCameraMode(CameraMode newMode)
|
||||
{
|
||||
if (CurrentMode == newMode) return;
|
||||
CurrentMode = newMode;
|
||||
|
||||
// Применяем настройки специфичные для режима
|
||||
ApplyModeSpecificSettings();
|
||||
}
|
||||
|
||||
// Применение настроек специфичных для текущего режима
|
||||
private void ApplyModeSpecificSettings()
|
||||
{
|
||||
switch (CurrentMode)
|
||||
{
|
||||
case CameraMode.FirstPerson:
|
||||
// В FirstPerson режиме дистанция всегда равна 0
|
||||
minDistance = 0f;
|
||||
maxDistance = 0f;
|
||||
defaultDistance = 0f;
|
||||
_targetDistance = 0f;
|
||||
_currentDistance = 0f;
|
||||
break;
|
||||
case CameraMode.ThirdPerson:
|
||||
// Восстанавливаем исходные значения дистанции
|
||||
minDistance = _originalMinDistance;
|
||||
maxDistance = _originalMaxDistance;
|
||||
defaultDistance = _originalDefaultDistance;
|
||||
_targetDistance = defaultDistance;
|
||||
break;
|
||||
// Заготовка на будущее (если понадобится)
|
||||
case CameraMode.Static:
|
||||
case CameraMode.Cinematic:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user