using UnityEngine; using Unheimlich.Core; using Unheimlich.World.CameraSystem; using Unheimlich.Features.Player; using Unheimlich.Features.OctoArms; using InputManager = Unheimlich.Core.Input.InputManager; using Unheimlich.Features.DetectiveBoard.UI; using Unheimlich.Features.Dialogue.UI; namespace Unheimlich.Features.DetectiveBoard { /// /// Controls player interaction with the detective board. /// public class DetectiveBoardController : Singleton { [Header("Settings")] [SerializeField] private float _activationRange = 2f; [SerializeField] private LayerMask _boardLayer; [SerializeField] private CameraPanSettings _playerAlignmentSettings; [Header("Virtual Camera")] [SerializeField] private DetectiveBoardVirtualCamera _virtualCamera; private bool _isBoardActive; private CameraHeadBob _cameraHeadBob; public bool IsBoardActive => _isBoardActive; protected override void OnAwake() { _cameraHeadBob = FindFirstObjectByType(); } void Start() { if(_virtualCamera == null) _virtualCamera = DetectiveBoardVirtualCamera.Instance; } 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?.PlayerCamera == null || PlayerController.Instance?.CameraPanController == null || DetectiveBoardCanvas.Instance == null || DetectiveBoardVirtualCamera.Instance == null) { Debug.LogError("[DetectiveBoardController] Missing required references!"); return; } _isBoardActive = true; if (PlayerController.Instance.Movement != null) { PlayerController.Instance.Movement.enabled = false; } OctoIkArmsImproved arms = PlayerController.Instance.GetComponentInChildren(); if (arms != null) { arms.HideArms(3f); } InputManager.SetContext(InputManager.InputContext.DetectiveBoard); if (_cameraHeadBob != null) { _cameraHeadBob.SetMode(HeadBobMode.Disabled); } if (CrosshairController.Instance != null) { CrosshairController.Instance.Hide(); } var cameraPan = PlayerController.Instance.CameraPanController; var originalSettings = cameraPan.Settings; if (_playerAlignmentSettings != null) cameraPan.Settings = _playerAlignmentSettings; cameraPan.SaveOriginalState(); cameraPan.AlignToTarget(DetectiveBoardCanvas.Instance.transform, () => { DetectiveBoardVirtualCamera.Instance.ActivateFromPlayerPosition( PlayerController.Instance.PlayerCamera, DetectiveBoardCanvas.Instance.transform, DetectiveBoardCanvas.Instance.BoardRenderer ); // Show clue hand fan when board is ready if (ClueHandUI.Instance != null) ClueHandUI.Instance.SetHandVisible(true); if (_playerAlignmentSettings != null) cameraPan.Settings = originalSettings; }); } private void HandleBoardInteraction() { var exitAction = InputManager.GetExitAction(); if (exitAction != null && exitAction.WasPressedThisFrame()) { DeactivateBoard(); } } public void DeactivateBoard() { if (!_isBoardActive || DetectiveBoardVirtualCamera.Instance == null) return; _isBoardActive = false; // Hide clue hand fan if (ClueHandUI.Instance != null) ClueHandUI.Instance.SetHandVisible(false); DetectiveBoardVirtualCamera.Instance.Deactivate(() => { var cameraPan = PlayerController.Instance?.CameraPanController; if (cameraPan != null) { OctoIkArmsImproved arms = PlayerController.Instance.GetComponentInChildren(); if (arms != null) { arms.ShowArms(3f); } cameraPan.ReturnToOriginalPosition(() => { if (PlayerController.Instance?.Movement != null) { PlayerController.Instance.Movement.enabled = true; } }); } else if (PlayerController.Instance?.Movement != null) { PlayerController.Instance.Movement.enabled = true; } }); InputManager.SetContext(InputManager.InputContext.Normal); RestoreHeadBob(); if (CrosshairController.Instance != null) { CrosshairController.Instance.Show(); } } 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); } } }