using UnityEngine;
using UnityEngine.InputSystem;
using Unheimlich.Features.Dialogue;
using Unheimlich.Core;
namespace Unheimlich.World.CameraSystem
{
///
/// Virtual camera system for detective board inspection (Alan Wake 2 style).
/// Handles smooth transition, edge-based panning, and zoom.
///
public class DetectiveBoardVirtualCamera : Singleton
{
[Header("References")]
[SerializeField] private Camera _virtualCamera;
private Transform _boardTarget;
[Header("Transition Settings")]
[SerializeField] private float _transitionSpeed = 3f;
[SerializeField] private AnimationCurve _transitionCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
[SerializeField] private float _initialDistance = 1.5f;
[Header("Pan Settings")]
[SerializeField] private float _panSpeed = 2f;
[SerializeField] private float _panSmoothTime = 0.2f;
[SerializeField][Range(0f, 0.5f)] private float _edgeBorderSize = 0.1f;
[SerializeField] private Vector2 _maxPanOffset = new Vector2(1.5f, 0.5f);
[SerializeField] private bool _useDynamicPanLimits = true;
[SerializeField] private float _panMargin = 0.0f;
[SerializeField] private bool _debugLimits = false;
[Header("Zoom Settings")]
[SerializeField] private float _minDistance = 0.5f;
[SerializeField] private float _maxDistance = 3f;
// [SerializeField] private float _zoomSpeed = 2f;
[SerializeField] private float _zoomSmoothTime = 0.15f;
[SerializeField] private float _scrollSensitivity = 0.3f;
private Camera _playerCamera;
private Transform _playerCameraTransform;
private Vector3 _startPosition;
private Quaternion _startRotation;
private Vector3 _targetCenterPosition;
private Quaternion _targetCenterRotation;
private bool _isActive;
private bool _isTransitioning;
private float _transitionProgress;
private Renderer _cachedBoardRenderer;
private Vector2 _currentPanOffset;
private Vector2 _targetPanOffset;
private Vector2 _panVelocity;
private Vector2 _dynamicMaxPanOffset;
private float _currentDistance;
private float _targetDistance;
private float _zoomVelocity;
private Vector2 _lastMousePosition;
public bool IsActive => _isActive;
public Camera VirtualCamera => _virtualCamera;
protected override void OnAwake()
{
if (_virtualCamera == null)
_virtualCamera = GetComponent();
if (_virtualCamera != null)
_virtualCamera.enabled = false;
}
public void ActivateFromPlayerPosition(Camera playerCamera, Transform boardTarget, Renderer boardRenderer = null)
{
if (_isActive)
return;
Debug.Log($"[VirtualCam] ActivateFromPlayerPosition - DebugLimits: {_debugLimits}");
_playerCamera = playerCamera;
_playerCameraTransform = playerCamera.transform;
_boardTarget = boardTarget;
_cachedBoardRenderer = boardRenderer;
_startPosition = _playerCameraTransform.position;
_startRotation = _playerCameraTransform.rotation;
_virtualCamera.transform.position = _startPosition;
_virtualCamera.transform.rotation = _startRotation;
CalculateTargetPosition();
_currentDistance = _initialDistance;
_targetDistance = _initialDistance;
_currentPanOffset = Vector2.zero;
_targetPanOffset = Vector2.zero;
_isActive = true;
_isTransitioning = true;
_transitionProgress = 0f;
_virtualCamera.enabled = true;
_playerCamera.enabled = false;
Canvas boardCanvas = _boardTarget.GetComponentInChildren