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);
}
}
}