using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace GameFramework { /// /// 结算界面 UI 控制器 —— 支持胜利/失败双界面。 /// /// 胜利:显示"你做到了" + 魂灵数量 + 新记录标识(如有) /// 失败:显示"你迷失了" + 去色底图 /// /// 通过 GameManager.GameState 判断胜负。 /// public class ScoringUIController : MonoBehaviour { [Header("底图")] [SerializeField] private Image bgImage; [SerializeField] private Sprite bgSprite; // bg.png(胜利彩色/失败去色共用同一张) [Header("胜利面板")] [SerializeField] private GameObject winPanel; [SerializeField] private Image winTitleImage; // "你做到了" 图片 [SerializeField] private Sprite winTitleSprite; // nizuodaol.png [SerializeField] private Text soulCountText; // 魂灵数量 [SerializeField] private Image soulCountBgImage; // 魂灵数量底图 [SerializeField] private Sprite soulCountBgSprite; // bgpoint.png [SerializeField] private Image newRecordImage; // "新记录" 图片 [SerializeField] private Sprite newRecordSprite; // 新纪录.png [SerializeField] private Image scoreLabelImage; // "拯救魂灵" 图片 [SerializeField] private Sprite scoreLabelSprite; [Header("失败面板")] [SerializeField] private GameObject losePanel; [SerializeField] private Image loseTitleImage; // "你迷失了" 图片 [SerializeField] private Sprite loseTitleSprite; // nizuodaol.png 副本 [Header("排行榜")] [SerializeField] private GameObject leaderboardPanel; [SerializeField] private Transform leaderboardContainer; [SerializeField] private Text finalScoreText; [Header("新纪录输入")] [SerializeField] private GameObject newHighScorePanel; [SerializeField] private InputField nameInputField; [SerializeField] private Button submitButton; [SerializeField] private Button cancelButton; [Header("导航")] [SerializeField] private Button mainMenuButton; [SerializeField] private Image mainMenuButtonImage; // 主界面.png [SerializeField] private Sprite mainMenuBtnSprite; [Header("装饰")] [SerializeField] private Image lineImage; [SerializeField] private Sprite lineSprite; [SerializeField] private Image bgPointImage; [SerializeField] private Sprite bgPointSprite; [Header("Audio")] [SerializeField] private AudioData submitSFX; [SerializeField] private AudioData cancelSFX; private bool _isWin; void Start() { // 判断胜负 _isWin = (GameManager.GameState == GameState.Victory); // 绑定按钮 if (submitButton != null) submitButton.onClick.AddListener(OnSubmitClick); if (cancelButton != null) cancelButton.onClick.AddListener(OnCancelClick); if (mainMenuButton != null) mainMenuButton.onClick.AddListener(OnMainMenuClick); // 初始隐藏所有面板 SetPanelActive(winPanel, false); SetPanelActive(losePanel, false); SetPanelActive(leaderboardPanel, false); SetPanelActive(newHighScorePanel, false); // 设置底图(共用同一张,失败时去色) if (bgImage != null && bgSprite != null) { bgImage.sprite = bgSprite; bgImage.color = _isWin ? Color.white : new Color(0.4f, 0.4f, 0.45f, 1f); // 失败去色 } // 设置装饰图片 if (lineImage != null && lineSprite != null) lineImage.sprite = lineSprite; if (bgPointImage != null && bgPointSprite != null) bgPointImage.sprite = bgPointSprite; // 设置返回主界面按钮图片 if (mainMenuButtonImage != null && mainMenuBtnSprite != null) mainMenuButtonImage.sprite = mainMenuBtnSprite; if (_isWin) { ShowWinScreen(); } else { ShowLoseScreen(); } } /// /// 显示胜利界面。 /// void ShowWinScreen() { SetPanelActive(winPanel, true); SetPanelActive(losePanel, false); // 设置“你做到了”图片 if (winTitleImage != null && winTitleSprite != null) winTitleImage.sprite = winTitleSprite; // 设置魂灵数量底图 if (soulCountBgImage != null && soulCountBgSprite != null) soulCountBgImage.sprite = soulCountBgSprite; // 显示魂灵数量(复用 ScoreManager) int score = ScoreManager.Instance != null ? ScoreManager.Instance.CurrentScore : 0; if (soulCountText != null) soulCountText.text = score.ToString(); // 设置“拯救魂灵”图片 if (scoreLabelImage != null && scoreLabelSprite != null) scoreLabelImage.sprite = scoreLabelSprite; // 判断是否新纪录 bool isNewRecord = ScoreManager.Instance != null && ScoreManager.Instance.HasNewHighScore; if (newRecordImage != null) { newRecordImage.gameObject.SetActive(isNewRecord); if (isNewRecord && newRecordSprite != null) newRecordImage.sprite = newRecordSprite; } // 新纪录时显示输入面板,否则直接显示排行榜 if (isNewRecord) { ShowNewHighScorePanel(); } else { ShowLeaderboard(); } } /// /// 显示失败界面。 /// void ShowLoseScreen() { SetPanelActive(winPanel, false); SetPanelActive(losePanel, true); // 设置"你迷失了"图片 if (loseTitleImage != null && loseTitleSprite != null) loseTitleImage.sprite = loseTitleSprite; // 失败也显示排行榜 ShowLeaderboard(); } /// /// 显示新纪录输入面板。 /// void ShowNewHighScorePanel() { SetPanelActive(newHighScorePanel, true); SetPanelActive(leaderboardPanel, false); if (nameInputField != null) { nameInputField.text = ""; nameInputField.ActivateInputField(); } } /// /// 显示排行榜。 /// void ShowLeaderboard() { SetPanelActive(newHighScorePanel, false); SetPanelActive(leaderboardPanel, true); UpdateLeaderboardDisplay(); if (mainMenuButton != null) mainMenuButton.Select(); } /// /// 更新排行榜显示。 /// void UpdateLeaderboardDisplay() { if (ScoreManager.Instance == null || leaderboardContainer == null) return; var data = ScoreManager.Instance.LoadPlayerScoreData(); for (int i = 0; i < leaderboardContainer.childCount; i++) { Transform entry = leaderboardContainer.GetChild(i); bool hasData = i < data.list.Count; 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); } } } Text FindTextByName(Transform parent, string name) { Transform t = parent.Find(name); if (t != null) return t.GetComponent(); return parent.GetComponent(); } void SetPanelActive(GameObject panel, bool active) { if (panel != null) panel.SetActive(active); } #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 } }