Files
gold_dolphin/unity/Assets/UI/ScoringUIController.cs
T
2026-06-30 09:46:59 +08:00

194 lines
6.6 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace GameFramework
{
/// <summary>
/// 排行榜场景 UI 控制器。
/// 如果当前得分能进入 Top-10,先显示输入名字面板;
/// 否则直接显示排行榜。
/// 修复了源项目 ScoringUIController 中 ShowScoringScreen() 被调用两次的 bug。
/// </summary>
public class ScoringUIController : MonoBehaviour
{
[Header("Panels")]
[SerializeField] GameObject leaderboardPanel;
[SerializeField] GameObject newHighScorePanel;
[Header("Leaderboard")]
[SerializeField] Transform leaderboardContainer; // 包含10个条目的父物体
[SerializeField] Text finalScoreText; // 显示当前局最终得分
[Header("New High Score")]
[SerializeField] InputField nameInputField;
[SerializeField] Button submitButton;
[SerializeField] Button cancelButton;
[Header("Navigation")]
[SerializeField] Button mainMenuButton;
[Header("Audio")]
[SerializeField] AudioData submitSFX;
[SerializeField] AudioData cancelSFX;
void Start()
{
// 绑定按钮
if (submitButton != null)
submitButton.onClick.AddListener(OnSubmitClick);
if (cancelButton != null)
cancelButton.onClick.AddListener(OnCancelClick);
if (mainMenuButton != null)
mainMenuButton.onClick.AddListener(OnMainMenuClick);
// 初始隐藏所有面板
if (leaderboardPanel != null)
leaderboardPanel.SetActive(false);
if (newHighScorePanel != null)
newHighScorePanel.SetActive(false);
// 显示当前最终得分
if (finalScoreText != null && ScoreManager.Instance != null)
finalScoreText.text = ScoreManager.Instance.CurrentScore.ToString();
// 判断是否进入排行榜
// 只调用一次——修复源项目的双重调用 bug
if (ScoreManager.Instance != null && ScoreManager.Instance.HasNewHighScore)
{
ShowNewHighScorePanel();
}
else
{
ShowLeaderboard();
}
}
/// <summary>
/// 显示新纪录输入面板。
/// </summary>
void ShowNewHighScorePanel()
{
if (newHighScorePanel != null)
newHighScorePanel.SetActive(true);
if (leaderboardPanel != null)
leaderboardPanel.SetActive(false);
// 自动选中输入框
if (nameInputField != null)
{
nameInputField.text = "";
nameInputField.ActivateInputField();
}
}
/// <summary>
/// 显示排行榜。
/// </summary>
void ShowLeaderboard()
{
if (newHighScorePanel != null)
newHighScorePanel.SetActive(false);
if (leaderboardPanel != null)
leaderboardPanel.SetActive(true);
UpdateLeaderboardDisplay();
// 选中主菜单按钮(键盘导航用)
if (mainMenuButton != null)
mainMenuButton.Select();
}
/// <summary>
/// 更新排行榜显示。
/// 遍历 leaderboardContainer 下的子物体,设置排名/得分/名字。
/// 每个条目子物体需要有三个 Text 组件,分别在 Rank/Score/Name 子物体上。
/// </summary>
void UpdateLeaderboardDisplay()
{
if (ScoreManager.Instance == null) return;
if (leaderboardContainer == null) return;
var data = ScoreManager.Instance.LoadPlayerScoreData();
int count = Mathf.Min(data.list.Count, leaderboardContainer.childCount);
for (int i = 0; i < leaderboardContainer.childCount; i++)
{
Transform entry = leaderboardContainer.GetChild(i);
bool hasData = i < data.list.Count;
// 查找条目下的三个 Text
Text rankText = FindTextByName(entry, "Rank");
Text scoreText = FindTextByName(entry, "Score");
Text nameText = FindTextByName(entry, "Name");
if (hasData)
{
var score = data.list[i];
if (rankText != null) rankText.text = $"{i + 1}.";
if (scoreText != null) scoreText.text = score.score.ToString();
if (nameText != null) nameText.text = score.playerName;
entry.gameObject.SetActive(true);
}
else
{
if (rankText != null) rankText.text = $"{i + 1}.";
if (scoreText != null) scoreText.text = "---";
if (nameText != null) nameText.text = "---";
entry.gameObject.SetActive(true);
}
}
}
/// <summary>
/// 在子物体中按名称查找 Text 组件。
/// </summary>
Text FindTextByName(Transform parent, string name)
{
Transform t = parent.Find(name);
if (t != null)
return t.GetComponent<Text>();
// 如果条目本身就是单个 Text(没有子结构),返回自身
return parent.GetComponent<Text>();
}
#region Button Handlers
void OnSubmitClick()
{
string playerName = "";
if (nameInputField != null)
playerName = nameInputField.text;
if (string.IsNullOrEmpty(playerName))
playerName = "Player";
if (ScoreManager.Instance != null)
ScoreManager.Instance.SavePlayerScore(playerName);
if (AudioManager.Instance != null && submitSFX != null)
AudioManager.Instance.PlaySFX(submitSFX);
ShowLeaderboard();
}
void OnCancelClick()
{
// 取消 = 用默认名保存后显示排行榜
if (ScoreManager.Instance != null)
ScoreManager.Instance.SavePlayerScore("Player");
if (AudioManager.Instance != null && cancelSFX != null)
AudioManager.Instance.PlaySFX(cancelSFX);
ShowLeaderboard();
}
void OnMainMenuClick()
{
if (SceneLoader.Instance != null)
SceneLoader.Instance.LoadMainMenuScene();
}
#endregion
}
}