重做粗略选曲界面 浮动小游戏可开关
修复一些小bug和加入部分新功能
This commit is contained in:
@@ -9,7 +9,7 @@ public class ChartFileEntry
|
||||
public int difficulty; // 该谱面对应的难度序列号
|
||||
[Header("展示给用户的难度分级:float数字")]
|
||||
public float difficultyLEVEL;
|
||||
[Header("本难度敌人总生命值=音符数量×下面的倍率")]
|
||||
[Header("本难本难度敌人总生命值=音符数量×下面的倍率")]
|
||||
public float enemyTotalHP_Multiplier;
|
||||
[Header("ez/hd/im/in 没啥用")]
|
||||
public string difficultyName; // 难度名称
|
||||
@@ -19,11 +19,13 @@ public class ChartFileEntry
|
||||
[TextArea(3,10)]
|
||||
public string difficultyDescription;
|
||||
[Header("本关本难度上次游玩分数记录")]
|
||||
public int lastScoreForThisDifficulty;
|
||||
[Header("本关本难度最佳纪录")]
|
||||
public int pmScore_personalRecordForThisDifficulty;
|
||||
public int idolScore_personalRecordForThisDifficulty;
|
||||
public int personalRecordForThisDifficulty;
|
||||
public int lastScoreForThisDifficulty; // 上次游玩(总分/参考)
|
||||
[Header("本关本难度个人分记录(谱面分)")]
|
||||
public int chartPersonalRecordForThisDifficulty; // 谱面(个人)分
|
||||
[Header("本关本难度偶像分记录")]
|
||||
public int idolPersonalRecordForThisDifficulty; // 偶像分
|
||||
[Header("本关本难度总分展示 (谱面分 + 偶像分)")]
|
||||
public int totalPersonalRecordForThisDifficulty; // 展示用:谱面分 + 偶像分 (总分)
|
||||
[Header("本关本难度进度")]
|
||||
public float levelProgressForThisDifficulty;
|
||||
[Header("本关本难度最后游玩时间")]
|
||||
@@ -52,21 +54,30 @@ public class SongData : ScriptableObject
|
||||
public int time_totalPlayingTime;
|
||||
public DateTime uploadData;
|
||||
|
||||
[Header("各种图")]
|
||||
public Sprite illustration;
|
||||
public Sprite backgroudPIC;
|
||||
public Sprite fullscreen_songPicture;
|
||||
public Sprite card_profileImage;
|
||||
[Header("右侧卡片用图")]
|
||||
public Sprite right_pic_bottom_image;
|
||||
public Sprite right_pic_top_image;
|
||||
[Header("音乐")]
|
||||
public AudioClip audioFile;
|
||||
public AudioClip audio_previewAudio;
|
||||
|
||||
[Header("")]
|
||||
// 支持不同难度的数据
|
||||
public Dictionary<int, int> difficultyNumberMap = new Dictionary<int, int>(); // 各个难度的难度数值
|
||||
public Dictionary<int, int> personalRecordMap = new Dictionary<int, int>(); // 各个难度的最高分
|
||||
public Dictionary<int, int> personalRecordMap = new Dictionary<int, int>(); // 各个难度的谱面(个人)最高分
|
||||
public Dictionary<int, int> idolRecordMap = new Dictionary<int, int>(); // 各个难度的偶像分
|
||||
public Dictionary<int, int> chartScoreMap = new Dictionary<int, int>(); // 各个难度的谱面(上次)分数记录
|
||||
public Dictionary<int, TextAsset> chartFileMap = new Dictionary<int, TextAsset>(); // 各个难度下的谱面文件
|
||||
|
||||
// 用于在 Inspector 选择谱面文件
|
||||
public List<ChartFileEntry> chartFiles = new List<ChartFileEntry>();
|
||||
|
||||
// 个人最高记录(所有难度中的最高分)
|
||||
// 个人最高记录(所有难度中的最高分) - 这里表示最高的「谱面分 + 偶像分」之和(全谱面最高)
|
||||
public int personalRecord;
|
||||
|
||||
// 当前游玩的难度
|
||||
@@ -78,6 +89,30 @@ public class SongData : ScriptableObject
|
||||
[Header("当前选择的关卡难度")]
|
||||
public int thisLevel_selectedDifficultyID;
|
||||
|
||||
[Header("本关卡加入时间:字符串格式yyyy-mm-dd")]
|
||||
public string thisLevel_addDateString;
|
||||
|
||||
[Header("本关卡总体简介")]
|
||||
[TextArea(3,10)]
|
||||
public string thisLevel_overallDescription;
|
||||
|
||||
// Ensure dictionaries initialized when ScriptableObject is loaded/deserialized
|
||||
private void OnEnable()
|
||||
{
|
||||
if (difficultyNumberMap == null) difficultyNumberMap = new Dictionary<int, int>();
|
||||
if (personalRecordMap == null) personalRecordMap = new Dictionary<int, int>();
|
||||
if (idolRecordMap == null) idolRecordMap = new Dictionary<int, int>();
|
||||
if (chartScoreMap == null) chartScoreMap = new Dictionary<int, int>();
|
||||
if (chartFileMap == null) chartFileMap = new Dictionary<int, TextAsset>();
|
||||
|
||||
// If chartFiles exist in inspector, ensure maps reflect them
|
||||
if (chartFiles != null && chartFiles.Count > 0)
|
||||
{
|
||||
SyncRecordsFromChartFiles();
|
||||
SyncChartFileMap();
|
||||
}
|
||||
}
|
||||
|
||||
// 构造函数:从 JSON 数据创建 SongData
|
||||
public SongData(SongDataSerializable jsonData)
|
||||
{
|
||||
@@ -102,8 +137,10 @@ public class SongData : ScriptableObject
|
||||
_if_level_is_EASE = jsonData._if_level_is_EASE;
|
||||
max_comboRecord = jsonData.max_comboRecord;
|
||||
|
||||
difficultyNumberMap = jsonData.difficultyNumberMap;
|
||||
personalRecordMap = jsonData.personalRecordMap;
|
||||
difficultyNumberMap = jsonData.difficultyNumberMap ?? new Dictionary<int,int>();
|
||||
personalRecordMap = jsonData.personalRecordMap ?? new Dictionary<int,int>();
|
||||
idolRecordMap = jsonData.idolRecordMap ?? new Dictionary<int,int>();
|
||||
chartScoreMap = jsonData.chartScoreMap ?? new Dictionary<int,int>();
|
||||
personalRecord = jsonData.personalRecord; // 赋值最高成绩
|
||||
|
||||
// 确保 JSON 里的谱面文件映射到可用的 List
|
||||
@@ -112,42 +149,119 @@ public class SongData : ScriptableObject
|
||||
chartFiles.Add(new ChartFileEntry { difficulty = kvp.Key, chartFile = Resources.Load<TextAsset>("Charts/" + kvp.Value) });
|
||||
}
|
||||
SyncChartFileMap();
|
||||
|
||||
// 从 chartFiles 中同步各难度的记录到字典(如果 inspector 中有填写)
|
||||
SyncRecordsFromChartFiles();
|
||||
|
||||
// Ensure per-difficulty chartScoreMap populated from entries if not present
|
||||
foreach (var entry in chartFiles)
|
||||
{
|
||||
if (!chartScoreMap.ContainsKey(entry.difficulty))
|
||||
chartScoreMap[entry.difficulty] = entry.lastScoreForThisDifficulty;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有难度中最高的成绩
|
||||
// 获取所有难度中最高的成绩(谱面分 + 偶像分 的最大和)
|
||||
public int CalculateHighestPersonalRecord()
|
||||
{
|
||||
if (personalRecordMap == null) personalRecordMap = new Dictionary<int,int>();
|
||||
if (idolRecordMap == null) idolRecordMap = new Dictionary<int,int>();
|
||||
|
||||
int highest = 0;
|
||||
foreach (var score in personalRecordMap.Values)
|
||||
foreach (var kvp in personalRecordMap)
|
||||
{
|
||||
if (score > highest)
|
||||
int diff = kvp.Key;
|
||||
int p = kvp.Value;
|
||||
int i = idolRecordMap.ContainsKey(diff) ? idolRecordMap[diff] : 0;
|
||||
int combined = p + i;
|
||||
if (combined > highest)
|
||||
{
|
||||
highest = score;
|
||||
highest = combined;
|
||||
}
|
||||
}
|
||||
personalRecord = highest;
|
||||
return highest;
|
||||
}
|
||||
|
||||
// 更新指定难度的最高成绩
|
||||
// 更新指定难度的谱面(个人)最高成绩
|
||||
public void UpdatePersonalRecord(int difficulty, int newScore)
|
||||
{
|
||||
if (personalRecordMap == null) personalRecordMap = new Dictionary<int,int>();
|
||||
if (!personalRecordMap.ContainsKey(difficulty) || newScore > personalRecordMap[difficulty])
|
||||
{
|
||||
personalRecordMap[difficulty] = newScore;
|
||||
}
|
||||
|
||||
// also update corresponding ChartFileEntry if exists
|
||||
var entry = chartFiles != null ? chartFiles.Find(e => e.difficulty == difficulty) : null;
|
||||
if (entry != null)
|
||||
{
|
||||
entry.chartPersonalRecordForThisDifficulty = personalRecordMap[difficulty];
|
||||
int idol = idolRecordMap != null && idolRecordMap.ContainsKey(difficulty) ? idolRecordMap[difficulty] : 0;
|
||||
entry.totalPersonalRecordForThisDifficulty = personalRecordMap[difficulty] + idol;
|
||||
}
|
||||
|
||||
CalculateHighestPersonalRecord();
|
||||
}
|
||||
|
||||
// 获取特定难度的最高分
|
||||
// 更新指定难度的偶像分
|
||||
public void UpdateIdolRecord(int difficulty, int newIdolScore)
|
||||
{
|
||||
if (idolRecordMap == null) idolRecordMap = new Dictionary<int,int>();
|
||||
if (!idolRecordMap.ContainsKey(difficulty) || newIdolScore > idolRecordMap[difficulty])
|
||||
{
|
||||
idolRecordMap[difficulty] = newIdolScore;
|
||||
}
|
||||
|
||||
// also update corresponding ChartFileEntry if exists
|
||||
var entry = chartFiles != null ? chartFiles.Find(e => e.difficulty == difficulty) : null;
|
||||
if (entry != null)
|
||||
{
|
||||
entry.idolPersonalRecordForThisDifficulty = idolRecordMap[difficulty];
|
||||
int personal = personalRecordMap != null && personalRecordMap.ContainsKey(difficulty) ? personalRecordMap[difficulty] : 0;
|
||||
entry.totalPersonalRecordForThisDifficulty = personal + idolRecordMap[difficulty];
|
||||
}
|
||||
|
||||
CalculateHighestPersonalRecord();
|
||||
}
|
||||
|
||||
// 更新或设置谱面上次分数记录(last run 总分)
|
||||
public void UpdateChartScore(int difficulty, int newChartScore)
|
||||
{
|
||||
if (chartScoreMap == null) chartScoreMap = new Dictionary<int,int>();
|
||||
chartScoreMap[difficulty] = newChartScore;
|
||||
var entry = chartFiles != null ? chartFiles.Find(e => e.difficulty == difficulty) : null;
|
||||
if (entry != null)
|
||||
{
|
||||
entry.lastScoreForThisDifficulty = newChartScore;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取特定难度的谱面(个人)最高分
|
||||
public int GetPersonalRecord(int difficulty)
|
||||
{
|
||||
if (personalRecordMap == null) return 0;
|
||||
return personalRecordMap.ContainsKey(difficulty) ? personalRecordMap[difficulty] : 0;
|
||||
}
|
||||
|
||||
// 获取特定难度的偶像分
|
||||
public int GetIdolRecord(int difficulty)
|
||||
{
|
||||
if (idolRecordMap == null) return 0;
|
||||
return idolRecordMap.ContainsKey(difficulty) ? idolRecordMap[difficulty] : 0;
|
||||
}
|
||||
|
||||
// 获取特定难度的谱面(上次)分数
|
||||
public int GetChartScore(int difficulty)
|
||||
{
|
||||
if (chartScoreMap == null) return 0;
|
||||
return chartScoreMap.ContainsKey(difficulty) ? chartScoreMap[difficulty] : 0;
|
||||
}
|
||||
|
||||
// 获取指定难度的谱面文件
|
||||
public TextAsset GetChartFile(int difficulty)
|
||||
{
|
||||
if (chartFiles == null) return null;
|
||||
foreach (var entry in chartFiles)
|
||||
{
|
||||
if (entry.difficulty == difficulty)
|
||||
@@ -159,7 +273,9 @@ public class SongData : ScriptableObject
|
||||
// 同步 Dictionary 和 List 确保数据一致
|
||||
public void SyncChartFileMap()
|
||||
{
|
||||
if (chartFileMap == null) chartFileMap = new Dictionary<int, TextAsset>();
|
||||
chartFileMap.Clear();
|
||||
if (chartFiles == null) return;
|
||||
foreach (var entry in chartFiles)
|
||||
{
|
||||
if (entry.chartFile != null)
|
||||
@@ -168,4 +284,36 @@ public class SongData : ScriptableObject
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 从 chartFiles 中读取各难度的谱面分/偶像分到 Map(用于 inspector 已填写时)
|
||||
public void SyncRecordsFromChartFiles()
|
||||
{
|
||||
if (personalRecordMap == null) personalRecordMap = new Dictionary<int,int>();
|
||||
if (idolRecordMap == null) idolRecordMap = new Dictionary<int,int>();
|
||||
if (chartScoreMap == null) chartScoreMap = new Dictionary<int,int>();
|
||||
|
||||
if (chartFiles == null) return;
|
||||
foreach (var entry in chartFiles)
|
||||
{
|
||||
if (entry == null) continue;
|
||||
if (!personalRecordMap.ContainsKey(entry.difficulty) || entry.chartPersonalRecordForThisDifficulty > personalRecordMap[entry.difficulty])
|
||||
{
|
||||
personalRecordMap[entry.difficulty] = entry.chartPersonalRecordForThisDifficulty;
|
||||
}
|
||||
if (!idolRecordMap.ContainsKey(entry.difficulty) || entry.idolPersonalRecordForThisDifficulty > idolRecordMap[entry.difficulty])
|
||||
{
|
||||
idolRecordMap[entry.difficulty] = entry.idolPersonalRecordForThisDifficulty;
|
||||
}
|
||||
if (!chartScoreMap.ContainsKey(entry.difficulty) || entry.lastScoreForThisDifficulty > chartScoreMap[entry.difficulty])
|
||||
{
|
||||
chartScoreMap[entry.difficulty] = entry.lastScoreForThisDifficulty;
|
||||
}
|
||||
// keep per-entry convenience field in sync to combined total
|
||||
int p = personalRecordMap.ContainsKey(entry.difficulty) ? personalRecordMap[entry.difficulty] : 0;
|
||||
int i = idolRecordMap.ContainsKey(entry.difficulty) ? idolRecordMap[entry.difficulty] : 0;
|
||||
entry.totalPersonalRecordForThisDifficulty = p + i;
|
||||
}
|
||||
|
||||
CalculateHighestPersonalRecord();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,36 +1,134 @@
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
public class SongButton : MonoBehaviour
|
||||
{
|
||||
public TextMeshProUGUI songNameText; // 歌曲名称文本
|
||||
public TextMeshProUGUI highestScoreText; // 个人最高分文本
|
||||
public TextMeshProUGUI difficultyIDText; // 难度ID文本
|
||||
public TextMeshProUGUI songIDText;
|
||||
public Image buttonImage; // 按钮的 Image 组件,用于设置背景图像
|
||||
public int song_songSerialID; // 按钮对应的歌曲ID
|
||||
|
||||
// 设置按钮的数据
|
||||
[Header("thisSong_so")]
|
||||
public ScriptableObject thisSong_so;
|
||||
[Header("展示的信息")]
|
||||
public Text songNameText;
|
||||
public Text multiNameText;
|
||||
public Text joinTime_and_dlcName_Text;
|
||||
public Text songOverallDescriptionText;
|
||||
public Text highestScoreText;
|
||||
public Text difficultyIDText;
|
||||
public Text songIDText;
|
||||
public Image buttonImage;
|
||||
[Header("头图")]
|
||||
public Image profileImage;
|
||||
public int song_songSerialID;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void SetButtonData(string songName, int highestScore, int difficultyID, Sprite songSprite, int songID)
|
||||
{
|
||||
Debug.Log("SetButtonData 被调用, songID 参数: " + songID);
|
||||
songNameText.text = songName;
|
||||
highestScoreText.text = "PR: " + highestScore.ToString();
|
||||
difficultyIDText.text = "" + difficultyID.ToString();
|
||||
buttonImage.sprite = songSprite;
|
||||
song_songSerialID = songID;
|
||||
songIDText.text = "Song ID: " + song_songSerialID.ToString();
|
||||
|
||||
// try to load SongData by id and populate fields from SO when available
|
||||
var sd = SongDataLibrary.Instance != null ? SongDataLibrary.Instance.GetSongDataByID(songID) : null;
|
||||
if (sd != null)
|
||||
{
|
||||
// song name
|
||||
if (songNameText != null) songNameText.text = sd.songName;
|
||||
|
||||
// multi name text: 音乐:artist | 曲绘:painter | 制谱:level_creator
|
||||
if (multiNameText != null)
|
||||
multiNameText.text = "音乐:" + sd.artistName + " | 曲绘:" + sd.painter + " | 制谱:" + sd.level_creator;
|
||||
|
||||
// song join time and DLC
|
||||
if (joinTime_and_dlcName_Text != null)
|
||||
{
|
||||
string join = string.IsNullOrEmpty(sd.thisLevel_addDateString) ? "未知" : sd.thisLevel_addDateString;
|
||||
string dlc = string.IsNullOrEmpty(sd.belongsTo_whichDLC) ? "未归档DLC" : sd.belongsTo_whichDLC;
|
||||
joinTime_and_dlcName_Text.text = "歌曲收录时间:" + join + " | " + "所属DLC:" + dlc;
|
||||
}
|
||||
|
||||
// song overall description
|
||||
if (songOverallDescriptionText != null)
|
||||
{
|
||||
songOverallDescriptionText.text = string.IsNullOrEmpty(sd.thisLevel_overallDescription) ? "暂无歌曲简介。" : sd.thisLevel_overallDescription;
|
||||
}
|
||||
|
||||
// compute highest total (chart personal + idol) and its difficulty
|
||||
int bestTotal = 0;
|
||||
int bestDiff = -1;
|
||||
if (sd.personalRecordMap != null)
|
||||
{
|
||||
foreach (var kvp in sd.personalRecordMap)
|
||||
{
|
||||
int diff = kvp.Key;
|
||||
int p = kvp.Value;
|
||||
int i = sd.GetIdolRecord(diff);
|
||||
int combined = p + i;
|
||||
if (combined > bestTotal)
|
||||
{
|
||||
bestTotal = combined;
|
||||
bestDiff = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fallback: use stored personalRecord and selected difficulty if maps empty
|
||||
if (bestDiff == -1)
|
||||
{
|
||||
bestTotal = sd.personalRecord;
|
||||
bestDiff = sd.thisLevel_selectedDifficultyID;
|
||||
}
|
||||
|
||||
if (highestScoreText != null) highestScoreText.text = bestTotal.ToString();
|
||||
|
||||
// difficultyIDText: show difficultyLEVEL from ChartFileEntry of bestDiff if available, else show numeric id
|
||||
string diffDisplay = bestDiff.ToString();
|
||||
if (sd.chartFiles != null)
|
||||
{
|
||||
foreach (var entry in sd.chartFiles)
|
||||
{
|
||||
if (entry != null && entry.difficulty == bestDiff)
|
||||
{
|
||||
diffDisplay = entry.difficultyLEVEL.ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (difficultyIDText != null) difficultyIDText.text = diffDisplay;
|
||||
|
||||
// button image
|
||||
if (buttonImage != null) buttonImage.sprite = sd.backgroudPIC;
|
||||
|
||||
// profile image: use card_profileImage from SO
|
||||
if (profileImage != null)
|
||||
{
|
||||
profileImage.sprite = sd.card_profileImage;
|
||||
if (sd.card_profileImage != null)
|
||||
{
|
||||
profileImage.color = new Color(profileImage.color.r, profileImage.color.g, profileImage.color.b, 1f);
|
||||
profileImage.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// hide if no sprite
|
||||
profileImage.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
song_songSerialID = songID;
|
||||
if (songIDText != null) songIDText.text = "数据库索引号:" + song_songSerialID.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// fallback to original behavior if SO not found
|
||||
if (songNameText != null) songNameText.text = songName;
|
||||
if (highestScoreText != null) highestScoreText.text = "PR: " + highestScore.ToString();
|
||||
if (difficultyIDText != null) difficultyIDText.text = difficultyID.ToString();
|
||||
if (buttonImage != null) buttonImage.sprite = songSprite;
|
||||
song_songSerialID = songID;
|
||||
if (songIDText != null) songIDText.text = "Song ID: " + song_songSerialID.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 按钮点击事件:根据 song_songSerialID 查找对应的 SongData,并传递到下个场景
|
||||
public void OnSongButtonClick()
|
||||
{
|
||||
Debug.Log("点击按钮的 song_songSerialID: " + song_songSerialID);
|
||||
@@ -45,5 +143,4 @@ public class SongButton : MonoBehaviour
|
||||
Debug.LogError("未找到对应的 SongData, songID: " + song_songSerialID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class SongSelectUI : MonoBehaviour
|
||||
{
|
||||
@@ -9,9 +10,9 @@ public class SongSelectUI : MonoBehaviour
|
||||
public GameObject songButtonPrefab; // 歌曲按钮的 Prefab (Button)
|
||||
public Transform contentPanel; // 滚动视图的 Content 面板
|
||||
|
||||
|
||||
[SerializeField] Button button_Main;
|
||||
[SerializeField] string ui_Main_Scene_Name = "UI_UI";
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (songList == null || songButtonPrefab == null || contentPanel == null)
|
||||
@@ -21,77 +22,80 @@ public class SongSelectUI : MonoBehaviour
|
||||
}
|
||||
|
||||
button_Main.onClick.AddListener(
|
||||
() => SceneManager.LoadScene(ui_Main_Scene_Name, LoadSceneMode.Single));
|
||||
DisplaySongs();
|
||||
() => SceneManager.LoadScene(ui_Main_Scene_NAME(), LoadSceneMode.Single));
|
||||
// Do not populate the song list at start. DLC buttons will request songs when clicked.
|
||||
}
|
||||
|
||||
// 显示所有歌曲
|
||||
void DisplaySongs()
|
||||
// 显示所有歌曲 (kept for manual use)
|
||||
public void DisplaySongs()
|
||||
{
|
||||
// 清空现有按钮
|
||||
foreach (Transform child in contentPanel)
|
||||
{
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
ClearSongList();
|
||||
|
||||
// 为每首歌曲创建一个按钮
|
||||
foreach (SongData song in songList.songs)
|
||||
{
|
||||
GameObject songButtonObj = Instantiate(songButtonPrefab, contentPanel);
|
||||
songButtonObj.transform.SetParent(contentPanel, false); // 确保 UI 结构正确
|
||||
|
||||
// 获取 SongButton 组件
|
||||
SongButton songButton = songButtonObj.GetComponent<SongButton>();
|
||||
if (songButton != null)
|
||||
{
|
||||
// 调用 SetButtonData 赋值
|
||||
songButton.SetButtonData(song.songName, song.personalRecord, song.difficultyID, song.illustration, song.songID);
|
||||
Debug.Log(" SetButtonData 被调用,songID: " + song.songID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError(" SongButton 组件未找到!");
|
||||
}
|
||||
|
||||
// **获取组件**
|
||||
Image songImage = songButtonObj.GetComponentInChildren<Image>(); // 获取图片组件
|
||||
TMP_Text[] texts = songButtonObj.GetComponentsInChildren<TMP_Text>();
|
||||
|
||||
if (songImage != null && song.illustration != null)
|
||||
{
|
||||
songImage.sprite = song.illustration; // 设置歌曲图片
|
||||
songImage.enabled = true;
|
||||
Debug.Log(" 设置图片:" + song.songName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(" Illustration 为空:" + song.songName);
|
||||
}
|
||||
|
||||
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();
|
||||
Debug.Log(" 设置文本:" + song.songName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("TextMeshPro 组件未找到");
|
||||
}
|
||||
|
||||
// **添加按钮事件**
|
||||
Button button = songButtonObj.GetComponent<Button>();
|
||||
button.onClick.AddListener(() => songButton.OnSongButtonClick());
|
||||
InstantiateSongButton(song);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 处理点击事件
|
||||
void OnSongButtonClicked(SongData song)
|
||||
// Instantiate from a provided list (used by dlcButton to show DLC songs)
|
||||
public void DisplaySongsFromList(List<SongData> list)
|
||||
{
|
||||
ClearSongList();
|
||||
|
||||
Debug.Log("🎵 选择歌曲:" + song.songName);
|
||||
if (list == null) return;
|
||||
foreach (var song in list)
|
||||
InstantiateSongButton(song);
|
||||
}
|
||||
|
||||
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<SongButton>();
|
||||
if (songButton != null)
|
||||
{
|
||||
songButton.SetButtonData(song.songName, song.personalRecord, song.difficultyID, song.illustration, song.songID);
|
||||
}
|
||||
|
||||
Image songImage = songButtonObj.GetComponentInChildren<Image>();
|
||||
TMP_Text[] texts = songButtonObj.GetComponentsInChildren<TMP_Text>();
|
||||
|
||||
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<Button>();
|
||||
if (button != null && songButton != null)
|
||||
button.onClick.AddListener(() => songButton.OnSongButtonClick());
|
||||
}
|
||||
|
||||
// helper to avoid hardcoding scene name string in delegate - keeps serializer-friendly field
|
||||
private string ui_Main_Scene_NAME() => ui_Main_Scene_Name;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class columnCardPrefab : MonoBehaviour
|
||||
{
|
||||
public Text columnNameText;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ff04e907f9cfb641a665f86e522cc85
|
||||
@@ -0,0 +1,207 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &1637007196218061563
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4551918553106998792}
|
||||
- component: {fileID: 758928773360508562}
|
||||
m_Layer: 5
|
||||
m_Name: columnText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &4551918553106998792
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1637007196218061563}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 6351664261704272468}
|
||||
- {fileID: 1698067159425250057}
|
||||
m_Father: {fileID: 0}
|
||||
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: 0, y: 0}
|
||||
m_SizeDelta: {x: 100, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &758928773360508562
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1637007196218061563}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 3ff04e907f9cfb641a665f86e522cc85, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
columnNameText: {fileID: 4717264116647129508}
|
||||
--- !u!1 &4388442211447082941
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6351664261704272468}
|
||||
- component: {fileID: 6379280332863238883}
|
||||
- component: {fileID: 542043941311315801}
|
||||
m_Layer: 5
|
||||
m_Name: btm
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &6351664261704272468
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4388442211447082941}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0.34, y: 0.34, z: 0.34}
|
||||
m_ConstrainProportionsScale: 1
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4551918553106998792}
|
||||
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: 0, y: 0}
|
||||
m_SizeDelta: {x: 501, y: 26}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6379280332863238883
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4388442211447082941}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &542043941311315801
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4388442211447082941}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: f47d8a39555c75d4aa3ca75114e70bc4, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 2
|
||||
--- !u!1 &6372430374524420013
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1698067159425250057}
|
||||
- component: {fileID: 1287313482979308491}
|
||||
- component: {fileID: 4717264116647129508}
|
||||
m_Layer: 5
|
||||
m_Name: ClmName
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1698067159425250057
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6372430374524420013}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4551918553106998792}
|
||||
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: 0, y: 0}
|
||||
m_SizeDelta: {x: 160, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &1287313482979308491
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6372430374524420013}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &4717264116647129508
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6372430374524420013}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 12800000, guid: cc180dff846d13a4d88ddaed6f77e5cd, type: 3}
|
||||
m_FontSize: 20
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 2
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "\u680F\u76EE\u540D"
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65079dfab509cba44983a7a031cbc6ea
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,541 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &138029197584297892
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 570804039580569020}
|
||||
- component: {fileID: 4445277613365452210}
|
||||
- component: {fileID: 2931296379136689410}
|
||||
m_Layer: 5
|
||||
m_Name: dlcProducer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &570804039580569020
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 138029197584297892}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5010078828579475845}
|
||||
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: 25.636463, y: -5.3366528}
|
||||
m_SizeDelta: {x: 197.413, y: 16}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4445277613365452210
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 138029197584297892}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &2931296379136689410
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 138029197584297892}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 12800000, guid: 775c674e81662c644b64550d2e8f74e0, type: 3}
|
||||
m_FontSize: 16
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 3
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "dlc\u51FA\u54C1\u65B9"
|
||||
--- !u!1 &773692126744785227
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 333634122881333044}
|
||||
- component: {fileID: 8988852884214291751}
|
||||
- component: {fileID: 3713972282091736206}
|
||||
m_Layer: 5
|
||||
m_Name: dlcPublishDate
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &333634122881333044
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 773692126744785227}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5010078828579475845}
|
||||
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: 25.636463, y: -21.336693}
|
||||
m_SizeDelta: {x: 197.413, y: 16}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8988852884214291751
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 773692126744785227}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &3713972282091736206
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 773692126744785227}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 12800000, guid: 775c674e81662c644b64550d2e8f74e0, type: 3}
|
||||
m_FontSize: 16
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 3
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "\u53D1\u884C\u65E5\u671F\uFF1A2026-66-66"
|
||||
--- !u!1 &2704985786795051223
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 67586661102091782}
|
||||
- component: {fileID: 4297944811495197019}
|
||||
- component: {fileID: 6447530100594578448}
|
||||
m_Layer: 5
|
||||
m_Name: Image
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &67586661102091782
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2704985786795051223}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5010078828579475845}
|
||||
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: -131.06, y: 2}
|
||||
m_SizeDelta: {x: 80, y: 80}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4297944811495197019
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2704985786795051223}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &6447530100594578448
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2704985786795051223}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!1 &3483744570565719852
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5010078828579475845}
|
||||
- component: {fileID: 2268568006775696577}
|
||||
- component: {fileID: 5644906588518313876}
|
||||
- component: {fileID: 2110413507685129963}
|
||||
- component: {fileID: 3083670225148312207}
|
||||
m_Layer: 5
|
||||
m_Name: dlcButton
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5010078828579475845
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3483744570565719852}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 67586661102091782}
|
||||
- {fileID: 3510870173842254657}
|
||||
- {fileID: 570804039580569020}
|
||||
- {fileID: 333634122881333044}
|
||||
- {fileID: 3306384613169609027}
|
||||
m_Father: {fileID: 0}
|
||||
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: 0, y: 0}
|
||||
m_SizeDelta: {x: 365, y: 102}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2268568006775696577
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3483744570565719852}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &5644906588518313876
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3483744570565719852}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: e2c536559de04a84bae8d1e1752633e7, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!114 &2110413507685129963
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3483744570565719852}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_SelectedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 5644906588518313876}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!114 &3083670225148312207
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3483744570565719852}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4eb65466412e86745aaacba1f78c5d12, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
dlc_profileImgae: {fileID: 6447530100594578448}
|
||||
dlcName: {fileID: 188579407499591497}
|
||||
dlcID: {fileID: 115205934777297662}
|
||||
dlcProducer: {fileID: 2931296379136689410}
|
||||
dlcPubliushDate: {fileID: 3713972282091736206}
|
||||
dlcDescription: {fileID: 0}
|
||||
dlcContent:
|
||||
- {fileID: 0}
|
||||
editorSearchFolder: Assets/Resources/dlc_dlcIndex
|
||||
runtimeResourcesFolder: Resources/dlc_dlcIndex
|
||||
--- !u!1 &6759998237426852132
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3510870173842254657}
|
||||
- component: {fileID: 277590058443354865}
|
||||
- component: {fileID: 188579407499591497}
|
||||
m_Layer: 5
|
||||
m_Name: dlcName
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3510870173842254657
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6759998237426852132}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5010078828579475845}
|
||||
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: 25.636463, y: 20.334257}
|
||||
m_SizeDelta: {x: 197.413, y: 30}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &277590058443354865
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6759998237426852132}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &188579407499591497
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6759998237426852132}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 12800000, guid: cc180dff846d13a4d88ddaed6f77e5cd, type: 3}
|
||||
m_FontSize: 24
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 2
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 3
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: dlcNameHere
|
||||
--- !u!1 &8646457970808721701
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3306384613169609027}
|
||||
- component: {fileID: 2498827089920741302}
|
||||
- component: {fileID: 115205934777297662}
|
||||
m_Layer: 5
|
||||
m_Name: dlcID
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3306384613169609027
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8646457970808721701}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5010078828579475845}
|
||||
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: 98.09924, y: -37.3367}
|
||||
m_SizeDelta: {x: 160, y: 16}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2498827089920741302
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8646457970808721701}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &115205934777297662
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8646457970808721701}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 12800000, guid: 775c674e81662c644b64550d2e8f74e0, type: 3}
|
||||
m_FontSize: 14
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 8
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: id
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e88e76e4b60a0314babf04294d5b53cb
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -26,9 +26,11 @@ public class SongDataSerializable
|
||||
public bool _if_level_is_EASE;
|
||||
public int max_comboRecord;
|
||||
|
||||
public int personalRecord; // 存储全局最高分
|
||||
public int personalRecord; // 存储总最高分 (个人分 + 偶像分)
|
||||
public Dictionary<int, int> difficultyNumberMap = new Dictionary<int, int>();
|
||||
public Dictionary<int, int> personalRecordMap = new Dictionary<int, int>();
|
||||
public Dictionary<int, int> idolRecordMap = new Dictionary<int, int>();
|
||||
public Dictionary<int, int> chartScoreMap = new Dictionary<int, int>();
|
||||
public Dictionary<int, string> chartFileMap = new Dictionary<int, string>();
|
||||
|
||||
public SongDataSerializable(SongData songData)
|
||||
@@ -56,7 +58,9 @@ public class SongDataSerializable
|
||||
|
||||
difficultyNumberMap = songData.difficultyNumberMap;
|
||||
personalRecordMap = songData.personalRecordMap;
|
||||
personalRecord = songData.personalRecord; // 存储全局最高分
|
||||
idolRecordMap = songData.idolRecordMap;
|
||||
chartScoreMap = songData.chartScoreMap;
|
||||
personalRecord = songData.personalRecord; // 存储综合最高分
|
||||
|
||||
chartFileMap = new Dictionary<int, string>();
|
||||
/*foreach (var kvp in songData.chartFileMap)
|
||||
@@ -91,7 +95,9 @@ public class SongDataSerializable
|
||||
|
||||
songData.difficultyNumberMap = difficultyNumberMap;
|
||||
songData.personalRecordMap = personalRecordMap;
|
||||
songData.personalRecord = personalRecord; // 赋值全局最高分
|
||||
songData.idolRecordMap = idolRecordMap;
|
||||
songData.chartScoreMap = chartScoreMap;
|
||||
songData.personalRecord = personalRecord; // 赋值综合最高分
|
||||
|
||||
foreach (var kvp in chartFileMap)
|
||||
{
|
||||
|
||||
@@ -20,8 +20,12 @@ public class SongDetailsUI : MonoBehaviour
|
||||
public Text songSerialNumberText;
|
||||
public Text personalRecordText;
|
||||
|
||||
// 新增:显示谱面(个人)分的文本
|
||||
public Text chartScoreText;
|
||||
|
||||
public Text thisSong_progressText;
|
||||
public Text thisSong_lastScoreText;
|
||||
public Text thisSong_lastScoreText; // will show last run total score if available
|
||||
public Text idolRecordText;
|
||||
//public Image songImage;
|
||||
|
||||
public int id_of_thisSong;
|
||||
@@ -122,13 +126,54 @@ public class SongDetailsUI : MonoBehaviour
|
||||
{
|
||||
difficultyText.text = entry.difficultyLEVEL.ToString();
|
||||
difficultyDesciptionText.text = entry.difficultyDescription;
|
||||
personalRecordText.text = entry.personalRecordForThisDifficulty.ToString();
|
||||
|
||||
// read values from SongData (SO)
|
||||
int chartPersonal = currentSong.GetPersonalRecord(difficulty); // 谱面个人分
|
||||
int idol = currentSong.GetIdolRecord(difficulty); // 偶像分
|
||||
|
||||
// Determine total: prefer stored total if present (>0), otherwise compute chartPersonal + idol
|
||||
int total;
|
||||
if (entry.totalPersonalRecordForThisDifficulty > 0)
|
||||
{
|
||||
total = entry.totalPersonalRecordForThisDifficulty;
|
||||
}
|
||||
else
|
||||
{
|
||||
total = chartPersonal + idol;
|
||||
}
|
||||
|
||||
// show total (personalRecord) and idol separately
|
||||
personalRecordText.text = total.ToString();
|
||||
if (idolRecordText != null)
|
||||
idolRecordText.text = idol.ToString();
|
||||
|
||||
// show chart personal (谱面分) if UI text provided
|
||||
if (chartScoreText != null)
|
||||
chartScoreText.text = chartPersonal.ToString();
|
||||
|
||||
// show last run total score if UI text provided
|
||||
if (thisSong_lastScoreText != null)
|
||||
{
|
||||
int lastRun = currentSong.GetChartScore(difficulty);
|
||||
thisSong_lastScoreText.text = lastRun.ToString();
|
||||
}
|
||||
|
||||
// also keep per-entry convenience fields in sync for inspector visibility
|
||||
entry.chartPersonalRecordForThisDifficulty = chartPersonal;
|
||||
entry.idolPersonalRecordForThisDifficulty = idol;
|
||||
entry.totalPersonalRecordForThisDifficulty = total;
|
||||
}
|
||||
else
|
||||
{
|
||||
difficultyText.text = difficulty.ToString();
|
||||
difficultyDesciptionText.text = "";
|
||||
personalRecordText.text = "0";
|
||||
if (idolRecordText != null)
|
||||
idolRecordText.text = "0";
|
||||
if (chartScoreText != null)
|
||||
chartScoreText.text = "0";
|
||||
if (thisSong_lastScoreText != null)
|
||||
thisSong_lastScoreText.text = "0";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4989cf41c3a3ee4c99f4197fe9e10d3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,265 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
public class dlcButton : MonoBehaviour
|
||||
{
|
||||
[Header("基本套件")]
|
||||
public Image dlc_profileImgae;
|
||||
public Text dlcName;
|
||||
public Text dlcID;
|
||||
public Text dlcProducer;
|
||||
public Text dlcPubliushDate;
|
||||
[Header("介绍")]
|
||||
public Text dlcDescription;
|
||||
|
||||
[Header("DLC SO (可在 Inspector 指定)")]
|
||||
public dlcData dlcDataSO;
|
||||
|
||||
[Header("DLC 内容 (运行时会由脚本填充)")]
|
||||
public List<SongData> dlcContent = new List<SongData>();
|
||||
|
||||
[Header("搜索路径 (编辑器/运行时)")]
|
||||
public string editorSearchFolder = "Assets/Resources/dlc_dlcIndex";
|
||||
public string runtimeResourcesFolder = "Resources/dlc_dlcIndex";
|
||||
|
||||
private Button _btn;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_btn = GetComponent<Button>();
|
||||
if (_btn != null)
|
||||
{
|
||||
_btn.onClick.RemoveAllListeners();
|
||||
_btn.onClick.AddListener(OnButtonClicked_ShowSongs);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve dlcData after all buttons have been instantiated
|
||||
public void ResolveDlcData()
|
||||
{
|
||||
Debug.Log($"dlcButton.ResolveDlcData called on '{gameObject.name}'");
|
||||
|
||||
if (dlcDataSO != null)
|
||||
{
|
||||
Debug.Log($"dlcButton: dlcDataSO already assigned on '{gameObject.name}' -> {dlcDataSO.name}");
|
||||
ApplyDlcData(dlcDataSO);
|
||||
return;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
if (dlcID != null && int.TryParse(dlcID.text, out id))
|
||||
{
|
||||
Debug.Log($"dlcButton: Resolving by dlcID text {id} for '{gameObject.name}'");
|
||||
LoadDlcDataById(id);
|
||||
return;
|
||||
}
|
||||
|
||||
string goName = gameObject.name;
|
||||
if (!string.IsNullOrEmpty(goName))
|
||||
{
|
||||
var parts = goName.Split('_');
|
||||
int parsed = 0;
|
||||
if (parts.Length > 0 && int.TryParse(parts[0], out parsed))
|
||||
{
|
||||
Debug.Log($"dlcButton: Resolving by GameObject name prefix {parsed} for '{gameObject.name}'");
|
||||
LoadDlcDataById(parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"dlcButton.ResolveDlcData: could not parse id from GameObject name '{goName}'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"dlcButton.ResolveDlcData: no dlcID text and no name to parse for '{gameObject.name}'");
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
// Do not auto-resolve here anymore. Resolution will be triggered externally after instantiation of all buttons.
|
||||
}
|
||||
|
||||
public void OnButtonClicked_ShowSongs()
|
||||
{
|
||||
var s = GameObject.FindObjectOfType<SongSelectUI>();
|
||||
if (s != null)
|
||||
{
|
||||
s.DisplaySongsFromList(dlcContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("dlcButton: SongSelectUI not found in scene to display songs");
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find a dlcData SO by id and apply its songList to dlcContent
|
||||
public void LoadDlcDataById(int id)
|
||||
{
|
||||
Debug.Log($"dlcButton.LoadDlcDataById: searching for id={id} (editorFolder='{editorSearchFolder}', runtimeFolder='{runtimeResourcesFolder}') on '{gameObject.name}'");
|
||||
#if UNITY_EDITOR
|
||||
// Editor search: search recursively for asset files under editorSearchFolder
|
||||
if (!string.IsNullOrEmpty(editorSearchFolder) && Directory.Exists(editorSearchFolder))
|
||||
{
|
||||
try
|
||||
{
|
||||
var files = Directory.GetFiles(editorSearchFolder, "*.asset", SearchOption.AllDirectories);
|
||||
Debug.Log($"dlcButton.LoadDlcDataById: found {files.Length} asset files under {editorSearchFolder}");
|
||||
foreach (var path in files)
|
||||
{
|
||||
string fileName = Path.GetFileNameWithoutExtension(path);
|
||||
if (fileName.StartsWith(id.ToString()))
|
||||
{
|
||||
string assetPath = path.Replace("\\", "/");
|
||||
Debug.Log($"dlcButton.LoadDlcDataById: candidate assetPath={assetPath}");
|
||||
var so = UnityEditor.AssetDatabase.LoadAssetAtPath<dlcData>(assetPath);
|
||||
if (so != null)
|
||||
{
|
||||
Debug.Log($"dlcButton.LoadDlcDataById: loaded dlcData SO '{so.name}' for id={id}");
|
||||
dlcDataSO = so;
|
||||
ApplyDlcData(so);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarning("dlcButton LoadDlcDataById (Editor) failed: " + e.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"dlcButton.LoadDlcDataById: editorSearchFolder '{editorSearchFolder}' does not exist or not set");
|
||||
}
|
||||
#endif
|
||||
// Runtime: search Resources (load all dlcData then filter by name prefix)
|
||||
try
|
||||
{
|
||||
var arr = Resources.LoadAll<dlcData>(runtimeResourcesFolder);
|
||||
Debug.Log($"dlcButton.LoadDlcDataById: Resources.LoadAll('{runtimeResourcesFolder}') returned {(arr != null ? arr.Length : 0)} items");
|
||||
if (arr != null)
|
||||
{
|
||||
foreach (var so in arr)
|
||||
{
|
||||
if (so == null) continue;
|
||||
if (so.name.StartsWith(id.ToString()))
|
||||
{
|
||||
Debug.Log($"dlcButton.LoadDlcDataById: found runtime dlcData '{so.name}' for id={id}");
|
||||
dlcDataSO = so;
|
||||
ApplyDlcData(so);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarning($"dlcButton.LoadDlcDataById: Resources search failed: {e.Message}");
|
||||
}
|
||||
|
||||
// fallback: search all Resources
|
||||
var all = Resources.LoadAll<dlcData>("");
|
||||
Debug.Log("dlcButton.LoadDlcDataById: Resources.LoadAll(\"\") returned " + (all != null ? all.Length : 0) + " items");
|
||||
if (all != null)
|
||||
{
|
||||
foreach (var so in all)
|
||||
{
|
||||
if (so == null) continue;
|
||||
if (so.name.StartsWith(id.ToString()))
|
||||
{
|
||||
Debug.Log($"dlcButton.LoadDlcDataById: found fallback dlcData '{so.name}' for id={id}");
|
||||
dlcDataSO = so;
|
||||
ApplyDlcData(so);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if no dlcData found, keep dlcContent empty but attempt old behavior: search SongData by id prefix
|
||||
Debug.Log($"dlcButton.LoadDlcDataById: no dlcData found for id={id}, falling back to song prefix search");
|
||||
LoadContentBySongIdPrefix(id);
|
||||
}
|
||||
|
||||
// Populate dlcContent from dlcData SO and update UI texts/images
|
||||
private void ApplyDlcData(dlcData so)
|
||||
{
|
||||
if (so == null) return;
|
||||
dlcContent = new List<SongData>();
|
||||
if (so.songList != null)
|
||||
{
|
||||
foreach (var s in so.songList)
|
||||
if (s != null) dlcContent.Add(s);
|
||||
}
|
||||
|
||||
if (dlcName != null) dlcName.text = so.dlcName ?? dlcName.text;
|
||||
if (dlcProducer != null) dlcProducer.text = so.dlcProducer ?? dlcProducer.text;
|
||||
if (dlcDescription != null) dlcDescription.text = so.dlcDescription ?? dlcDescription.text;
|
||||
if (dlcPubliushDate != null) dlcPubliushDate.text = so.dlcPublishDate ?? dlcPubliushDate.text;
|
||||
if (dlc_profileImgae != null)
|
||||
{
|
||||
dlc_profileImgae.sprite = so.dlc_image;
|
||||
dlc_profileImgae.enabled = so.dlc_image != null;
|
||||
}
|
||||
|
||||
Debug.Log($"dlcButton.ApplyDlcData: applied dlcData '{so.name}' with {dlcContent.Count} songs to button '{gameObject.name}'");
|
||||
}
|
||||
|
||||
// Legacy: if no dlcData SO, search SongData assets by id prefix and fill dlcContent
|
||||
public void LoadContentBySongIdPrefix(int id)
|
||||
{
|
||||
dlcContent.Clear();
|
||||
#if UNITY_EDITOR
|
||||
if (!string.IsNullOrEmpty(editorSearchFolder) && Directory.Exists(editorSearchFolder))
|
||||
{
|
||||
try
|
||||
{
|
||||
var files = Directory.GetFiles(editorSearchFolder, "*.asset", SearchOption.AllDirectories);
|
||||
foreach (var path in files)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(path);
|
||||
if (fileName.StartsWith(id.ToString()))
|
||||
{
|
||||
var assetPath = path.Replace("\\", "/");
|
||||
var so = UnityEditor.AssetDatabase.LoadAssetAtPath<SongData>(assetPath);
|
||||
if (so != null) dlcContent.Add(so);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarning("dlcButton LoadContentBySongIdPrefix (Editor) failed: " + e.Message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!string.IsNullOrEmpty(runtimeResourcesFolder))
|
||||
{
|
||||
var arr = Resources.LoadAll<SongData>(runtimeResourcesFolder);
|
||||
if (arr != null)
|
||||
{
|
||||
foreach (var so in arr)
|
||||
{
|
||||
if (so == null) continue;
|
||||
if (so.name.StartsWith(id.ToString())) dlcContent.Add(so);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dlcContent.Count == 0)
|
||||
{
|
||||
var arr2 = Resources.LoadAll<SongData>("");
|
||||
if (arr2 != null)
|
||||
{
|
||||
foreach (var so in arr2)
|
||||
{
|
||||
if (so == null) continue;
|
||||
if (so.name.StartsWith(id.ToString())) dlcContent.Add(so);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"dlcButton: Loaded {dlcContent.Count} SongData entries for DLC id={id} (fallback search)");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4eb65466412e86745aaacba1f78c5d12
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[CreateAssetMenu(fileName = "NewDLCData", menuName = "EaseOut/dlcData")]
|
||||
public class dlcData : ScriptableObject
|
||||
{
|
||||
[Header("DLC之图")]
|
||||
public Sprite dlc_image;
|
||||
|
||||
[Header("DLC之ID")]
|
||||
public int dlcID;
|
||||
|
||||
[Header("DLC名称")]
|
||||
public string dlcName;
|
||||
|
||||
[Header("DLC出品人")]
|
||||
public string dlcProducer;
|
||||
|
||||
[Header("DLC是否已解锁")]
|
||||
public bool dlcIsUnlocked;
|
||||
|
||||
[Header("DLC简介")]
|
||||
[TextArea(3,10)]
|
||||
public string dlcDescription;
|
||||
|
||||
[Header("DLC发行日期 yyyy-mm-dd")]
|
||||
public string dlcPublishDate;
|
||||
|
||||
[Header("DLC所含曲目(ScriptableObjects)")]
|
||||
public List<SongData> songList = new List<SongData>();
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e2d53881abb9314b97975546108ee61
|
||||
@@ -0,0 +1,117 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class loadDlcListPrefab : MonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Column
|
||||
{
|
||||
public string columnName;
|
||||
public List<dlcData> dlcList = new List<dlcData>();
|
||||
}
|
||||
|
||||
[Header("À¸Ä¿Áбí")]
|
||||
public List<Column> columns = new List<Column>();
|
||||
|
||||
[Header("UI Ô¤ÖÆÌå")]
|
||||
public GameObject dlc_scContent;
|
||||
public GameObject columnPrefab;
|
||||
public GameObject dlcButtonPrefab;
|
||||
|
||||
void Start()
|
||||
{
|
||||
RefreshUI();
|
||||
}
|
||||
|
||||
public void RefreshUI()
|
||||
{
|
||||
if (dlc_scContent == null) return;
|
||||
|
||||
for (int i = dlc_scContent.transform.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
var c = dlc_scContent.transform.GetChild(i).gameObject;
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying) DestroyImmediate(c);
|
||||
else Destroy(c);
|
||||
#else
|
||||
Destroy(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (columns == null) return;
|
||||
|
||||
for (int colIndex = 0; colIndex < columns.Count; colIndex++)
|
||||
{
|
||||
var col = columns[colIndex];
|
||||
|
||||
if (columnPrefab != null)
|
||||
{
|
||||
var headerGO = Instantiate(columnPrefab, dlc_scContent.transform);
|
||||
headerGO.name = "Column_" + colIndex;
|
||||
|
||||
var card = headerGO.GetComponent<columnCardPrefab>();
|
||||
if (card != null && card.columnNameText != null)
|
||||
{
|
||||
card.columnNameText.text = col.columnName ?? "(Unnamed)";
|
||||
}
|
||||
else
|
||||
{
|
||||
var txt = headerGO.transform.Find("ColumnNameText")?.GetComponent<Text>();
|
||||
if (txt != null) txt.text = col.columnName ?? "(Unnamed)";
|
||||
}
|
||||
}
|
||||
|
||||
if (col.dlcList == null) continue;
|
||||
|
||||
for (int entryIndex = 0; entryIndex < col.dlcList.Count; entryIndex++)
|
||||
{
|
||||
var dlc = col.dlcList[entryIndex];
|
||||
if (dlcButtonPrefab == null)
|
||||
{
|
||||
Debug.LogWarning("dlcButtonPrefab is not assigned");
|
||||
break;
|
||||
}
|
||||
|
||||
var itemGO = Instantiate(dlcButtonPrefab, dlc_scContent.transform);
|
||||
itemGO.name = $"DLC_Col{colIndex}_Item{entryIndex}";
|
||||
|
||||
var btn = itemGO.GetComponent<dlcButton>();
|
||||
if (btn != null)
|
||||
{
|
||||
if (dlc != null)
|
||||
{
|
||||
if (btn.dlc_profileImgae != null)
|
||||
{
|
||||
btn.dlc_profileImgae.sprite = dlc.dlc_image;
|
||||
btn.dlc_profileImgae.enabled = dlc.dlc_image != null;
|
||||
}
|
||||
if (btn.dlcName != null) btn.dlcName.text = dlc.dlcName ?? "(Unnamed)";
|
||||
if (btn.dlcID != null) btn.dlcID.text = dlc.dlcID.ToString();
|
||||
if (btn.dlcProducer != null) btn.dlcProducer.text = dlc.dlcProducer ?? "";
|
||||
if (btn.dlcPubliushDate != null) btn.dlcPubliushDate.text = dlc.dlcPublishDate ?? "";
|
||||
if (btn.dlcDescription != null) btn.dlcDescription.text = dlc.dlcDescription ?? "";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (btn.dlcName != null) btn.dlcName.text = "(None)";
|
||||
if (btn.dlcID != null) btn.dlcID.text = "";
|
||||
if (btn.dlc_profileImgae != null) btn.dlc_profileImgae.enabled = false;
|
||||
if (btn.dlcDescription != null) btn.dlcDescription.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var rt = dlc_scContent.GetComponent<RectTransform>();
|
||||
if (rt != null) UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(rt);
|
||||
|
||||
// After all buttons are instantiated, have each dlcButton resolve its dlcData (deferred lookup)
|
||||
var allButtons = dlc_scContent.GetComponentsInChildren<dlcButton>(true);
|
||||
foreach (var b in allButtons)
|
||||
{
|
||||
if (b != null)
|
||||
b.ResolveDlcData();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43304e66aae67444f8980df3fa43f9b8
|
||||
Reference in New Issue
Block a user