功能批量实现 优化 服务端 新浮动小游戏框架 新界面UI

This commit is contained in:
FloatGaming
2026-04-24 13:20:16 +08:00
parent e0bc0bbf08
commit 5eec879582
257 changed files with 38481 additions and 1288 deletions
@@ -6,6 +6,7 @@ using DG.Tweening;
public class SongButton : MonoBehaviour
{
private const bool VerboseLogs = false;
[Header("thisSong_so")]
public ScriptableObject thisSong_so;
[Header("Inspector")]
@@ -42,6 +43,21 @@ public class SongButton : MonoBehaviour
private Coroutine fadeCoroutine;
private Coroutine blinkCoroutine;
public bool IsSelectedForQuickEnter()
{
return selected_boarder != null && selected_boarder.color.a > 0.5f;
}
public SongData GetAssignedSongData()
{
return thisSong_so as SongData;
}
public int GetSongSerialId()
{
return song_songSerialID;
}
public void Start()
{
if (selected_boarder != null)
@@ -58,12 +74,39 @@ public class SongButton : MonoBehaviour
}
}
private void OnDisable()
{
StopVisualCoroutines();
}
private void OnDestroy()
{
StopVisualCoroutines();
if (currentSelected == this)
{
currentSelected = null;
}
}
private void StopVisualCoroutines()
{
if (fadeCoroutine != null)
{
StopCoroutine(fadeCoroutine);
fadeCoroutine = null;
}
if (blinkCoroutine != null)
{
StopCoroutine(blinkCoroutine);
blinkCoroutine = null;
}
}
public void SetButtonData(string songName, int highestScore, int difficultyID, Sprite songSprite, int songID)
{
Debug.Log("SetButtonData called, songID: " + songID);
SongData sd = thisSong_so as SongData;
if (sd != null) sd.LoadPersistent();
if (sd != null) sd.EnsurePersistentDataLoaded();
if (SongDataLibrary.Instance != null && SongDataLibrary.Instance.IsLoaded)
sd = SongDataLibrary.Instance.GetSongDataByID(songID) ?? sd;
if (sd != null)
@@ -193,7 +236,6 @@ public class SongButton : MonoBehaviour
public void OnSongButtonClick()
{
Debug.Log("Song button clicked, song_songSerialID: " + song_songSerialID);
SongData selectedSong = null;
if (SongDataLibrary.Instance != null && SongDataLibrary.Instance.IsLoaded)
{
@@ -205,7 +247,7 @@ public class SongButton : MonoBehaviour
}
if (selectedSong != null)
{
selectedSong.LoadPersistent();
selectedSong.EnsurePersistentDataLoaded();
selectedSong.GetAbsoluteHighestScore(out int bestTotal, out int bestDiff, out string bestDiffName);
if (bestDiff >= 0)
{
@@ -232,7 +274,7 @@ public class SongButton : MonoBehaviour
int index = GetIndexAmongSongButtons();
PlayerPrefs.SetInt(prefsKey, index);
PlayerPrefs.Save();
Debug.Log($"SongButton: saved selected song index {index} for key {prefsKey}");
if (VerboseLogs) Debug.Log($"SongButton: saved selected song index {index} for key {prefsKey}");
}
else
{
@@ -8,6 +8,7 @@ using DG.Tweening;
public class SongSelectUI : MonoBehaviour
{
private const bool VerboseLogs = false;
public SongList songList; // Documentation text normalized.
public GameObject songButtonPrefab; // Documentation text normalized.
public Transform contentPanel; // Documentation text normalized.
@@ -70,6 +71,48 @@ public class SongSelectUI : MonoBehaviour
}
}
private void OnDisable()
{
KillActiveTweensAndCoroutines();
}
private void OnDestroy()
{
KillActiveTweensAndCoroutines();
}
private void KillActiveTweensAndCoroutines()
{
if (buildCoroutine != null)
{
StopCoroutine(buildCoroutine);
buildCoroutine = null;
}
if (switchCoroutine != null)
{
StopCoroutine(switchCoroutine);
switchCoroutine = null;
}
if (restoreCoroutine != null)
{
StopCoroutine(restoreCoroutine);
restoreCoroutine = null;
}
RectTransform root = GetListAnimRoot();
if (root != null)
{
root.DOKill();
}
if (listCanvasGroup != null)
{
listCanvasGroup.DOKill();
}
}
private IEnumerator LoadSceneAsync(string sceneName)
{
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single);
@@ -270,7 +313,7 @@ public class SongSelectUI : MonoBehaviour
var allSongButtons = contentPanel.GetComponentsInChildren<SongButton>(true);
if (allSongButtons == null || allSongButtons.Length == 0)
{
Debug.LogWarning("SongSelectUI.RestoreSelectedSongForCurrentDlc: no song buttons found to restore selection");
if (VerboseLogs) Debug.LogWarning("SongSelectUI.RestoreSelectedSongForCurrentDlc: no song buttons found to restore selection");
return;
}
@@ -300,10 +343,10 @@ public class SongSelectUI : MonoBehaviour
if (btn != null)
{
// simulate click
btn.OnSongButtonClick();
Debug.Log($"SongSelectUI: restored and clicked song index={savedIndex} for key={key}, totalButtons={allSongButtons.Length}");
btn.OnSongButtonClick();
if (VerboseLogs) Debug.Log($"SongSelectUI: restored and clicked song index={savedIndex} for key={key}, totalButtons={allSongButtons.Length}");
}
}
}
private void ClearSongList()
{
@@ -372,8 +415,7 @@ public class SongSelectUI : MonoBehaviour
}
Button button = songButtonObj.GetComponent<Button>();
if (button != null && songButton != null)
button.onClick.AddListener(() => songButton.OnSongButtonClick());
// SongButton.Awake already binds its own click handler. Avoid double invocation here.
}
// helper to avoid hardcoding scene name string in delegate - keeps serializer-friendly field