some updates

This commit is contained in:
FloatGaming
2026-07-25 08:31:10 +08:00
parent af8a0b6810
commit 86351dbd2a
225 changed files with 46757 additions and 590 deletions
@@ -176,7 +176,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!224 &4553002270050802252
RectTransform:
m_ObjectHideFlags: 0
@@ -498,9 +498,9 @@ RectTransform:
- {fileID: 1786747130064482794}
m_Father: {fileID: 6592276605955103311}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 25, y: -58.2}
m_SizeDelta: {x: 50, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6923511498419407553
@@ -813,7 +813,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 312.3, y: 4}
m_AnchoredPosition: {x: 337.7, y: 4}
m_SizeDelta: {x: 200, y: 200}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3397289974922444082
@@ -962,9 +962,9 @@ RectTransform:
- {fileID: 5753355558868935913}
m_Father: {fileID: 6592276605955103311}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 25, y: -25}
m_SizeDelta: {x: 50, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3117658159281603999
@@ -1040,7 +1040,7 @@ RectTransform:
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: -47}
m_SizeDelta: {x: 116.5648, y: 30}
m_SizeDelta: {x: 247.2, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4000680467974343741
CanvasRenderer:
@@ -1077,13 +1077,13 @@ MonoBehaviour:
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 6
m_Alignment: 7
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: "\u6700\u9AD8\u8BC4\u7EA7"
m_Text: "\u5F53\u524D\u96BE\u5EA6\u6700\u9AD8\u8BC4\u7EA7"
--- !u!1 &3377730911931670977
GameObject:
m_ObjectHideFlags: 0
@@ -1175,7 +1175,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!224 &6592276605955103311
RectTransform:
m_ObjectHideFlags: 0
@@ -1336,9 +1336,9 @@ RectTransform:
- {fileID: 6458878320999319224}
m_Father: {fileID: 6592276605955103311}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 25, y: -91.4}
m_SizeDelta: {x: 50, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5018549670956333322
@@ -1803,7 +1803,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 177.6, y: 13.76}
m_AnchoredPosition: {x: 182.6, y: 6.7}
m_SizeDelta: {x: 100, y: 59.109898}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &8522042171786968858
@@ -1978,7 +1978,7 @@ MonoBehaviour:
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: "\u6700\u5927\u96BE\u5EA6\u8BC4\u5206"
m_Text: "\u5F53\u524D\u96BE\u5EA6"
--- !u!1 &9045718542968113931
GameObject:
m_ObjectHideFlags: 0
@@ -2094,4 +2094,4 @@ MonoBehaviour:
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: "\u6700\u9AD8\u603B\u5206"
m_Text: "\u5F53\u524D\u96BE\u5EA6\u7EAA\u5F55"
@@ -152,50 +152,7 @@ public class SongButton : MonoBehaviour
songOverallDescriptionText.text = string.IsNullOrEmpty(sd.thisLevel_overallDescription) ? "" : sd.thisLevel_overallDescription;
}
sd.GetAbsoluteHighestScore(out int bestTotal, out int bestDiff, out string bestDiffName);
if (bestTotal < 0) bestTotal = 0;
if (highestScoreText != null) highestScoreText.text = bestTotal.ToString();
if (highestScoreDifficultyText != null)
highestScoreDifficultyText.text = string.IsNullOrEmpty(bestDiffName) ? "" : "(" + bestDiffName + ")";
if (scoreLevelImage != null)
{
if (rankConfig != null)
{
scoreLevelImage.sprite = rankConfig.GetRankSprite(bestTotal);
}
else
{
Debug.LogWarning("SongButton: rankConfig is not assigned!");
}
}
// Determine displayed difficulty: show the highest difficultyLEVEL present in chartFiles (if any)
string diffDisplay = "0";
if (sd.chartFiles != null && sd.chartFiles.Count > 0)
{
float maxLevel = float.MinValue;
foreach (var entry in sd.chartFiles)
{
if (entry == null) continue;
if (entry.difficultyLEVEL > maxLevel)
{
maxLevel = entry.difficultyLEVEL;
}
}
if (maxLevel != float.MinValue)
{
diffDisplay = maxLevel.ToString();
}
}
if (difficultyIDText != null) difficultyIDText.text = diffDisplay;
// Set rank images for the first three difficulties
SetDifficultyRankImages(sd);
RefreshCurrentDifficultyDisplay(sd, difficultyID);
if (buttonImage != null) buttonImage.sprite = resolvedIllustration != null ? resolvedIllustration : songSprite;
@@ -227,34 +184,166 @@ public class SongButton : MonoBehaviour
}
}
private void SetDifficultyRankImages(SongData sd)
public void RefreshCurrentDifficultyDisplay()
{
if (rankConfig == null) return;
SongData sd = null;
if (SongDataLibrary.Instance != null && SongDataLibrary.Instance.IsLoaded)
{
sd = SongDataLibrary.Instance.GetSongDataByID(song_songSerialID);
}
if (sd == null)
{
sd = thisSong_so as SongData;
}
RefreshCurrentDifficultyDisplay(sd, 0);
}
public static void RefreshAllButtonsForCurrentDifficulty()
{
SongButton[] buttons = UnityEngine.Object.FindObjectsByType<SongButton>(FindObjectsInactive.Include, FindObjectsSortMode.None);
for (int i = 0; i < buttons.Length; i++)
{
if (buttons[i] == null) continue;
buttons[i].RefreshCurrentDifficultyDisplay();
}
}
private void RefreshCurrentDifficultyDisplay(SongData sd, int fallbackDifficulty)
{
if (sd == null)
{
if (highestScoreText != null) highestScoreText.text = "0";
if (highestScoreDifficultyText != null) highestScoreDifficultyText.text = "";
if (difficultyIDText != null) difficultyIDText.text = fallbackDifficulty.ToString();
ApplyScoreRankSprite(0);
ClearDifficultyRankImages();
return;
}
sd.EnsurePersistentDataLoaded();
int currentDifficulty = ResolveCurrentDisplayDifficulty(sd, fallbackDifficulty);
ChartFileEntry entry = FindChartEntry(sd, currentDifficulty);
float difficultyLevel = entry != null ? entry.difficultyLEVEL : currentDifficulty;
int totalForDifficulty = GetTotalRecordForDifficulty(sd, currentDifficulty, entry);
string difficultyName = GetDifficultyCode(currentDifficulty);
if (highestScoreText != null) highestScoreText.text = totalForDifficulty.ToString();
if (highestScoreDifficultyText != null) highestScoreDifficultyText.text = "(" + difficultyName + ")";
if (difficultyIDText != null)
{
string difficultyLevelText = difficultyLevel.ToString("0.#");
difficultyIDText.text = string.IsNullOrEmpty(difficultyName)
? difficultyLevelText
: difficultyLevelText + " (" + difficultyName + ")";
}
ApplyScoreRankSprite(totalForDifficulty);
ClearDifficultyRankImages();
}
private int ResolveCurrentDisplayDifficulty(SongData sd, int fallbackDifficulty)
{
if (sd == null)
{
return Mathf.Clamp(fallbackDifficulty, 0, 3);
}
int difficulty = Mathf.Clamp(sd.thisLevel_selectedDifficultyID, 0, 3);
string difficultyKey = BuildSongSelectedDifficultyPrefsKey(sd.songID);
if (PlayerPrefs.HasKey(difficultyKey))
{
difficulty = Mathf.Clamp(PlayerPrefs.GetInt(difficultyKey, difficulty), 0, 3);
}
if (FindChartEntry(sd, difficulty) != null || sd.GetResolvedChartFile(difficulty) != null)
{
return difficulty;
}
int fallback = Mathf.Clamp(fallbackDifficulty, 0, 3);
if (FindChartEntry(sd, fallback) != null || sd.GetResolvedChartFile(fallback) != null)
{
return fallback;
}
return GetFirstAvailableDifficulty(sd);
}
private string GetDifficultyCode(int difficulty)
{
switch (difficulty)
{
case 0: return "EZ";
case 1: return "HD";
case 2: return "IN";
case 3: return "IM";
default: return difficulty.ToString();
}
}
private ChartFileEntry FindChartEntry(SongData sd, int difficulty)
{
if (sd == null || sd.chartFiles == null)
{
return null;
}
for (int i = 0; i < sd.chartFiles.Count; i++)
{
ChartFileEntry entry = sd.chartFiles[i];
if (entry != null && entry.difficulty == difficulty)
{
return entry;
}
}
return null;
}
private int GetTotalRecordForDifficulty(SongData sd, int difficulty, ChartFileEntry entry)
{
int total = entry != null ? entry.totalPersonalRecordForThisDifficulty : 0;
if (total <= 0 && entry != null)
{
total = entry.chartPersonalRecordForThisDifficulty + entry.idolPersonalRecordForThisDifficulty;
}
if (total <= 0 && sd != null)
{
total = sd.GetPersonalRecord(difficulty) + sd.GetIdolRecord(difficulty);
}
return Mathf.Max(0, total);
}
private void ApplyScoreRankSprite(int score)
{
if (scoreLevelImage == null)
{
return;
}
if (rankConfig != null)
{
scoreLevelImage.sprite = rankConfig.GetRankSprite(score);
scoreLevelImage.enabled = scoreLevelImage.sprite != null;
}
else
{
scoreLevelImage.enabled = false;
Debug.LogWarning("SongButton: rankConfig is not assigned!");
}
}
private void ClearDifficultyRankImages()
{
Image[] rankImages = { lvl_img_01, lvl_img_02, lvl_img_03 };
for (int i = 0; i < rankImages.Length; i++)
{
if (rankImages[i] == null) continue;
if (sd.chartFiles != null && i < sd.chartFiles.Count)
{
var entry = sd.chartFiles[i];
if (entry != null)
{
int score = entry.totalPersonalRecordForThisDifficulty;
rankImages[i].sprite = rankConfig.GetRankSprite(score);
rankImages[i].enabled = rankImages[i].sprite != null;
}
else
{
rankImages[i].enabled = false;
}
}
else
{
rankImages[i].enabled = false;
}
rankImages[i].enabled = false;
}
}
@@ -282,6 +371,7 @@ public class SongButton : MonoBehaviour
FadeInSelectedBorder();
SongDataHolder.SelectedSongData = selectedSong;
RefreshCurrentDifficultyDisplay(selectedSong, selectedSong.thisLevel_selectedDifficultyID);
var selectedInfo = SceneObjectLookupCache.FindAny<selected_songInfo>();
if (selectedInfo != null)
{
@@ -313,6 +403,12 @@ public class SongButton : MonoBehaviour
}
int songId = selectedSong.songID;
int globalDifficulty = SongSelectUI.GetSelectedDifficulty();
if (IsDifficultyAvailable(selectedSong, globalDifficulty))
{
return globalDifficulty;
}
string difficultyKey = BuildSongSelectedDifficultyPrefsKey(songId);
if (PlayerPrefs.HasKey(difficultyKey))
{
@@ -33,6 +33,8 @@ public class SongSelectUI : MonoBehaviour
// Current DLC key used for per-DLC saved song selection
public static string CurrentDlcKey = "dlc_default_0";
public static bool ForceFirstSongOnNextRestore;
private const string GlobalSelectedDifficultyPrefsKey = "song_select_global_difficulty";
private static int cachedSelectedDifficulty = -1;
// Track pending restore to avoid multiple overlapping restores
private Coroutine restoreCoroutine;
@@ -72,6 +74,79 @@ public class SongSelectUI : MonoBehaviour
}
}
public static int GetSelectedDifficulty()
{
if (cachedSelectedDifficulty < 0)
{
cachedSelectedDifficulty = Mathf.Clamp(PlayerPrefs.GetInt(GlobalSelectedDifficultyPrefsKey, 0), 0, 3);
}
return cachedSelectedDifficulty;
}
public static void SetSelectedDifficulty(int difficulty)
{
cachedSelectedDifficulty = Mathf.Clamp(difficulty, 0, 3);
PlayerPrefs.SetInt(GlobalSelectedDifficultyPrefsKey, cachedSelectedDifficulty);
PlayerPrefs.Save();
}
public static void ApplySelectedDifficultyToLoadedSongButtons()
{
int difficulty = GetSelectedDifficulty();
SongButton[] buttons = UnityEngine.Object.FindObjectsByType<SongButton>(FindObjectsInactive.Include, FindObjectsSortMode.None);
for (int i = 0; i < buttons.Length; i++)
{
SongButton button = buttons[i];
if (button == null)
{
continue;
}
SongData song = button.GetAssignedSongData();
ApplySelectedDifficultyToSong(song, difficulty, true);
button.RefreshCurrentDifficultyDisplay();
}
PlayerPrefs.Save();
}
public static void ApplySelectedDifficultyToSongList(IEnumerable<SongData> songs)
{
int difficulty = GetSelectedDifficulty();
if (songs == null)
{
return;
}
foreach (SongData song in songs)
{
ApplySelectedDifficultyToSong(song, difficulty, true);
}
PlayerPrefs.Save();
}
public static void ApplySelectedDifficultyToSong(SongData song)
{
ApplySelectedDifficultyToSong(song, GetSelectedDifficulty(), true);
}
private static void ApplySelectedDifficultyToSong(SongData song, int difficulty, bool persist)
{
if (song == null)
{
return;
}
difficulty = Mathf.Clamp(difficulty, 0, 3);
song.thisLevel_selectedDifficultyID = difficulty;
if (persist)
{
PlayerPrefs.SetInt(SongButton.BuildSongSelectedDifficultyPrefsKey(song.songID), difficulty);
}
}
private void OnDisable()
{
KillActiveTweensAndCoroutines();
@@ -180,6 +255,8 @@ public class SongSelectUI : MonoBehaviour
// allow UI to render a frame before heavy instantiation
yield return null;
ApplySelectedDifficultyToSongList(list);
int count = 0;
foreach (var song in list)
{
@@ -449,7 +526,7 @@ public class SongSelectUI : MonoBehaviour
TMP_Text[] texts = songButtonObj.GetComponentsInChildren<TMP_Text>();
if (texts.Length >= 4)
if (songButton == null && texts.Length >= 4)
{
texts[0].text = song.songName;
texts[1].text = "Record : " + bestTotal;