46 lines
1.6 KiB
C#
46 lines
1.6 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using BaseGames.Core.Events;
|
|
|
|
namespace BaseGames.Core
|
|
{
|
|
/// <summary>
|
|
/// 状态机核心,持有状态注册表与当前状态。
|
|
/// GameManager 持有一个实例;状态对象在 Awake 注入。
|
|
/// </summary>
|
|
public class GameStateMachine
|
|
{
|
|
private readonly Dictionary<GameStateId, IGameState> _states = new();
|
|
private IGameState _current;
|
|
|
|
public GameStateId CurrentStateId => _current?.Id ?? default;
|
|
|
|
/// <summary>注册状态实现(同 Id 注册多次以最后一次为准)。</summary>
|
|
public void Register(IGameState state) => _states[state.Id] = state;
|
|
|
|
/// <summary>转换到目标状态。失败时返回 false 并填充 error 字符串。</summary>
|
|
public bool TransitionTo(GameStateId nextId, out string error)
|
|
{
|
|
if (!_states.TryGetValue(nextId, out var next))
|
|
{
|
|
error = $"[GameStateMachine] 未知状态 '{nextId}'";
|
|
return false;
|
|
}
|
|
if (_current != null && !_current.ValidNextStates.Contains(nextId))
|
|
{
|
|
error = $"[GameStateMachine] 非法转换 {_current.Id} → {nextId}";
|
|
return false;
|
|
}
|
|
var prev = _current?.Id ?? default;
|
|
_current?.OnExit(nextId);
|
|
_current = next;
|
|
_current.OnEnter(prev);
|
|
error = null;
|
|
return true;
|
|
}
|
|
|
|
public void Tick(float deltaTime) => _current?.Tick(deltaTime);
|
|
}
|
|
}
|