using UnityEngine; using UnityEngine.UI; using TMPro; using UnityEngine.SceneManagement; using System.Collections; using System.Collections.Generic; public class SongSelectUI : MonoBehaviour { public SongList songList; // 存储歌曲列表的 ScriptableObject public GameObject songButtonPrefab; // 歌曲按钮的 Prefab (Button) public Transform contentPanel; // 滚动视图的 Content 面板 [SerializeField] Button button_Main; [SerializeField] string ui_Main_Scene_Name = "UI_UI"; // Current DLC key used for per-DLC saved song selection public static string CurrentDlcKey = "dlc_default_0"; // Track pending restore to avoid multiple overlapping restores private Coroutine restoreCoroutine; void Start() { if (songList == null || songButtonPrefab == null || contentPanel == null) { Debug.LogError("请在 Inspector 中分配所有字段!"); return; } button_Main.onClick.AddListener( () => SceneManager.LoadScene(ui_Main_Scene_NAME(), LoadSceneMode.Single)); // Do not populate the song list at start. DLC buttons will request songs when clicked. } // 显示所有歌曲 (kept for manual use) public void DisplaySongs() { ClearSongList(); foreach (SongData song in songList.songs) { InstantiateSongButton(song); } if (restoreCoroutine != null) StopCoroutine(restoreCoroutine); restoreCoroutine = StartCoroutine(RestoreSelectedSongNextFrame()); } // Instantiate from a provided list (used by dlcButton to show DLC songs) public void DisplaySongsFromList(List list) { ClearSongList(); if (list == null) return; foreach (var song in list) InstantiateSongButton(song); // After populating, attempt to restore per-DLC selected song (next frame to avoid stale objects) if (restoreCoroutine != null) StopCoroutine(restoreCoroutine); restoreCoroutine = StartCoroutine(RestoreSelectedSongNextFrame()); } private IEnumerator RestoreSelectedSongNextFrame() { // Wait one frame so Destroy() in ClearSongList fully completes and stale SongButtons are gone. yield return null; RestoreSelectedSongForCurrentDlc(); restoreCoroutine = null; } private void RestoreSelectedSongForCurrentDlc() { // read saved index using CurrentDlcKey string dlcKey = (string.IsNullOrEmpty(CurrentDlcKey) ? "default_0" : CurrentDlcKey); string key = "song_selected_" + dlcKey; // collect song buttons under contentPanel var allSongButtons = contentPanel.GetComponentsInChildren(true); if (allSongButtons == null || allSongButtons.Length == 0) { Debug.LogWarning("SongSelectUI.RestoreSelectedSongForCurrentDlc: no song buttons found to restore selection"); return; } // Ensure every DLC has a default persisted value (0) int savedIndex; if (!PlayerPrefs.HasKey(key)) { PlayerPrefs.SetInt(key, 0); PlayerPrefs.Save(); savedIndex = 0; } else { savedIndex = PlayerPrefs.GetInt(key, 0); } if (savedIndex < 0) savedIndex = 0; if (savedIndex >= allSongButtons.Length) savedIndex = 0; var btn = allSongButtons[savedIndex]; if (btn == null) { // hard fallback to first btn = allSongButtons[0]; } if (btn != null) { // simulate click btn.OnSongButtonClick(); Debug.Log($"SongSelectUI: restored and clicked song index={savedIndex} for key={key}, totalButtons={allSongButtons.Length}"); } } private void ClearSongList() { if (contentPanel == null) return; for (int i = contentPanel.childCount - 1; i >= 0; i--) { #if UNITY_EDITOR if (!Application.isPlaying) DestroyImmediate(contentPanel.GetChild(i).gameObject); else Destroy(contentPanel.GetChild(i).gameObject); #else Destroy(contentPanel.GetChild(i).gameObject); #endif } } private void InstantiateSongButton(SongData song) { if (songButtonPrefab == null || contentPanel == null) return; GameObject songButtonObj = Instantiate(songButtonPrefab, contentPanel); songButtonObj.transform.SetParent(contentPanel, false); SongButton songButton = songButtonObj.GetComponent(); if (songButton != null) { songButton.SetButtonData(song.songName, song.personalRecord, song.difficultyID, song.illustration, song.songID); } Image songImage = songButtonObj.GetComponentInChildren(); TMP_Text[] texts = songButtonObj.GetComponentsInChildren(); if (songImage != null && song.illustration != null) { songImage.sprite = song.illustration; songImage.enabled = true; } if (texts.Length >= 4) { texts[0].text = song.songName; texts[1].text = "Record : " + song.personalRecord; texts[3].text = "" + song.difficultyID; texts[2].text = "SongID : " + song.songID.ToString(); } Button button = songButtonObj.GetComponent