181 lines
6.3 KiB
C#
181 lines
6.3 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// Controls player interaction with the detective board.
|
|
/// </summary>
|
|
public class DetectiveBoardController : Singleton<DetectiveBoardController>
|
|
{
|
|
[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<CameraHeadBob>();
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|