From 16bc037093d00b0df355ead12836407e9a34c71f Mon Sep 17 00:00:00 2001 From: jongjae Date: Thu, 21 May 2026 01:05:04 +0900 Subject: [PATCH] =?UTF-8?q?UI=20=EC=88=98=EC=A0=95,=20=ED=86=A0=EA=B8=80?= =?UTF-8?q?=20=EA=B8=B0=EB=B3=B8=EA=B0=92,=20Spawner=20=EC=98=A4=EB=94=94?= =?UTF-8?q?=EC=98=A4=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [SceneBuilder] - 사용자 수동 조정 위치 반영 (AudioDropdown, RefreshBtn, FilePickerBtn, UrlInput, UrlDownloadBtn, 난이도 토글 4개, BackButton) - MakeTMP 텍스트 정렬: MidlineLeft → Center - MakePanel/Button/InputField/Dropdown: sprite = null 설정으로 흰색 배경 제거 - 버튼 텍스트 특수문자 → ASCII 대체 (→ > / ▼▶✕ 제거): NanumGothic SDF 미지원 문자 경고 해결 - 난이도 토글 4개 기본값 모두 true로 변경 [SongCreatorManager] - Start()에서 토글 전체 꺼진 경우 자동으로 4개 모두 켜기 (씬 재빌드 없이 즉시 적용) [Spawner] - Awake(): playOnAwake = false, clip = null 설정 — Inspector 하드코딩 클립 자동 재생 차단 - InitGame(): AudioSource/GameSession null 체크, 파일 존재 확인, 경로 로그 추가 - audioSource.clip == null 후 yield break로 로드 실패 시 재생 방지 Co-Authored-By: Claude Sonnet 4.6 --- Assets/Editor/VRBeatSaberSceneBuilder.cs | 288 ++++++++++++++++++++--- Assets/Script/SongCreatorManager.cs | 143 ++++++++++- Assets/Script/Spawner.cs | 72 +++++- 3 files changed, 456 insertions(+), 47 deletions(-) diff --git a/Assets/Editor/VRBeatSaberSceneBuilder.cs b/Assets/Editor/VRBeatSaberSceneBuilder.cs index 733131e..dad6472 100644 --- a/Assets/Editor/VRBeatSaberSceneBuilder.cs +++ b/Assets/Editor/VRBeatSaberSceneBuilder.cs @@ -16,6 +16,188 @@ public static class VRBeatSaberSceneBuilder { private static GameObject s_cardPrefab; + // ══════════════════════════════════════════════════════════ + // 뒤로가기 버튼 패치 (기존 씬에 추가) + // ══════════════════════════════════════════════════════════ + + [MenuItem("Tools/VRBeatSaber/뒤로가기 버튼 추가 (기존 씬 패치)")] + public static void PatchBackButtons() + { + if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) return; + + // SongSelect: 뒤로(Intro) + DetailPanel 닫기(X) + PatchSceneWithBackButton( + "Assets/Scenes/SongSelect.unity", + () => + { + FindAndBindBackButton("backButton", "< 뒤로", new Vector2(-500, 310), new Vector2(130, 50)); + AddDetailPanelCloseButton(); + }); + + // SongCreator: 뒤로(Intro) + PatchSceneWithBackButton( + "Assets/Scenes/SongCreator.unity", + () => FindAndBindBackButton("backButton", "< 뒤로", new Vector2(-405, 345), new Vector2(130, 50))); + + // MapEditorScene: 뒤로(SongCreator) + PatchSceneWithBackButton( + "Assets/Scenes/MapEditorScene.unity", + FindAndBindBackButtonOnMapEditor); + + // Game: 뒤로(SongSelect) — 우측 상단 소형 버튼 + PatchSceneWithBackButton( + "Assets/Scenes/Game.unity", + AddGameSceneBackButton); + + AssetDatabase.Refresh(); + EditorUtility.DisplayDialog("완료", "뒤로가기 버튼 추가 완료!\n\n추가된 버튼:\n- SongSelect: < 뒤로 + 상세패널 X 닫기\n- SongCreator: < 뒤로\n- MapEditorScene: < 뒤로\n- Game: < 뒤로", "확인"); + } + + private static void PatchSceneWithBackButton(string scenePath, System.Action patchAction) + { + if (!File.Exists(scenePath)) { Debug.LogWarning($"[SceneBuilder] 씬 없음: {scenePath}"); return; } + var scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); + patchAction(); + EditorSceneManager.SaveScene(scene); + Debug.Log($"[SceneBuilder] 패치 완료: {scenePath}"); + } + + private static void FindAndBindBackButton(string fieldName, string label, Vector2 pos, Vector2 size) where T : MonoBehaviour + { + var mgr = Object.FindObjectOfType(); + if (mgr == null) { Debug.LogWarning($"[SceneBuilder] {typeof(T).Name} 없음"); return; } + + // 이미 있으면 건너뜀 + var so = new SerializedObject(mgr); + if (so.FindProperty(fieldName)?.objectReferenceValue != null) return; + + // Canvas 찾기 + var canvas = Object.FindObjectOfType(); + if (canvas == null) return; + + var backGO = MakeButton("BackButton", canvas.transform, label, pos, size); + backGO.GetComponent().color = new Color(0.18f, 0.18f, 0.18f); + + Bind(so, fieldName, backGO.GetComponent