State Machines
November 17, 2021About 3 min
State Machines
AI角色在游戏中一般都是一直做一样的事情,直到收到某个信息才会改变角色现在做的事情。这我们就可以使用状态机来制作。
A Basic State Machine
在一个状态中每个角色都有一个状态变量。一个行为对应着一个状态,并且有一系列的条件。当满足状态切换条件时,这个叫做触发(trigger),当切换到一个新的状态时,这叫激活(fired)

上图展示了一个简单的状态机:巡逻,战斗,逃跑。每个状态都有自己的一些条件。
Finite State Machines
有限状态机就是一般状态机。
The Problem
我们想要一个支持具有任何类型转换条件的任意状态机的一般系统。状态机将符合上述结构,并且同一时刻只占据一种状态。
The Algorithm
为了实现这个,我们可以使用一个通用的状态接口,并且状态中用条件。一个状态机有着一些可能进入的状态和记录着当前的状态。
在每一帧我们就更新状态机,状态机去更新当前状态,从而检测是否切换状态。
Pseudo-code
这里我们一帧去检测当前状态是已经被切换了,并且调用特定的切换的方法。
class StateMachine:
# We’re in one state at a time.
initialState: State
currentState: State = initialState
targetState: State
# transfrom to next state
function transitionTo(state)
targetState = state
# Checks and applies transitions, returning current state actions.
function update()
currentState.update()
if targetState ! = null then
executeStateTransition()
# execute transition
function executeStateTransition()
currentState.exit()
currentState = targetState
currentState.OnTransitionTo = transitionTo
currentState.entry()
Data Structures and Interfaces
状态的接口:
class IState:
Action<IState> OnTransitionTo
function entry()
# do state actions
function update()
function exit()
Weaknesses
有限状态机在角色行为简单时非常实用,但随着需求增长会暴露出明显缺陷:
- 状态爆炸(State Explosion):每增加一种状态,潜在的转换边数以平方级增长(
)。当状态数量较多时,维护所有转换条件变得极为困难。 - 可扩展性差:新增一个行为往往需要在已有的多个状态中分别添加新的转换,改动分散、容易遗漏。
- 逻辑复用困难:相似的行为逻辑(如"低血量时退出战斗")无法在多个状态间共享,只能重复定义。
- 缺乏并发支持:基础 FSM 同一时刻只有一个活跃状态,难以表达"同时巡逻并保持警惕"这类并发行为,需要手工组合状态才能模拟。
- 可读性下降:状态与转换数量增多后,状态图变得难以阅读和调试,行为逻辑不再直观。
常见改进方案:
- 层次状态机(HFSM):将状态组织为父子层级,子状态可继承父状态的转换,减少重复定义,缓解状态爆炸问题。
- 行为树(Behavior Tree):以树形组合行为节点,天然支持顺序、选择、并行等复合行为,可读性和可复用性更强,是现代游戏 AI 的主流方案之一。