#nullable enable using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.SceneManagement; using DTNavigation.CameraSystem; namespace DTNavigation.Editor { /// /// 샘플 씬 자동 설정 에디터 메뉴. /// Unity 메뉴 → DTNavigation → 샘플 씬 설정 생성 /// 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(); 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(); var so = new SerializedObject(navPoint); so.FindProperty("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() ?? mainCam.gameObject.AddComponent(); // 초기 카메라: 큐브 정면 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(); #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; } }