Files
2026-03-09 01:05:56 +09:00

92 lines
3.8 KiB
C#

#nullable enable
using UnityEngine;
namespace DTNavigation.CameraSystem
{
/// <summary>
/// 씬에 배치하여 탭별 카메라 이동 지점을 정의하는 컴포넌트.
///
/// ■ 동작 방식
/// - 이 GameObject의 위치 = 카메라가 바라볼 타겟 지점
/// - 이 GameObject의 Y회전 = 카메라가 접근하는 수평 방향
/// - 카메라는 타겟으로부터 Distance 거리, PitchAngle 각도 위쪽에 위치하여 타겟을 바라봅니다.
///
/// ■ 설정 방법
/// 1. NavPoint를 바라볼 오브젝트 위에 배치합니다.
/// 2. Y축 회전으로 카메라가 접근할 방향을 설정합니다.
/// 3. Inspector에서 Distance / PitchAngle 을 조절합니다.
/// </summary>
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;
// ──────────────────────────────────────────────────────────
/// <summary>
/// 타겟을 위에서 내려다보는 위치로 카메라를 이동시킵니다.
/// CameraNavManager에서 자동으로 호출됩니다.
/// </summary>
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
}
}