GOAP:目标导向行为规划
GOAP:目标导向行为规划
GOAP(Goal-Oriented Action Planning,目标导向行为规划)是一种让 NPC 自己「想办法」达成目标的决策技术。行为树把决策路径提前写死,GOAP 反过来:你只描述角色想要什么(Goal)和能做什么(Action),至于先做哪一步、再做哪一步,交给规划器(Planner)在运行时算出来。
这套思路并不新,源头是 1970 年代的自动规划(STRIPS)。真正让它在游戏圈出名的是 2005 年的《极度恐慌》(F.E.A.R.)——敌兵会绕后、找掩体、喊队友合围,很大程度上就是 GOAP 规划出来的。更早在 2003 年的《杀出重围:隐形战争》里就试过一次,但那一代的 AI 因为行为不一致、战术偏简单、算力吃紧挨了不少批评。这段历史其实提前把 GOAP 的代价摆到了台面上:规划是要花 CPU 的,用之前得想清楚值不值。
核心概念
GOAP 的世界由几个部件拼起来:
- WorldState:世界状态集合,描述 AI 当前认知里的世界。通常拆成一组布尔量——「看得到玩家吗」「手里有武器吗」「在掩体后面吗」。
- Goal:目标。每个目标带一个 GoalState(想要到达的世界状态)和优先级。
- Action:具体动作。每个动作有 Precondition(执行前提)和 Effect(执行后对世界状态的改变),还带一个 Cost。
- GoalSet / ActionSet:分别管理目标和动作的集合。GoalSet 负责按优先级和当前 WorldState 挑出一个可行的 Goal;ActionSet 为规划器提供候选动作。
- Planner:规划器,根据选中的 Goal 算出一串能到达 GoalState 的动作序列(Plan)。普遍做法是用 A*。
- Agent:AI 实例,持有并管理上面这些对象。
用类图表示它们的关系:
规划的本质:反向图搜索
一个 Plan 就是从「当前世界状态」走到「目标世界状态」的一条路径。把每个世界状态看成图上的节点,每个 Action 看成一条带 Cost 的边,规划就退化成了图上的最短路——所以用 A* 很自然。
关键在于方向:GOAP 通常是从目标反向往回搜。先找哪个 Action 的 Effect 能满足 GoalState,再看这个 Action 的 Precondition 需要什么,把「满足这个 Precondition」当成新的子目标继续往回找,直到某个 Action 的 Precondition 为空(可以直接执行),这条链就接通了。
举个具体例子。假设目标是「拥有一间房子」,动作库里有 A~E 五个动作:
- 只有 E 的 Effect 是「拥有房子」,正好满足目标 → 当前 Plan:
E - E 的 Precondition 能由 B 和 D 满足,且 B 的 Cost 比 D 小,排在前面 →
D → B → E - B、D 的 Precondition 能由 A 和 C 满足 →
A → C → D → B → E - A、C 的 Precondition 为空,作为起点,链条接通 → 最终 Plan:
A → C → D → B → E
这里有个容易忽略的不对称:Precondition 和 Effect 在匹配时逻辑不一样。Precondition 要求完全匹配(传入的 WorldState 必须和 Precondition 一致才算通过),而 Effect 用交集匹配(WorldState 与 Effect 的交集吻合即可)。原因就在于反向 A*——只要一个 Action 的 Effect 是当前目标的子集,就有资格成为路径上的一环。这个细节在自己实现规划器时是必踩的坑,具体到代码层面我在 UE 中实现 GOAP 里展开。
GOAP 对比行为树
| 维度 | 行为树(Behavior Tree) | GOAP |
|---|---|---|
| 决策方式 | 预定义的节点结构,逻辑路径固定 | 运行时动态生成行动序列 |
| 可读性 | 结构直观,好理解好调试 | 行为在运行时才产生,难追踪 |
| 应对变化 | 静态,容易显得机械、可预测 | 动态适应环境,行为不易被玩家预测 |
| 扩展性 | AI 一复杂,树会膨胀到难以维护 | 加一个 Action 不动其他逻辑,横向扩展好 |
| 性能 | 遍历成本低 | 每次规划都要跑一次搜索,成本高 |
| 实现复杂度 | 低 | 高 |
我的经验是:这不是「谁更先进」的问题,而是需求匹配的问题。AI 行为相对简单、或者开发时间紧,行为树更省心。GOAP 划得来的场景很具体:AI 要能对环境变化做出真实反馈,行为还不能让玩家几局就摸透套路——这种复杂度用行为树硬写会很快失控。
一个典型的适用场景是沉浸式潜行:AI 听到声音要去调查,发现同伴尸体会呼叫增援一起搜人,会找掩体、会协同作战。这类「每种情况都要有合理反应」的需求,用行为树硬写会爆炸,用 GOAP 描述成「目标 + 动作 + 前提/效果」反而清爽——代价就是那份规划开销,得靠工程手段压下去(限制参与规划的动作数量、对象池等,同样见实现篇)。
延伸阅读
- Jeff Orkin, Goal-Oriented Action Planning(F.E.A.R. 作者的资料主页,GOAP 入门必读)
- Building the AI of F.E.A.R. with Goal Oriented Action Planning
- GDC 演讲:Goal-Oriented Action Planning
- Goal-Oriented Action Planning for a Smarter AI
- 知乎:目标导向型行动计划(GOAP)
- 开源实现参考:ReGoap