using Code.DI; using Code.Input; using UnityEngine; namespace Code.Gameplay.Camera { public class CameraController : MonoBehaviour { [Header("Settings")] [SerializeField] private float rotationSpeed = 300f; [SerializeField] private float rotationSharpness = 10f; [SerializeField] private float followSharpness = 10f; [SerializeField] private float minVerticalAngle = -90f; [SerializeField] private float maxVerticalAngle = 90f; [SerializeField] private float defaultVerticalAngle = 0f; [Header("Target")] [SerializeField] private Transform followTransform; private UnityEngine.Camera _camera; private Vector3 _currentFollowPosition; private Vector3 _planarDirection; private float _targetVerticalAngle; private IInputService _inputService; private void Awake() { _camera = GetComponent(); if (_camera == null) { Debug.LogError("CameraController requires a Camera component!"); enabled = false; return; } Initialize(); } private void Start() { _inputService = FindFirstObjectByType().Resolve(); } private void Initialize() { _targetVerticalAngle = Mathf.Clamp(defaultVerticalAngle, minVerticalAngle, maxVerticalAngle); _planarDirection = followTransform != null ? followTransform.forward : Vector3.forward; _currentFollowPosition = followTransform != null ? followTransform.position : Vector3.zero; } private void LateUpdate() { if (followTransform != null) { UpdateCamera(Time.deltaTime, GetLookInput()); } } private void UpdateCamera(float deltaTime, Vector3 lookInput) { // Handle rotation Quaternion targetRotation = HandleRotation(deltaTime, lookInput); // Handle position HandlePosition(deltaTime, targetRotation); } private Quaternion HandleRotation(float deltaTime, Vector3 lookInput) { // Horizontal rotation Quaternion horizontalRotation = Quaternion.Euler(Vector3.up * (lookInput.x * rotationSpeed)); _planarDirection = horizontalRotation * _planarDirection; Quaternion planarRotation = Quaternion.LookRotation(_planarDirection, followTransform.up); // Vertical rotation _targetVerticalAngle -= lookInput.y * rotationSpeed; _targetVerticalAngle = Mathf.Clamp(_targetVerticalAngle, minVerticalAngle, maxVerticalAngle); Quaternion verticalRotation = Quaternion.Euler(_targetVerticalAngle, 0, 0); // Combine and apply Quaternion targetRotation = planarRotation * verticalRotation; transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, deltaTime * rotationSharpness); return targetRotation; } private void HandlePosition(float deltaTime, Quaternion targetRotation) { _currentFollowPosition = Vector3.Lerp( _currentFollowPosition, followTransform.position, 1f - Mathf.Exp(-followSharpness * deltaTime) ); transform.position = _currentFollowPosition; } private Vector3 GetLookInput() { // Получите здесь ваш инпут (например, из Input System) // Это пример для стандартного инпута: return _inputService.MoveInput; } // Публичные методы для получения данных public Quaternion GetCameraRotation() { return transform.rotation; } public Vector3 GetPlanarDirection() { return _planarDirection; } // Метод для установки цели следования public void SetFollowTransform(Transform target) { followTransform = target; if (target != null) { _currentFollowPosition = target.position; _planarDirection = target.forward; } } } }