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(); } } }