using System;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using IndianOceanAssets.Engine2_5D;
namespace GameFramework
{
///
/// 全局游戏状态管理器(持久化单例)。
/// 维护 GameState,提供 GameOver / Win 触发入口与对应事件。
///
public class GameManager : PersistentSingleton
{
/// 游戏结束(失败)时触发。
public static Action onGameOver;
/// 游戏胜利时触发。
public static Action onGameWin;
public static GameState GameState
{
get => Instance != null ? Instance.gameState : GameState.Playing;
set { if (Instance != null) Instance.gameState = value; }
}
[SerializeField] private GameState gameState = GameState.Playing;
[Header("过场动画 - 失败(光圈缩小)")]
[Tooltip("光源缩小的持续时间(秒)")]
[SerializeField] private float lightShrinkDuration = 2f;
[Tooltip("失败后黑色遮罩淡出持续时间(秒)")]
[SerializeField] private float lostFadeOutDuration = 1f;
[Header("过场动画 - 胜利(光源扩大 + 切场景)")]
[Tooltip("光源扩大的持续时间(秒)")]
[SerializeField] private float lightExpandDuration = 1.5f;
[Tooltip("光源扩大目标半径")]
[SerializeField] private float lightExpandTargetRadius = 20f;
[Tooltip("淡出持续时间(秒)")]
[SerializeField] private float fadeOutDuration = 1f;
/// 触发游戏失败:设状态 + 触发事件 + 播放过场动画。
public static void GameOver()
{
if (Instance == null) return;
GameState = GameState.GameOver;
onGameOver?.Invoke();
Instance.StartCoroutine(Instance.DeathTransition());
}
/// 触发游戏胜利:设状态 + 触发事件 + 播放过场动画。
public static void Win()
{
if (Instance == null) return;
GameState = GameState.Victory;
onGameWin?.Invoke();
Instance.StartCoroutine(Instance.VictoryTransition());
}
///
/// 失败过场协程:禁用控制 → 光源缩小至 0 → 淡出黑色 → 显示失败叠加层。
/// 不切换场景,留在 Gameplay。
///
private IEnumerator DeathTransition()
{
// 确保从暂停状态恢复(玩家可能在暂停时死亡)
Time.timeScale = 1f;
// 等待一帧,让 HUD 先更新血量显示
yield return null;
// 1. 禁用所有敌人 AI 和控制
DisableAllEnemyAI();
// 2. 查找玩家并禁用一切控制
var player = GameObject.FindGameObjectWithTag("Player");
if (player != null)
{
// 移动/翻滚/输入
var playerController = player.GetComponent();
if (playerController != null) playerController.enabled = false;
// 近战攻击(点击)
var swordAttack = player.GetComponent();
if (swordAttack != null) swordAttack.enabled = false;
// 远程攻击(点击)
var projectileShooter = player.GetComponent();
if (projectileShooter != null) projectileShooter.enabled = false;
// 技能:唤魂灯笼
var lanternSystem = player.GetComponent();
if (lanternSystem != null) lanternSystem.enabled = false;
// 相机跟随
var camFollow = Camera.main != null ? Camera.main.GetComponent() : null;
if (camFollow != null) camFollow.enabled = false;
// 3. 光源缩小至完全不可见
var lightSource = player.GetComponent();
if (lightSource != null)
{
float startRadius = lightSource.Radius;
float startIntensity = lightSource.Intensity;
float elapsed = 0f;
while (elapsed < lightShrinkDuration)
{
elapsed += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(elapsed / lightShrinkDuration);
float smoothT = t * t * (3f - 2f * t); // SmoothStep
lightSource.SetRadius(Mathf.Lerp(startRadius, 0.1f, smoothT));
lightSource.SetIntensity(Mathf.Lerp(startIntensity, 0f, smoothT));
yield return null;
}
lightSource.SetRadius(0.1f);
lightSource.SetIntensity(0f);
}
else
{
yield return new WaitForSecondsRealtime(lightShrinkDuration);
}
}
else
{
yield return new WaitForSecondsRealtime(lightShrinkDuration);
}
// 4. 淡出黑色 + 显示失败叠加层(不切场景)
yield return StartCoroutine(ShowLostOverlay());
}
///
/// 禁用场景中所有敌人相关的 AI 和控制组件。
///
private void DisableAllEnemyAI()
{
// 禁用所有 EnemyAI
var enemyAIs = FindObjectsOfType();
foreach (var ai in enemyAIs)
ai.enabled = false;
// 禁用 EnemyManager(停止生成/管理逻辑)
var enemyManager = FindObjectOfType();
if (enemyManager != null)
enemyManager.enabled = false;
Debug.Log($"[GameManager] 已禁用 {enemyAIs.Length} 个 EnemyAI + EnemyManager");
}
///
/// 胜利过场协程:光源扩大 → 淡出 → 跳转 Scoring。
///
private IEnumerator VictoryTransition()
{
// 胜利使用光源扩散 + 淡出 + 切场景(与失败不同)
yield return null;
var player = GameObject.FindGameObjectWithTag("Player");
if (player != null)
{
var playerController = player.GetComponent();
if (playerController != null) playerController.enabled = false;
var camFollow = Camera.main != null ? Camera.main.GetComponent() : null;
if (camFollow != null) camFollow.enabled = false;
var lightSource = player.GetComponent();
if (lightSource != null)
{
float startRadius = lightSource.Radius;
float elapsed = 0f;
while (elapsed < lightExpandDuration)
{
elapsed += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(elapsed / lightExpandDuration);
float smoothT = t * t * (3f - 2f * t);
lightSource.SetRadius(Mathf.Lerp(startRadius, lightExpandTargetRadius, smoothT));
yield return null;
}
lightSource.SetRadius(lightExpandTargetRadius);
}
else
{
yield return new WaitForSecondsRealtime(lightExpandDuration);
}
}
else
{
yield return new WaitForSecondsRealtime(lightExpandDuration);
}
yield return StartCoroutine(FadeOutAndLoad());
}
///
/// 失败叠加层:淡入黑色 → 显示"你已迷失"UI → 黑色稍微淡出露出暗黑场景。
/// 不切换场景,留在 Gameplay。
///
private IEnumerator ShowLostOverlay()
{
// 创建全屏黑色遮罩
var canvasObj = new GameObject("FadeOverlay");
var canvas = canvasObj.AddComponent