状态模式 是一种行为型设计模式,允许对象在内部状态改变时动态改变其行为,使对象的行为看起来像是改变了。该模式通过将状态逻辑拆分为独立类,消除复杂的条件分支语句,提升代码的可维护性和扩展性。
状态模式的核心价值在于解耦状态逻辑与上下文,为复杂状态管理提供结构化解决方案。在游戏开发中,它尤其适合管理角色控制、AI行为等动态状态流转场景,但需权衡类膨胀和性能成本。
优点:
- 消除复杂条件分支:消除大量if-else或switch语句,避免代码臃肿且难以维护,将每个分支独立为一个状态类,通过状态切换取代条件分支。
2.提高扩展性:新增状态无需修改上下文类,只需添加新的状态类即可。
3.职责单一化:每个状态类仅关注自身行为,符合单一职责原则。
4.状态转换显式管理:状态转换条件封装在状态类中,避免分散在代码各处。
5.提高可测试性:每个状态可单独测试,无需依赖其他逻辑。
缺点:
1.类数量增多 :每个状态对应一个类,可能导致类数量过多。(例如10个状态 → 10个类 + 接口 + 上下文类)
优化:
1.使用 层级状态机 合并相似状态(如 BaseMovementState 派生 Walk/Run)。
2.对简单状态使用 枚举 + 委托 简化实现。
2.Context数据共享 :状态类需访问上下文数据,可能导致过度暴露接口(如Player类需向状态类公开血量、位置等字段)。
优化:
1.将共享数据封装为 上下文接口,限制访问权限。
2.通过事件/委托通信,减少直接依赖。
3.性能开销 :频繁创建/销毁状态对象可能影响性能(如每帧切换状态)。
优化:
1.使用对象池复用状态实例。
说明例子:
1.UML类图:

2.实现:
1.定义State的抽象类:
cs
public abstract class State
{
protected Context m_Context = null;
public State(Context _context)
{
m_Context = _context;
}
public abstract void Handler(int value);
}
2.定义Context类:
cs
public class Context
{
State m_State = null;
public void Request(int value)
{
m_State.Handler(value);
}
public void SetState(State state)
{
Debug.Log("Context.SetState:" + state);
m_State = state;
}
}
3.定义具体状态类:ConcreteStateA、ConcreteStateB、ConcreteStateC
cs
public class ConcreteStateA : State
{
public ConcreteStateA(Context _context) : base(_context)
{
}
public override void Handler(int value)
{
Debug.Log("ConcreteStateA.Handler");
if (value > 10)
{
m_Context.SetState(new ConcreateStateB(m_Context));
}
}
}
public class ConcreateStateB : State
{
public ConcreateStateB(Context _context) : base(_context)
{
}
public override void Handler(int value)
{
Debug.Log("ConcreteStateB.Handler");
if (value > 20)
{
m_Context.SetState(new ConcreateStateC(m_Context));
}
}
}
public class ConcreateStateC : State
{
public ConcreateStateC(Context _context) : base(_context)
{
}
public override void Handler(int value)
{
Debug.Log("ConcreteStateC.Handler");
if (value > 30)
{
m_Context.SetState(new ConcreteStateA(m_Context));
}
}
}
4.测试类:
cs
public class StateParttern : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Context context = new Context();
context.SetState(new ConcreteStateA(context));
context.Request(5);
context.Request(15);
context.Request(25);
context.Request(35);
}
}
游戏中的使用场景:
1.角色行为管理 :玩家状态 --> 站立、移动、跳跃、攻击、死亡。
2.AI决策系统 :敌人AI --> 巡逻、追击、攻击、逃跑。
3.UI界面切换 :游戏菜单 --> 主界面、设置、背包、暂停。
4.场景切换 :游戏场景 --> 开始场景、大厅场景、战斗场景切换。
5.物理交互系统:物体状态 --> 静止、运动、碰撞、销毁。
参考书籍:
《Hands-On Game Development Patterns with Unity 2019》
《设计模式与游戏完美开发》