Files
zeling_v2/Assets/Scripts/Core/GameManager.cs
2026-05-08 11:04:00 +08:00

145 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
}
}
}