先上代码:
✅ 1. 自定义状态标识特性(Attribute)
[AttributeUsage(AttributeTargets.Class)] public class GameStateAttribute : Attribute {}
✅ 2. 状态切换上下文(用于传参)
public class StateSwitchCtx { // 可扩展,例如:public string fromScene; }
✅ 3. 状态接口与基类定义
public interface IState { void OnStateEnter(StateSwitchCtx inSwitchCtx); //状态进入状态栈 void OnStateLeave(); //状态退出状态栈 void OnStateOverride(); //状态由栈顶变成非栈顶 void OnStateResume(); //状态从非栈顶变成栈顶 string name { get; } } public abstract class BaseState : IState { public virtual void OnStateEnter(StateSwitchCtx inSwitchCtx) {} public virtual void OnStateLeave() {} public virtual void OnStateOverride() {} public virtual void OnStateResume() {} public virtual string name => GetType().Name; }
✅ 4. 核心状态机类(注册 + 切换 + 状态栈)
public class StateMachine { private Dictionary<string, IState> registeredStates = new Dictionary<string, IState>(); private Stack<IState> stateStack = new Stack<IState>(); public void RegisterStates<TAttribute>(Assembly assembly) where TAttribute : Attribute { var enumerator = new ClassEnumerator(typeof(TAttribute), typeof(IState), assembly); foreach (var type in enumerator.Results) { var instance = (IState)Activator.CreateInstance(type); if (!registeredStates.ContainsKey(instance.name)) { registeredStates[instance.name] = instance; } } } public void ChangeState(string name, StateSwitchCtx ctx = null) { if (stateStack.Count > 0) { var current = stateStack.Pop(); current.OnStateLeave(); } if (registeredStates.TryGetValue(name, out var newState)) { stateStack.Push(newState); newState.OnStateEnter(ctx); } } public IState TopState() => stateStack.Count > 0 ? stateStack.Peek() : null; }
✅ 5. 状态控制器封装类(对外接口)
public class GameStateCtr { private StateMachine stateMachine = new StateMachine(); public void Initialize() { // 默认加载当前程序集 stateMachine.RegisterStates<GameStateAttribute>(Assembly.GetExecutingAssembly()); } public void GotoState(string name, StateSwitchCtx ctx = null) { stateMachine.ChangeState(name, ctx); } public IState G