using UnityEngine; using static OnlyScove.Scripts.CameraController; namespace OnlyScove.Scripts { [System.Serializable] public class CameraRotationHandler { [Header("Rotation Settings")] [SerializeField] private float sensitivity = 0.1f; [SerializeField] private float minVerticalAngle = -45f; [SerializeField] private float maxVerticalAngle = 45f; [SerializeField] private bool invertX; [SerializeField] private bool invertY; [Header("Auto Rotation")] [SerializeField] private bool useAutoRotation = true; [SerializeField] private float autoRotateDelay = 2.5f; [SerializeField] private float autoRotateSpeed = 2f; private float _rotationX; private float _rotationY; private float _lastInputTime; public Quaternion CurrentRotation { get; private set; } // Camera's actual rotation public Quaternion PlanarRotation => Quaternion.Euler(0f, _rotationY, 0f); // Horizontal rotation (for player body in FPV) public void Initialize(Transform cameraTransform) { _rotationX = cameraTransform.eulerAngles.x; _rotationY = cameraTransform.eulerAngles.y; _lastInputTime = Time.time; CurrentRotation = cameraTransform.rotation; } // New method to initialize rotation specifically for FPV public void InitializeFPV(Transform fpvTargetTransform) { _rotationX = fpvTargetTransform.localEulerAngles.x; // Use local rotation for vertical angle in FPV _rotationY = fpvTargetTransform.eulerAngles.y; // Use world rotation for horizontal angle _lastInputTime = Time.time; CurrentRotation = fpvTargetTransform.rotation; // Camera starts matching fpvTarget rotation } public void HandleRotation(InputReader inputReader, Transform followTarget, float rotationSmoothTime, CameraViewMode viewMode) { if (inputReader == null) return; // Debug for rotation if (inputReader.LookInput.sqrMagnitude > 0.001f) { Debug.Log($"[CameraRotationHandler] LookInput: {inputReader.LookInput}, _rotationX: {_rotationX}, _rotationY: {_rotationY}, ViewMode: {viewMode}"); } // Update _lastInputTime regardless of view mode if there's look input if (inputReader.LookInput.magnitude > 0.01f) { _lastInputTime = Time.time; } float invertXVal = (invertX) ? -1 : 1; float invertYVal = (invertY) ? -1 : 1; _rotationX -= inputReader.LookInput.y * invertYVal * sensitivity * Time.deltaTime; _rotationX = Mathf.Clamp(_rotationX, minVerticalAngle, maxVerticalAngle); _rotationY += inputReader.LookInput.x * invertXVal * sensitivity * Time.deltaTime; if (viewMode == CameraViewMode.ThirdPerson) { // Auto-Correction for TPV if (useAutoRotation && Time.time - _lastInputTime > autoRotateDelay) { if (inputReader.MoveInput.magnitude > 0.1f) { float targetYaw = followTarget.eulerAngles.y; _rotationY = Mathf.LerpAngle(_rotationY, targetYaw, autoRotateSpeed * Time.deltaTime); } } Quaternion targetRotation = Quaternion.Euler(_rotationX, _rotationY, 0f); CurrentRotation = Quaternion.Slerp(CurrentRotation, targetRotation, rotationSmoothTime * Time.deltaTime); } else // FirstPerson { // In FPV, CurrentRotation *is* the camera's rotation (head rotation) // The horizontal part of this (_rotationY) will also be used to rotate the player's body. Quaternion targetRotation = Quaternion.Euler(_rotationX, _rotationY, 0f); CurrentRotation = Quaternion.Slerp(CurrentRotation, targetRotation, rotationSmoothTime * Time.deltaTime); } } } }