Files
bansonic_beta_main/Assets/songsDatabase/SongDataController/SongButton.cs
T

391 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections;
using DG.Tweening;
public class SongButton : MonoBehaviour
{
[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 highestScoreDifficultyText;
public Text difficultyIDText;
public Text songIDText;
public Image buttonImage;
public Image scoreLevelImage;
[Header("头图")]
public Image profileImage;
public int song_songSerialID;
[Header("select mark")]
public Image selected_boarder;
public Image fade_image;
[Header("计数百分比")]
public float easePercent = 1f;
public float ssPercent = 0.95f;
public float sPercent = 0.9f;
public float aPercent = 0.8f;
public float bPercent = 0.7f;
public float cPercent = 0.6f;
public float dPercent = 0.5f;
public float ePercent = 0.4f;
public float fPercent = 0.3f;
[Header("阶段图")]
public Sprite easeSprite;
public Sprite ssSprite;
public Sprite sSprite;
public Sprite aSprite;
public Sprite bSprite;
public Sprite cSprite;
public Sprite dSprite;
public Sprite eSprite;
public Sprite fSprite;
public Sprite ufSprite;
[Header("Fade Image Settings")]
public float minAlpha = 0f;
public float maxAlpha = 1f;
public float blinkDuration = 0.5f;
private static SongButton currentSelected;
private Coroutine fadeCoroutine;
private Coroutine blinkCoroutine;
public void Start()
{
if (selected_boarder != null)
{
Color c = selected_boarder.color;
c.a = 0f;
selected_boarder.color = c;
}
if (fade_image != null)
{
Color c = fade_image.color;
c.a = 0f;
fade_image.color = c;
}
}
public void SetButtonData(string songName, int highestScore, int difficultyID, Sprite songSprite, int songID)
{
Debug.Log("SetButtonData 被调用, songID 参数: " + songID);
var sd = SongDataLibrary.Instance != null ? SongDataLibrary.Instance.GetSongDataByID(songID) : null;
if (sd != null)
{
if (songNameText != null) songNameText.text = sd.songName;
if (multiNameText != null)
multiNameText.text = "音乐:" + sd.artistName + " | 曲绘:" + sd.painter + " | 制谱:" + sd.level_creator;
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;
}
if (songOverallDescriptionText != null)
{
songOverallDescriptionText.text = string.IsNullOrEmpty(sd.thisLevel_overallDescription) ? "暂无歌曲简介。" : sd.thisLevel_overallDescription;
}
// Robust logic: compute best total across chartFiles if present
int bestTotal = -1;
int bestDiff = -1;
if (sd.chartFiles != null && sd.chartFiles.Count > 0)
{
foreach (var entry in sd.chartFiles)
{
if (entry == null) continue;
int total = 0;
// prefer stored total if > 0
if (entry.totalPersonalRecordForThisDifficulty > 0)
{
total = entry.totalPersonalRecordForThisDifficulty;
}
else
{
// else compute from entry fields
int p = entry.chartPersonalRecordForThisDifficulty;
int i = entry.idolPersonalRecordForThisDifficulty;
total = p + i;
// as fallback also check SongData maps
if (total == 0 && sd.personalRecordMap != null)
{
int pm = sd.personalRecordMap.ContainsKey(entry.difficulty) ? sd.personalRecordMap[entry.difficulty] : 0;
int im = sd.idolRecordMap != null && sd.idolRecordMap.ContainsKey(entry.difficulty) ? sd.idolRecordMap[entry.difficulty] : 0;
total = pm + im;
}
}
if (bestDiff == -1 || total > bestTotal)
{
bestTotal = total;
bestDiff = entry.difficulty;
}
}
}
// If still not found, fallback to maps
if (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 (bestDiff == -1 || combined > bestTotal)
{
bestTotal = combined;
bestDiff = diff;
}
}
}
}
// final fallback
if (bestDiff == -1)
{
bestTotal = sd.personalRecord;
bestDiff = sd.thisLevel_selectedDifficultyID;
}
if (bestTotal < 0) bestTotal = 0;
if (highestScoreText != null) highestScoreText.text = bestTotal.ToString();
// Map difficulty index to label and set highestScoreDifficultyText as (Label)
if (highestScoreDifficultyText != null)
{
string label = "";
switch (bestDiff)
{
case 0: label = "(Easy)"; break;
case 1: label = "(Hard)"; break;
case 2: label = "(Incredible)"; break;
case 3: label = "(Impossible)"; break;
default: label = ""; break;
}
highestScoreDifficultyText.text = label;
}
// Assign scoreLevelImage based on thresholds relative to 2,000,000
if (scoreLevelImage != null)
{
Sprite chosenSprite = null;
float baseScore = 2000000f;
// Evaluate from top to bottom thresholds
if (bestTotal >= baseScore * easePercent && easeSprite != null)
chosenSprite = easeSprite;
else if (bestTotal >= baseScore * ssPercent && ssSprite != null)
chosenSprite = ssSprite;
else if (bestTotal >= baseScore * sPercent && sSprite != null)
chosenSprite = sSprite;
else if (bestTotal >= baseScore * aPercent && aSprite != null)
chosenSprite = aSprite;
else if (bestTotal >= baseScore * bPercent && bSprite != null)
chosenSprite = bSprite;
else if (bestTotal >= baseScore * cPercent && cSprite != null)
chosenSprite = cSprite;
else if (bestTotal >= baseScore * dPercent && dSprite != null)
chosenSprite = dSprite;
else if (bestTotal >= baseScore * ePercent && eSprite != null)
chosenSprite = eSprite;
else if (bestTotal >= baseScore * fPercent && fSprite != null)
chosenSprite = fSprite;
else if (ufSprite != null)
chosenSprite = ufSprite;
if (chosenSprite != null)
scoreLevelImage.sprite = chosenSprite;
}
// 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;
if (buttonImage != null) buttonImage.sprite = sd.backgroudPIC;
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
{
profileImage.enabled = false;
}
}
song_songSerialID = songID;
if (songIDText != null) songIDText.text = "数据库索引号:" + song_songSerialID.ToString();
}
else
{
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();
}
}
public void OnSongButtonClick()
{
Debug.Log("点击按钮的 song_songSerialID: " + song_songSerialID);
SongData selectedSong = SongDataLibrary.Instance.GetSongDataByID(song_songSerialID);
if (selectedSong != null)
{
if (currentSelected != null && currentSelected != this)
{
currentSelected.FadeOutSelectedBorder();
}
currentSelected = this;
FadeInSelectedBorder();
SongDataHolder.SelectedSongData = selectedSong;
var selectedInfo = FindObjectOfType<selected_songInfo>();
if (selectedInfo != null)
{
selectedInfo.UpdateSelectedSongDisplay();
}
// Save per-DLC selected song index to PlayerPrefs
string dlcKey = SongSelectUI.CurrentDlcKey;
if (string.IsNullOrEmpty(dlcKey)) dlcKey = "default_0";
string prefsKey = "song_selected_" + dlcKey;
int index = GetIndexAmongSongButtons();
PlayerPrefs.SetInt(prefsKey, index);
PlayerPrefs.Save();
Debug.Log($"SongButton: saved selected song index {index} for key {prefsKey}");
}
else
{
Debug.LogError("未找到对应的 SongData, songID: " + song_songSerialID);
}
}
private int GetIndexAmongSongButtons()
{
// Use parent traversal to find only SongButton siblings, to avoid mismatch when other UI children exist.
var parent = transform.parent;
if (parent == null) return 0;
int idx = 0;
for (int i = 0; i < parent.childCount; i++)
{
var child = parent.GetChild(i);
var sb = child != null ? child.GetComponent<SongButton>() : null;
if (sb == null) continue;
if (sb == this) return idx;
idx++;
}
return 0;
}
private void FadeInSelectedBorder()
{
if (selected_boarder != null)
{
if (fadeCoroutine != null) StopCoroutine(fadeCoroutine);
fadeCoroutine = StartCoroutine(FadeImage(selected_boarder, selected_boarder.color.a, 1f, 0.3f));
}
if (fade_image != null)
{
if (blinkCoroutine != null) StopCoroutine(blinkCoroutine);
blinkCoroutine = StartCoroutine(BlinkFadeImage());
}
}
private void FadeOutSelectedBorder()
{
if (selected_boarder != null)
{
if (fadeCoroutine != null) StopCoroutine(fadeCoroutine);
fadeCoroutine = StartCoroutine(FadeImage(selected_boarder, selected_boarder.color.a, 0f, 0.3f));
}
if (fade_image != null)
{
if (blinkCoroutine != null) StopCoroutine(blinkCoroutine);
fadeCoroutine = StartCoroutine(FadeImage(fade_image, fade_image.color.a, 0f, 0.3f));
}
}
private IEnumerator FadeImage(Image img, float startAlpha, float endAlpha, float duration)
{
if (img == null) yield break;
float time = 0f;
Color color = img.color;
while (time < duration)
{
time += Time.deltaTime;
float alpha = Mathf.Lerp(startAlpha, endAlpha, time / duration);
color.a = alpha;
img.color = color;
yield return null;
}
color.a = endAlpha;
img.color = color;
}
private IEnumerator BlinkFadeImage()
{
if (fade_image == null) yield break;
Color color = fade_image.color;
while (true)
{
float time = 0f;
while (time < blinkDuration / 2f)
{
time += Time.deltaTime;
float alpha = Mathf.Lerp(minAlpha, maxAlpha, time / (blinkDuration / 2f));
color.a = alpha;
fade_image.color = color;
yield return null;
}
time = 0f;
while (time < blinkDuration / 2f)
{
time += Time.deltaTime;
float alpha = Mathf.Lerp(maxAlpha, minAlpha, time / (blinkDuration / 2f));
color.a = alpha;
fade_image.color = color;
yield return null;
}
}
}
}