#nullable enable using UnityEngine; namespace DTNavigation.CameraSystem { /// /// 씬에 배치하여 탭별 카메라 이동 지점을 정의하는 컴포넌트. /// /// ■ 동작 방식 /// - 이 GameObject의 위치 = 카메라가 바라볼 타겟 지점 /// - 이 GameObject의 Y회전 = 카메라가 접근하는 수평 방향 /// - 카메라는 타겟으로부터 Distance 거리, PitchAngle 각도 위쪽에 위치하여 타겟을 바라봅니다. /// /// ■ 설정 방법 /// 1. NavPoint를 바라볼 오브젝트 위에 배치합니다. /// 2. Y축 회전으로 카메라가 접근할 방향을 설정합니다. /// 3. Inspector에서 Distance / PitchAngle 을 조절합니다. /// public sealed class CameraNavPoint : MonoBehaviour { [Tooltip("SidebarConfig에 정의된 NavChildItemModel.Id와 동일하게 입력하세요.\n예: \"cutting-24bay\"")] [field: SerializeField] public string ItemId { get; private set; } = string.Empty; [Header("카메라 오프셋")] [Tooltip("타겟으로부터 카메라까지의 거리")] [SerializeField] private float _distance = 100f; [Tooltip("수평면 기준 카메라 피치 각도 (0°=수평 / 90°=바로 위)")] [Range(0f, 90f)] [SerializeField] private float _pitchAngle = 45f; [Header("이동 지속 시간 (초, 0 이하 = CameraController 기본값 사용)")] [SerializeField] private float _duration = -1f; // ────────────────────────────────────────────────────────── /// /// 타겟을 위에서 내려다보는 위치로 카메라를 이동시킵니다. /// CameraNavManager에서 자동으로 호출됩니다. /// public void ApplyTo(CameraController camera) { var (cameraPos, cameraRot) = CalculateCameraTransform(); camera.NavigateToPosition(cameraPos, cameraRot, _duration); } // ── 카메라 위치/회전 계산 ────────────────────────────────── private (Vector3 position, Quaternion rotation) CalculateCameraTransform() { var target = transform.position; var pitchRad = _pitchAngle * Mathf.Deg2Rad; // NavPoint의 Y회전으로 수평 접근 방향 결정 var forward = new Vector3(transform.forward.x, 0f, transform.forward.z).normalized; if (forward == Vector3.zero) forward = Vector3.forward; var horizontalDist = _distance * Mathf.Cos(pitchRad); var verticalDist = _distance * Mathf.Sin(pitchRad); // 타겟 뒤쪽 + 위쪽으로 카메라 배치 var cameraPos = target - forward * horizontalDist + Vector3.up * verticalDist; var cameraRot = Quaternion.LookRotation(target - cameraPos); return (cameraPos, cameraRot); } #if UNITY_EDITOR private void OnDrawGizmos() { var (cameraPos, _) = CalculateCameraTransform(); var target = transform.position; // 타겟 지점 (초록) Gizmos.color = Color.green; Gizmos.DrawWireSphere(target, 0.4f); // 카메라 예상 위치 (파랑) Gizmos.color = Color.cyan; Gizmos.DrawWireSphere(cameraPos, 0.6f); // 타겟 → 카메라 연결선 Gizmos.color = new Color(0f, 1f, 1f, 0.4f); Gizmos.DrawLine(target, cameraPos); UnityEditor.Handles.Label(cameraPos + Vector3.up * 0.8f, $"Cam [{ItemId}]\nDist:{_distance} Pitch:{_pitchAngle}°"); } #endif } }