Files
gold_dolphin/unity/Assets/UI/ScoringUIController.cs
T

293 lines
10 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 System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace GameFramework
{
/// <summary>
/// 结算界面 UI 控制器 —— 支持胜利/失败双界面。
///
/// 胜利:显示"你做到了" + 魂灵数量 + 新记录标识(如有)
/// 失败:显示"你迷失了" + 去色底图
///
/// 通过 GameManager.GameState 判断胜负。
/// </summary>
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()
{
// 确保 Canvas 有 GraphicRaycaster(否则按钮无法响应点击)
var canvas = GetComponent<Canvas>();
if (canvas != null && GetComponent<GraphicRaycaster>() == null)
gameObject.AddComponent<GraphicRaycaster>();
// 判断胜负(GameManager 可能未初始化,默认视为失败)
_isWin = GameManager.Instance != null && 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();
}
}
/// <summary>
/// 显示胜利界面。
/// </summary>
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();
}
}
/// <summary>
/// 显示失败界面。
/// </summary>
void ShowLoseScreen()
{
SetPanelActive(winPanel, false);
SetPanelActive(losePanel, true);
// 设置"你迷失了"图片
if (loseTitleImage != null && loseTitleSprite != null)
loseTitleImage.sprite = loseTitleSprite;
// 失败也显示排行榜
ShowLeaderboard();
}
/// <summary>
/// 显示新纪录输入面板。
/// </summary>
void ShowNewHighScorePanel()
{
SetPanelActive(newHighScorePanel, true);
SetPanelActive(leaderboardPanel, false);
if (nameInputField != null)
{
nameInputField.text = "";
nameInputField.ActivateInputField();
}
}
/// <summary>
/// 显示排行榜。
/// </summary>
void ShowLeaderboard()
{
SetPanelActive(newHighScorePanel, false);
SetPanelActive(leaderboardPanel, true);
UpdateLeaderboardDisplay();
if (mainMenuButton != null)
mainMenuButton.Select();
}
/// <summary>
/// 更新排行榜显示。
/// </summary>
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<Text>();
return parent.GetComponent<Text>();
}
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
}
}