Files
SHI_Sample_UI/Assets/Scripts/DTNavigation/Editor/NavigationSampleSetup.cs
2026-03-09 01:05:56 +09:00

121 lines
5.8 KiB
C#

#nullable enable
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using DTNavigation.CameraSystem;
namespace DTNavigation.Editor
{
/// <summary>
/// 샘플 씬 자동 설정 에디터 메뉴.
/// Unity 메뉴 → DTNavigation → 샘플 씬 설정 생성
/// </summary>
public static class NavigationSampleSetup
{
private const float DefaultDistance = 100f;
private const float DefaultPitch = 45f;
private const float DefaultDuration = 1.2f;
[MenuItem("DTNavigation/샘플 씬 설정 생성")]
public static void CreateSampleSetup()
{
// ── 1. 샘플 큐브 생성 ──────────────────────────────────
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.name = "SampleCube";
cube.transform.position = Vector3.zero;
cube.transform.localScale = new Vector3(5f, 3f, 5f);
// ── 2. CameraNavManager + NavPoints 생성 ───────────────
// NavPoint 위치 = 바라볼 타겟 (큐브 중심 = 원점)
// NavPoint Y회전 = 카메라 접근 방향
var managerGo = new GameObject("CameraNavManager");
var manager = managerGo.AddComponent<CameraNavManager>();
var navData = new (string id, string goName, float yRotation)[]
{
("cutting-overview", "NavPoint_CuttingOverview", 0f), // 정면
("cutting-trans-bay", "NavPoint_TransBay", 90f), // 우측
("cutting-25bay", "NavPoint_25Bay", 45f), // 우전방
("cutting-24bay", "NavPoint_24Bay", -45f), // 좌전방
("cutting-23bay", "NavPoint_23Bay", -90f), // 좌측
("cutting-22bay", "NavPoint_22Bay", 180f), // 후방
};
foreach (var (id, goName, yRot) in navData)
{
var navGo = new GameObject(goName);
navGo.transform.SetParent(managerGo.transform);
navGo.transform.position = Vector3.zero; // 큐브 중심을 타겟으로
navGo.transform.rotation = Quaternion.Euler(0f, yRot, 0f); // 접근 방향
var navPoint = navGo.AddComponent<CameraNavPoint>();
var so = new SerializedObject(navPoint);
so.FindProperty("<ItemId>k__BackingField").stringValue = id;
so.FindProperty("_distance").floatValue = DefaultDistance;
so.FindProperty("_pitchAngle").floatValue = DefaultPitch;
so.FindProperty("_duration").floatValue = DefaultDuration;
so.ApplyModifiedProperties();
}
// ── 3. MainCamera에 CameraController 추가 ─────────────
CameraController? camController = null;
var mainCam = Camera.main;
if (mainCam != null)
{
camController = mainCam.GetComponent<CameraController>()
?? mainCam.gameObject.AddComponent<CameraController>();
// 초기 카메라: 큐브 정면 45° 위, 거리 100
var pitchRad = DefaultPitch * Mathf.Deg2Rad;
mainCam.transform.position = new Vector3(
0f,
DefaultDistance * Mathf.Sin(pitchRad),
-DefaultDistance * Mathf.Cos(pitchRad));
mainCam.transform.rotation = Quaternion.Euler(DefaultPitch, 0f, 0f);
var managerSo = new SerializedObject(manager);
managerSo.FindProperty("_cameraController").objectReferenceValue = camController;
managerSo.ApplyModifiedProperties();
}
else
{
Debug.LogWarning("[Sample] MainCamera를 찾을 수 없습니다. CameraController를 수동으로 연결해주세요.");
}
// ── 4. SidebarNavigationController 자동 연결 ──────────
#pragma warning disable CS0618
var navController = Object.FindObjectOfType<SidebarNavigationController>();
#pragma warning restore CS0618
if (navController != null)
{
var controllerSo = new SerializedObject(navController);
controllerSo.FindProperty("_cameraNavManager").objectReferenceValue = manager;
if (camController != null)
controllerSo.FindProperty("_cameraController").objectReferenceValue = camController;
controllerSo.ApplyModifiedProperties();
Debug.Log("[Sample] SidebarNavigationController 자동 연결 완료.");
}
else
{
Debug.LogWarning("[Sample] SidebarNavigationController를 찾을 수 없습니다.\n" +
"Inspector에서 CameraNavManager / CameraController를 수동으로 연결해주세요.");
}
// ── 5. 씬 변경 표시 ───────────────────────────────────
EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
Debug.Log("[Sample] 샘플 씬 설정 완료!\n" +
$" - 큐브: {cube.name} (원점)\n" +
$" - NavPoints: {navData.Length}개 — 피치 {DefaultPitch}°, 거리 {DefaultDistance}\n" +
" - Ctrl+S 로 씬을 저장하세요.");
}
[MenuItem("DTNavigation/샘플 씬 설정 생성", validate = true)]
public static bool ValidateCreateSampleSetup()
=> !Application.isPlaying;
}
}