This commit is contained in:
2026-07-07 03:34:56 +08:00
parent e7891d7e00
commit ecb20cf370
81 changed files with 2108 additions and 293 deletions
+25 -40
View File
@@ -2,6 +2,7 @@ using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using Architecture.Core;
namespace GameFramework
{
@@ -12,14 +13,12 @@ namespace GameFramework
/// 1. 在 Gameplay 场景里创建一个空物体,挂上本脚本
/// 2. 运行一次游戏(或点 Editor 按钮),脚本会自动构建子 UI
/// 3. 停止运行后,子 UI 留在场景中,可自由编辑样式/位置/精灵
/// 4. 运行时由 GameManager 调用 GameLostOverlay.Show() 激活
/// 4. 运行时订阅 OnGameOver 事件自激活(不再由 GameManager 直接调用)
///
/// 所有 UI 元素均为 [SerializeField],可在 Inspector 中替换。
/// </summary>
public class GameLostOverlay : MonoBehaviour
{
private static GameLostOverlay _instance;
// ====== Canvas ======
[Header("Canvas(留空则自动创建)")]
[SerializeField] private Canvas lostCanvas;
@@ -43,6 +42,9 @@ namespace GameFramework
[Header("音效")]
[SerializeField] private AudioData lostSFX;
[Header("SO 事件通道(替代 GameManager 直接调用 Show,订阅 OnGameOver 自激活)")]
[SerializeField] private GameEvent onGameOverEvent;
[Header("标题渐现动效")]
[Tooltip("标题渐现总时长(秒)")]
[SerializeField] private float titleFadeDuration = 1.5f;
@@ -54,6 +56,9 @@ namespace GameFramework
[SerializeField] private float rippleFrequency = 15f;
[Tooltip("水波纹材质(留空则自动从 Shader 创建)")]
[SerializeField] private Material rippleMaterial;
[Tooltip("水波纹着色器(留空则尝试 Shader.Find 兜底;建议拖入 Assets/UI/shaders/WaterRippleFade.shader 以避免构建裁剪导致运行时找不到)")]
[SerializeField] private Shader waterRippleShader;
[Tooltip("主界面按钮延迟出现时间(秒)")]
[SerializeField] private float buttonFadeDelay = 2f;
[Tooltip("按钮渐现时长(秒)")]
@@ -65,46 +70,11 @@ namespace GameFramework
private Material _rippleMaterial;
// ====================================================================
// 静态入口
// ====================================================================
/// <summary>
/// 显示失败叠加层。优先使用场景中已有的实例,
/// 没有则动态创建一个。
/// </summary>
public static void Show()
{
// 场景中已有(隐藏的)实例?
if (_instance != null)
{
_instance.Activate();
return;
}
// 尝试在场景中找到
var found = FindObjectOfType<GameLostOverlay>();
if (found != null)
{
_instance = found;
found.Activate();
return;
}
// 都没有 → 动态创建
var obj = new GameObject("GameLostOverlay");
var overlay = obj.AddComponent<GameLostOverlay>();
overlay.BuildAll();
overlay.Activate();
}
// ====================================================================
// 生命周期
// 生命周期(激活由 OnGameOver 事件驱动,见 OnEnable
// ====================================================================
void Awake()
{
_instance = this;
// 如果 Canvas 还没赋值,尝试从自身获取
if (lostCanvas == null)
lostCanvas = GetComponent<Canvas>();
@@ -114,6 +84,21 @@ namespace GameFramework
lostCanvas.enabled = false;
}
void OnEnable()
{
if (onGameOverEvent != null)
onGameOverEvent.Register(OnGameOver);
}
void OnDisable()
{
if (onGameOverEvent != null)
onGameOverEvent.Unregister(OnGameOver);
}
/// <summary>收到 OnGameOver 事件后激活失败叠加层(替代 GameManager 直接调用 Show)。</summary>
private void OnGameOver() => Activate();
void Update()
{
if (!_isVisible) return;
@@ -355,7 +340,7 @@ namespace GameFramework
}
else
{
var shader = Shader.Find("GameFramework/UI/WaterRippleFade");
var shader = waterRippleShader != null ? waterRippleShader : Shader.Find("GameFramework/UI/WaterRippleFade");
if (shader == null)
{
Debug.LogWarning("[GameLostOverlay] 找不到 WaterRippleFade Shader!请确认 Assets/UI/shaders/WaterRippleFade.shader 存在且无编译错误。回退到抖动动效。");