using UnityEngine; using Unheimlich.Core; using Unheimlich.Data.CameraSettings; using Unheimlich.Gameplay.Player; using InputManager = Unheimlich.Managers.InputManager; using Unheimlich.UI.DetectiveBoard; namespace Unheimlich.Gameplay.DetectiveBoard { /// /// Controls player interaction with the detective board. /// public class DetectiveBoardController : Singleton { [Header("Settings")] [SerializeField] private CameraPanSettings _boardCameraPanSettings; [SerializeField] private float _activationRange = 2f; [SerializeField] private LayerMask _boardLayer; private bool _isBoardActive; private CameraPanSettings _originalCameraPanSettings; private CameraHeadBob _cameraHeadBob; public bool IsBoardActive => _isBoardActive; protected override void OnAwake() { _cameraHeadBob = FindFirstObjectByType(); } private void Update() { if (_isBoardActive) { HandleBoardInteraction(); } else { CheckForBoardActivation(); } } private void CheckForBoardActivation() { if (PlayerController.Instance == null || PlayerController.Instance.PlayerCamera == null || DetectiveBoardCanvas.Instance == null) return; var camera = PlayerController.Instance.PlayerCamera; var boardTransform = DetectiveBoardCanvas.Instance.transform; float distanceToBoard = Vector3.Distance(camera.transform.position, boardTransform.position); if (distanceToBoard > _activationRange) return; Ray ray = new Ray(camera.transform.position, camera.transform.forward); if (Physics.Raycast(ray, out RaycastHit hit, _activationRange, _boardLayer)) { bool isLookingAtBoard = (hit.transform == boardTransform) || (boardTransform.IsChildOf(hit.transform)) || (hit.transform.IsChildOf(boardTransform)); if (isLookingAtBoard) { var interactAction = InputManager.GetInteractAction(); if (interactAction != null && interactAction.WasPressedThisFrame()) { ActivateBoard(); } } } } public void ActivateBoard() { if (_isBoardActive || PlayerController.Instance?.CameraPanController == null || DetectiveBoardCanvas.Instance == null || _boardCameraPanSettings == null) { Debug.LogError("[DetectiveBoardController] Missing required references!"); return; } _isBoardActive = true; // Disable OctoPlayer completely to prevent ANY input processing if (PlayerController.Instance.Movement != null) { PlayerController.Instance.Movement.enabled = false; } var cameraPan = PlayerController.Instance.CameraPanController; _originalCameraPanSettings = cameraPan.Settings; cameraPan.Settings = _boardCameraPanSettings; // Save state for return (before alignment) cameraPan.SaveOriginalState(); // Align to target, then start pan AFTER alignment completes cameraPan.AlignToTarget(DetectiveBoardCanvas.Instance.transform, () => { // NOW start pan using the aligned rotation as base cameraPan.StartPan(); }); InputManager.SetContext(InputManager.InputContext.Listening); ApplyHeadBobSettings(_boardCameraPanSettings); } private void HandleBoardInteraction() { if (PlayerController.Instance?.CameraPanController != null) { PlayerController.Instance.CameraPanController.UpdatePan(); } var exitAction = InputManager.GetExitAction(); if (exitAction != null && exitAction.WasPressedThisFrame()) { DeactivateBoard(); } } public void DeactivateBoard() { if (!_isBoardActive || PlayerController.Instance?.CameraPanController == null) return; _isBoardActive = false; var cameraPan = PlayerController.Instance.CameraPanController; cameraPan.StopPan(); cameraPan.ReturnToOriginalPosition(() => { if (_originalCameraPanSettings != null) { cameraPan.Settings = _originalCameraPanSettings; } // Re-enable OctoPlayer AFTER the return animation completes if (PlayerController.Instance?.Movement != null) { PlayerController.Instance.Movement.enabled = true; } }); InputManager.SetContext(InputManager.InputContext.Normal); RestoreHeadBob(); } private void ApplyHeadBobSettings(CameraPanSettings settings) { if (_cameraHeadBob == null || settings == null) return; _cameraHeadBob.SetMode(settings.HeadBobMode); } private void RestoreHeadBob() { if (_cameraHeadBob == null) return; _cameraHeadBob.ClearOverride(); } private void OnDrawGizmosSelected() { if (DetectiveBoardCanvas.Instance == null) return; Gizmos.color = _isBoardActive ? Color.green : Color.yellow; Gizmos.DrawWireSphere(DetectiveBoardCanvas.Instance.transform.position, _activationRange); } } }