using UnityEngine; using Unheimlich.Data.CameraSettings; using Unheimlich.Gameplay.CameraControl; using Unheimlich.Gameplay.Player; using PlayerInput = Unheimlich.Managers.PlayerInputManager; namespace Unheimlich.Gameplay.DetectiveBoard { /// /// Controls player interaction with the detective board in world space. /// Uses CameraPanController for wide-angle camera movement across the board. /// Activates when player is in range and looking at the board. /// public class DetectiveBoardController : MonoBehaviour { [Header("References")] [SerializeField] private CameraPanController _cameraPanController; [SerializeField] private Transform _boardTransform; [Header("Settings")] [SerializeField] private CameraPanSettings _boardCameraPanSettings; [SerializeField] private float _activationRange = 2f; [SerializeField] private LayerMask _boardLayer; private Camera _playerCamera; private bool _isBoardActive; private CameraPanSettings _originalCameraPanSettings; private CameraHeadBob _cameraHeadBob; private void Awake() { _playerCamera = Camera.main; if (_cameraPanController == null) { _cameraPanController = FindFirstObjectByType(); } _cameraHeadBob = FindFirstObjectByType(); } private void Update() { if (_isBoardActive) { HandleBoardInteraction(); } else { CheckForBoardActivation(); } } /// /// Checks if player is looking at the board and in range to activate. /// private void CheckForBoardActivation() { if (_playerCamera == null || _boardTransform == null) return; float distanceToBoard = Vector3.Distance(_playerCamera.transform.position, _boardTransform.position); if (distanceToBoard > _activationRange) return; Ray ray = new Ray(_playerCamera.transform.position, _playerCamera.transform.forward); if (Physics.Raycast(ray, out RaycastHit hit, _activationRange, _boardLayer)) { if (hit.transform.IsChildOf(_boardTransform) || hit.transform == _boardTransform) { var interactAction = PlayerInput.GetInteractAction(); if (interactAction != null && interactAction.WasPressedThisFrame()) { ActivateBoard(); } } } } /// /// Activates the detective board, switching to pan mode with wide-angle settings. /// public void ActivateBoard() { if (_cameraPanController == null || _boardCameraPanSettings == null) { Debug.LogError("[DetectiveBoardController] Missing required references!"); return; } _isBoardActive = true; _originalCameraPanSettings = _cameraPanController.Settings; _cameraPanController.Settings = _boardCameraPanSettings; _cameraPanController.SaveOriginalState(); _cameraPanController.AlignToTarget(_boardTransform, () => { _cameraPanController.StartPan(); }); PlayerInput.SetContext(PlayerInput.InputContext.Listening); ApplyHeadBobSettings(_boardCameraPanSettings); Debug.Log("[DetectiveBoardController] Detective board activated"); } /// /// Handles board interaction while active (panning and exit). /// private void HandleBoardInteraction() { if (_cameraPanController != null) { _cameraPanController.UpdatePan(); } var exitAction = PlayerInput.GetExitAction(); if (exitAction != null && exitAction.WasPressedThisFrame()) { DeactivateBoard(); } } /// /// Deactivates the board and returns to normal gameplay. /// public void DeactivateBoard() { if (!_isBoardActive) return; _isBoardActive = false; if (_cameraPanController != null) { _cameraPanController.StopPan(); _cameraPanController.ReturnToOriginalPosition(() => { if (_originalCameraPanSettings != null) { _cameraPanController.Settings = _originalCameraPanSettings; } }); } PlayerInput.SetContext(PlayerInput.InputContext.Normal); RestoreHeadBob(); Debug.Log("[DetectiveBoardController] Detective board deactivated"); } /// /// Applies head bob settings based on CameraPanSettings configuration. /// private void ApplyHeadBobSettings(CameraPanSettings settings) { if (_cameraHeadBob == null || settings == null) return; _cameraHeadBob.SetMode(settings.HeadBobMode); } /// /// Restores head bob to normal behavior. /// private void RestoreHeadBob() { if (_cameraHeadBob == null) return; _cameraHeadBob.ClearOverride(); } private void OnDrawGizmosSelected() { if (_boardTransform == null) return; Gizmos.color = _isBoardActive ? Color.green : Color.yellow; Gizmos.DrawWireSphere(_boardTransform.position, _activationRange); } } }