using Code.Example.Liminal.Player; using Code.Infrastructure.Generators; using Code.Infrastructure.Input; using UnityEngine; using UnityEngine.InputSystem; namespace Code.Infrastructure.Camera.CameraStates { [State(typeof(CameraMode),typeof(CameraStateMachineContext), true)] public partial class FirstPersonCameraState : BaseCameraState { private CameraSettingsConfig _settings; public FirstPersonCameraState(CameraStateMachineContext context, EventBus.EventBus eventBus) : base(context, eventBus) { } public override CameraMode myState => CameraMode.FirstPerson; protected override void OnEnterState() { _settings = Context.cameraLoadedData.SettingsConfigs[myState]; Context.InputService.BindActionPerformed((int)ActionMappings.Gameplay, (int) GameplayActions.Look, OnLookPerformed); Context.InputService.BindActionCancel((int)ActionMappings.Gameplay, (int) GameplayActions.Look, OnLookCanceled); } protected override void HandleRotationInput(float deltaTime, Vector3 rotationInput, out Quaternion targetRotation) { // Вращение вокруг вертикальной оси (горизонтальный поворот) var rotationFromInput = Quaternion.Euler(Vector3.up * (rotationInput.x * _settings.rotationSpeed)); PlanarDirection = rotationFromInput * PlanarDirection; var planarRotation = Quaternion.LookRotation(PlanarDirection, FollowTransform.up); // Вращение вокруг горизонтальной оси (вертикальный наклон) TargetVerticalAngle -= rotationInput.y * _settings.rotationSpeed; TargetVerticalAngle = Mathf.Clamp(TargetVerticalAngle, _settings.minVerticalAngle, _settings.maxVerticalAngle); var verticalRotation = Quaternion.Euler(TargetVerticalAngle, 0, 0); // Интерполяция к целевому вращению для плавности targetRotation = Quaternion.Slerp(Context.cameraLoadedData.Camera.transform.rotation, planarRotation * verticalRotation, deltaTime * _settings.rotationSharpness); // Применение финального вращения Context.cameraLoadedData.Camera.transform.rotation = targetRotation; } protected override void OnExitState() { } protected override void HandlePosition(float deltaTime, object targetRotation) { // Плавное следование за целью с использованием экспоненциального сглаживания // CurrentFollowPosition = Vector3.Lerp(CurrentFollowPosition, FollowTransform.position, 1f - Mathf.Exp(-_settings.followSharpness * deltaTime)); // В FirstPerson режиме камера находится прямо на позиции цели Да ну нахуй чё правда пиздец // var targetPosition = CurrentFollowPosition; // Установка финальной позиции камеры Да ну нахуй чё правда пиздец Context.cameraLoadedData.Camera.transform.position = FollowTransform.position; } private Vector2 _lookInput; private void OnLookPerformed(InputAction.CallbackContext context) { _lookInput = context.ReadValue(); } private void OnLookCanceled(InputAction.CallbackContext context) { _lookInput = Vector2.zero; } public override void Update() { } public override void LateUpdate() { // Обновляем камеру только если есть цель для следования // if (FollowTransform) // { // UpdateWithInput(Time.deltaTime, _lookInput); // } if (_playerMovementController) { UpdateWithInput(Time.deltaTime, _lookInput); _playerMovementController.SetCameraRotation(Context.cameraLoadedData.Camera.transform.rotation); } } public void SetFollowTransform(Transform t) { FollowTransform = t; CurrentFollowPosition = t.position; PlanarDirection = t.forward; // Начальное направление совпадает с направлением цели } private PlayerMovementController _playerMovementController; public void SetPlayer(PlayerMovementController playerMovementController) { _playerMovementController = playerMovementController; FollowTransform = _playerMovementController.PlayerHeadPoint; CurrentFollowPosition = _playerMovementController.PlayerHeadPoint.position; PlanarDirection = _playerMovementController.PlayerHeadPoint.forward; // Начальное направление совпадает с направлением цели } } }