노래 만들기 수정 — NAS 업로드 완성, Easy 제거 및 ExpertPlus 추가, 다운로드 버그 수정

- NasPublisher: DSM 7.2 multipart body 수동 구성으로 업로드 401 오류 해결
- NasPublisher: 비밀번호 StreamingAssets/nas_config.json 분리, .gitignore 등록
- NasPublisher: staticBaseUrl 포트 8180 → 80 수정
- BeatSageUploader: Easy 난이도 제거, ExpertPlus(.dat) 추가
- NoteData: DifficultyMap에서 easy 제거, expertplus 추가
- SongCreatorManager: toggleEasy → toggleExpertPlus 교체
- SongDetailPanel: btnEasy → btnExpertPlus 교체
- DownloadManager: DownloadHandlerFile 경로 정규화(Path.GetFullPath), mapFile 빈 값 방어 처리
- PersistentXRRig: FindObjectsOfType obsolete 경고 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 23:39:27 +09:00
parent 2cd1be88d4
commit c73ff7f412
15 changed files with 481 additions and 93 deletions
+42 -17
View File
@@ -20,14 +20,16 @@ public class SongCreatorManager : MonoBehaviour
[SerializeField] private TMP_InputField bpmInput;
[Header("난이도")]
[SerializeField] private Toggle toggleEasy;
[SerializeField] private Toggle toggleNormal;
[SerializeField] private Toggle toggleHard;
[SerializeField] private Toggle toggleExpert;
[SerializeField] private Toggle toggleExpertPlus;
[Header("액션")]
[SerializeField] private Button generateButton;
[SerializeField] private Button manualEditorButton; // 작은 버튼
[SerializeField] private Button backButton;
[SerializeField] private string introSceneName = "Intro";
[Header("진행 상태")]
[SerializeField] private GameObject progressGroup;
@@ -59,6 +61,7 @@ public class SongCreatorManager : MonoBehaviour
refreshBtn.onClick.AddListener(RefreshAudioList);
generateButton.onClick.AddListener(OnGenerateClicked);
manualEditorButton.onClick.AddListener(() => SceneManager.LoadScene(mapEditorScene));
backButton?.onClick.AddListener(() => SceneManager.LoadScene(introSceneName));
progressGroup.SetActive(false);
RefreshAudioList();
@@ -96,14 +99,18 @@ public class SongCreatorManager : MonoBehaviour
{ SetStatus("BPM을 올바르게 입력해주세요."); return; }
var diffs = new List<string>();
if (toggleEasy.isOn) diffs.Add("easy");
if (toggleNormal.isOn) diffs.Add("normal");
if (toggleHard.isOn) diffs.Add("hard");
if (toggleExpert.isOn) diffs.Add("expert");
if (toggleNormal.isOn) diffs.Add("normal");
if (toggleHard.isOn) diffs.Add("hard");
if (toggleExpert.isOn) diffs.Add("expert");
if (toggleExpertPlus.isOn) diffs.Add("expertplus");
if (diffs.Count == 0) { SetStatus("난이도를 하나 이상 선택해주세요."); return; }
StartCoroutine(GenerateFlow(audioFiles[audioDropdown.value], bpm, diffs));
string audioPath = audioFiles[audioDropdown.value];
Debug.Log($"[SongCreator] 생성 시작 — 파일: {audioPath}, BPM: {bpm}, 난이도: {string.Join(",", diffs)}");
Debug.Log($"[SongCreator] beatSageUploader={beatSageUploader}, nasPublisher={nasPublisher}");
StartCoroutine(GenerateFlow(audioPath, bpm, diffs));
}
// ── 생성 플로우 ───────────────────────────────────────────
@@ -112,40 +119,58 @@ public class SongCreatorManager : MonoBehaviour
{
SetInteractable(false);
progressGroup.SetActive(true);
Debug.Log("[SongCreator] GenerateFlow 시작");
// 1단계: Beat Sage 전송 → 변환
Dictionary<string, List<NoteData>> maps = null;
bool failed = false;
Debug.Log("[SongCreator] BeatSage Upload 호출");
yield return beatSageUploader.Upload(
audioPath, diffs, bpm,
onProgress: p =>
{
progressSlider.value = p * 0.8f;
SetStatus(beatSageUploader.CurrentStatus);
SetStatus($"{beatSageUploader.CurrentStatus} ({(int)(p * 80)}%)");
},
onComplete: result => maps = result,
onError: err => { SetStatus($"Beat Sage 실패: {err}"); failed = true; });
onComplete: result =>
{
maps = result;
Debug.Log($"[SongCreator] BeatSage 완료 — 난이도 수: {result?.Count}");
},
onError: err =>
{
Debug.LogError($"[SongCreator] BeatSage 오류: {err}");
SetStatus($"오류: {err}");
failed = true;
});
Debug.Log($"[SongCreator] BeatSage 단계 끝 — failed={failed}, maps={maps?.Count}");
if (failed) { SetInteractable(true); yield break; }
// 2단계: NAS 업로드
SetStatus("NAS에 업로드 중...");
SongInfo song = BuildSongInfo(audioPath, bpm, maps);
Debug.Log($"[SongCreator] NAS Publish 호출 — song.id={song.id}");
yield return nasPublisher.Publish(
song, audioPath, maps,
onProgress: p =>
{
progressSlider.value = 0.8f + p * 0.2f;
SetStatus($"NAS 업로드 중... {(int)((0.8f + p * 0.2f) * 100)}%");
SetStatus($"[4/4] NAS 업로드 중... ({(int)((0.8f + p * 0.2f) * 100)}%)");
},
onComplete: () =>
{
progressSlider.value = 1f;
SetStatus($"'{song.title}' 생성 완료!");
SetStatus($"완료! '{song.title}' 생성 성공 (100%)");
Debug.Log($"[SongCreator] NAS 업로드 완료");
},
onError: err => { SetStatus($"NAS 업로드 실패: {err}"); failed = true; });
onError: err =>
{
Debug.LogError($"[SongCreator] NAS 오류: {err}");
SetStatus($"NAS 업로드 실패: {err}");
failed = true;
});
SetInteractable(true);
}
@@ -163,10 +188,10 @@ public class SongCreatorManager : MonoBehaviour
var info = new DifficultyInfo { noteCount = kv.Value.Count };
switch (kv.Key)
{
case "easy": diffMap.easy = info; break;
case "normal": diffMap.normal = info; break;
case "hard": diffMap.hard = info; break;
case "expert": diffMap.expert = info; break;
case "normal": diffMap.normal = info; break;
case "hard": diffMap.hard = info; break;
case "expert": diffMap.expert = info; break;
case "expertplus": diffMap.expertplus = info; break;
}
}