145 lines
7.2 KiB
C#
145 lines
7.2 KiB
C#
using System.Collections;
|
||
using UnityEngine;
|
||
using BaseGames.Core.Events;
|
||
using BaseGames.Core.States;
|
||
|
||
namespace BaseGames.Core
|
||
{
|
||
/// <summary>
|
||
/// 全局游戏管理器。
|
||
/// 生命周期:Persistent → 第一个执行(DefaultExecutionOrder(-1000))。
|
||
/// 持有 <see cref="GameStateMachine"/> 并协调所有顶层服务。
|
||
/// </summary>
|
||
[DefaultExecutionOrder(-1000)]
|
||
public class GameManager : MonoBehaviour
|
||
{
|
||
// ── 单例 ──────────────────────────────────────────────────────────
|
||
public static GameManager Instance { get; private set; }
|
||
|
||
// ── Inspector 引用 ────────────────────────────────────────────────
|
||
[Header("Managers")]
|
||
[SerializeField] private SettingsManager _settingsManager;
|
||
[SerializeField] private DeathRespawnService _deathRespawnService;
|
||
[SerializeField] private SceneService _sceneService;
|
||
|
||
[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<GameStateId> _onGameStateChanged;
|
||
[SerializeField] private VoidEventChannelSO _onPlayerRespawned;
|
||
|
||
// ── 状态机 ────────────────────────────────────────────────────────
|
||
private readonly GameStateMachine _fsm = new GameStateMachine();
|
||
public GameStateId CurrentState => _fsm.CurrentStateId;
|
||
|
||
// ──────────────────────────────────────────────────────────────────
|
||
private void Awake()
|
||
{
|
||
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
|
||
Instance = this;
|
||
DontDestroyOnLoad(gameObject);
|
||
|
||
RegisterServices();
|
||
RegisterStates();
|
||
_settingsManager?.Initialize();
|
||
|
||
_fsm.TransitionTo(GameStates.Initializing, out _);
|
||
}
|
||
|
||
private void OnEnable()
|
||
{
|
||
if (_onPlayerDied) _onPlayerDied.OnEventRaised += HandlePlayerDied;
|
||
if (_onPauseRequested) _onPauseRequested.OnEventRaised += HandlePauseRequested;
|
||
if (_onResumeRequested) _onResumeRequested.OnEventRaised += HandleResumeRequested;
|
||
if (_onBossFightStarted) _onBossFightStarted.OnEventRaised += HandleBossFightStarted;
|
||
if (_onBossFightEnded) _onBossFightEnded.OnEventRaised += HandleBossFightEnded;
|
||
if (_onDeathScreenConfirmed) _onDeathScreenConfirmed.OnEventRaised += HandleDeathScreenConfirmed;
|
||
}
|
||
|
||
private void OnDisable()
|
||
{
|
||
if (_onPlayerDied) _onPlayerDied.OnEventRaised -= HandlePlayerDied;
|
||
if (_onPauseRequested) _onPauseRequested.OnEventRaised -= HandlePauseRequested;
|
||
if (_onResumeRequested) _onResumeRequested.OnEventRaised -= HandleResumeRequested;
|
||
if (_onBossFightStarted) _onBossFightStarted.OnEventRaised -= HandleBossFightStarted;
|
||
if (_onBossFightEnded) _onBossFightEnded.OnEventRaised -= HandleBossFightEnded;
|
||
if (_onDeathScreenConfirmed) _onDeathScreenConfirmed.OnEventRaised -= HandleDeathScreenConfirmed;
|
||
}
|
||
|
||
private void Update() => _fsm.Tick(Time.deltaTime);
|
||
|
||
// ── 初始化 ────────────────────────────────────────────────────────
|
||
private void RegisterServices()
|
||
{
|
||
if (_deathRespawnService)
|
||
ServiceLocator.Register<IDeathRespawnService>(_deathRespawnService);
|
||
if (_sceneService)
|
||
ServiceLocator.Register<ISceneService>(_sceneService);
|
||
}
|
||
|
||
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() => RequestTransition(GameStates.Paused);
|
||
private void HandleResumeRequested() => RequestTransition(GameStates.Gameplay);
|
||
|
||
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 void HandleDeathScreenConfirmed() => _deathScreenConfirmed = true;
|
||
|
||
private IEnumerator DeathFlow()
|
||
{
|
||
RequestTransition(GameStates.Dead);
|
||
var deathService = ServiceLocator.Get<IDeathRespawnService>();
|
||
yield return deathService.StartDeathSequenceCoroutine();
|
||
|
||
// 等待玩家在死亡画面点击重试
|
||
_deathScreenConfirmed = false;
|
||
yield return new WaitUntil(() => _deathScreenConfirmed);
|
||
|
||
yield return deathService.StartRespawnCoroutine();
|
||
RequestTransition(GameStates.LoadingScene);
|
||
_onPlayerRespawned?.Raise();
|
||
}
|
||
}
|
||
}
|