using System.Collections;
using UnityEngine;
using BaseGames.Core.Events;
using BaseGames.Core.States;
namespace BaseGames.Core
{
///
/// 全局游戏管理器。
/// 生命周期:Persistent → 第一个执行(DefaultExecutionOrder(-1000))。
/// 持有 并协调所有顶层服务。
///
[DefaultExecutionOrder(-1000)]
public class GameManager : MonoBehaviour
{
// ── Inspector 引用 ────────────────────────────────────────────────
[Header("Managers")]
[SerializeField] private SettingsManager _settingsManager;
[Header("Event Channels - Listen")]
[SerializeField] private VoidEventChannelSO _onPlayerDied;
[SerializeField] private VoidEventChannelSO _onPauseRequested;
[SerializeField] private VoidEventChannelSO _onResumeRequested;
[SerializeField] private StringEventChannelSO _onBossFightStarted;
[SerializeField] private BoolEventChannelSO _onBossFightEnded;
[SerializeField] private VoidEventChannelSO _onDeathScreenConfirmed;
[Header("Event Channels - Raise")]
[SerializeField] private BaseEventChannelSO _onGameStateChanged;
[SerializeField] private VoidEventChannelSO _onPlayerRespawned;
// ── 状态机 ────────────────────────────────────────────────────────
private readonly GameStateMachine _fsm = new GameStateMachine();
private readonly CompositeDisposable _subs = new();
public GameStateId CurrentState => _fsm.CurrentStateId;
private static GameManager _instance;
// ──────────────────────────────────────────────────────────────────
private void Awake()
{
if (_instance != null) { Destroy(gameObject); return; }
_instance = this;
DontDestroyOnLoad(transform.root.gameObject);
RegisterStates();
_settingsManager?.Initialize();
_fsm.TransitionTo(GameStates.Initializing, out _);
}
private void Start()
{
// 在 Start 广播初始状态,确保其他组件已在 OnEnable 中完成订阅。
_onGameStateChanged?.Raise(new Events.GameStateId(GameStates.Initializing.Id));
}
private void OnEnable()
{
_onPlayerDied? .Subscribe(HandlePlayerDied).AddTo(_subs);
_onPauseRequested? .Subscribe(HandlePauseRequested).AddTo(_subs);
_onResumeRequested? .Subscribe(HandleResumeRequested).AddTo(_subs);
_onBossFightStarted? .Subscribe(HandleBossFightStarted).AddTo(_subs);
_onBossFightEnded? .Subscribe(HandleBossFightEnded).AddTo(_subs);
_onDeathScreenConfirmed?.Subscribe(HandleDeathScreenConfirmed).AddTo(_subs);
}
private void OnDisable() => _subs.Clear();
private void OnDestroy()
{
if (_instance == this) _instance = null;
}
private void Update() => _fsm.Tick(Time.deltaTime);
// ── 初始化 ────────────────────────────────────────────────────────
private void RegisterStates()
{
_fsm.Register(new InitializingState());
_fsm.Register(new MainMenuState());
_fsm.Register(new LoadingSceneState());
_fsm.Register(new GameplayState());
_fsm.Register(new BossFightState());
_fsm.Register(new PausedState());
_fsm.Register(new DeadState());
_fsm.Register(new CutsceneState());
_fsm.Register(new GameOverState());
}
// ── 状态转换公共 API ──────────────────────────────────────────────
public bool RequestTransition(GameStateId nextState)
{
if (_fsm.TransitionTo(nextState, out string error))
{
// 通知 UI 等监听者(GameStateId in Core.Events 是 string-based)
_onGameStateChanged?.Raise(new Events.GameStateId(nextState.Id));
return true;
}
Debug.LogWarning($"[GameManager] {error}");
return false;
}
// ── 事件处理 ──────────────────────────────────────────────────────
private void HandlePlayerDied() => StartCoroutine(DeathFlow());
private void HandlePauseRequested()
{
_prePauseState = _fsm.CurrentStateId;
RequestTransition(GameStates.Paused);
}
private void HandleResumeRequested() => RequestTransition(_prePauseState);
private void HandleBossFightStarted(string bossId)
=> RequestTransition(GameStates.BossFight);
private void HandleBossFightEnded(bool victory)
{
if (victory) RequestTransition(GameStates.Gameplay);
else RequestTransition(GameStates.GameOver);
}
private bool _deathScreenConfirmed;
private GameStateId _prePauseState = GameStates.Gameplay;
private void HandleDeathScreenConfirmed() => _deathScreenConfirmed = true;
private IEnumerator DeathFlow()
{
RequestTransition(GameStates.Dead);
var deathService = ServiceLocator.Get();
// SteelSoul 模式:清档后返回主菜单(架构 19 §6)
var scaler = ServiceLocator.GetOrDefault()?.CurrentScaler;
if (scaler != null && scaler.InstantDeathOnZeroHP)
{
yield return deathService.StartGameOverCoroutine();
yield break;
}
yield return deathService.StartDeathSequenceCoroutine();
// 等待玩家在死亡画面点击重试
_deathScreenConfirmed = false;
yield return new WaitUntil(() => _deathScreenConfirmed);
yield return deathService.StartRespawnCoroutine();
RequestTransition(GameStates.LoadingScene);
_onPlayerRespawned?.Raise();
}
}
}