行为树(Behavior Tree):从 ROS 机器人到 Unity 游戏 AI 的统一决策范式

行为树(Behavior Tree):从 ROS 机器人到 Unity 游戏 AI 的统一决策范式

作者按:本文是"每日一学"系列之一。今天我们聊一个在机器人和游戏 AI 领域都被广泛使用的决策架构------行为树(Behavior Tree, BT)。我们将以 ROS 机器人编程为主线,再延伸到 Unity 中的实践。


一、为什么需要行为树?

在早期的游戏 AI 和机器人决策系统中,有限状态机(Finite State Machine, FSM) 是最常用的方案。它简单直观:定义若干状态,再定义状态之间的跳转条件。

但 FSM 存在一个致命问题:状态数量增加时,跳转边会以平方级膨胀。当你的机器人需要"巡逻 → 发现目标 → 追踪 → 抓取 → 返航 → 充电"等一系列复杂行为时,FSM 会变成一张难以维护的"意大利面图"。

行为树则用树形结构 + 组合节点优雅地解决了这个问题,具备三大优势:

  • 模块化:每个节点是独立的行为单元,可复用、可组合。
  • 可读性强:树形结构天然适合可视化编辑与调试。
  • 响应式(Reactive):每个 tick 都重新评估,能实时响应环境变化。

二、行为树的核心概念

2.1 节点类型

行为树的节点主要分为四大类:

节点类型 作用 典型代表
控制节点(Control) 控制子节点的执行流程 Sequence、Selector、Parallel
装饰节点(Decorator) 修饰单个子节点的行为 Inverter、Retry、Timeout
条件节点(Condition) 判断某种条件 IsBatteryLow、IsObstacleAhead
动作节点(Action) 执行具体行为 MoveTo、Grasp、Speak

2.2 三种状态返回值

每个节点在被 tick 时会返回以下三种状态之一:

  • SUCCESS:执行成功
  • FAILURE:执行失败
  • RUNNING:仍在执行中

2.3 两个最重要的控制节点

Sequence(顺序节点) :相当于逻辑"AND",从左到右依次执行子节点,遇到 FAILURE 立即返回失败,全部成功才返回成功。

Selector / Fallback(选择节点) :相当于逻辑"OR",从左到右依次执行子节点,遇到 SUCCESS 立即返回成功,全部失败才返回失败。


在 ROS 2 生态中,最主流的行为树库是 BehaviorTree.CPP ,它也是 Nav2(导航栈) 的核心调度引擎。Nav2 中的路径规划、避障恢复、目标重试等行为,全部由行为树编排。

3.1 一个机器人巡逻的 XML 示例

BehaviorTree.CPP 支持用 XML 描述行为树:

xml 复制代码
<root main_tree_to_execute="MainTree">
    <BehaviorTree ID="MainTree">
        <Fallback name="root">
            <Sequence name="LowBatteryRecovery">
                <IsBatteryLow/>
                <MoveTo goal="charging_station"/>
                <Charge/>
            </Sequence>
            <Sequence name="Patrol">
                <MoveTo goal="waypoint_A"/>
                <MoveTo goal="waypoint_B"/>
                <MoveTo goal="waypoint_C"/>
            </Sequence>
        </Fallback>
    </BehaviorTree>
</root>

这棵树的逻辑非常清晰:优先检查电量,低电量则回去充电;否则按 A→B→C 巡逻

3.2 自定义动作节点(C++)

cpp 复制代码
#include "behaviortree_cpp/bt_factory.h"

using namespace BT;

class MoveTo : public SyncActionNode {
public:
    MoveTo(const std::string& name, const NodeConfig& config)
        : SyncActionNode(name, config) {}

    static PortsList providedPorts() {
        return { InputPort<std::string>("goal") };
    }

    NodeStatus tick() override {
        std::string goal;
        if (!getInput("goal", goal)) {
            return NodeStatus::FAILURE;
        }
        // 这里调用 ROS 2 的 Action Client,发送导航目标
        ROS_INFO("Moving to: %s", goal.c_str());
        // ... 省略实际导航调用 ...
        return NodeStatus::SUCCESS;
    }
};

int main(int argc, char** argv) {
    BehaviorTreeFactory factory;
    factory.registerNodeType<MoveTo>("MoveTo");

    auto tree = factory.createTreeFromFile("./patrol.xml");
    tree.tickWhileRunning();
    return 0;
}

Nav2 的默认导航行为树(navigate_to_pose_w_replanning_and_recovery.xml)包含:

  • 主流程:周期性重新规划 → 跟随路径
  • 恢复行为 :当导航失败时,依次尝试清除局部代价地图 → 清除全局代价地图 → 原地旋转 → 后退

这种"主行为 + 恢复行为"的模式正是行为树的经典应用:用 Fallback 把"成功路径"和"恢复策略"组合在一起。

3.4 调试利器:Groot2

Groot2 是 BehaviorTree.CPP 配套的可视化编辑器,可以拖拽设计行为树,并在运行时实时高亮当前 tick 的节点,对调试复杂机器人行为极其有用。


四、Unity 中的行为树:游戏 AI 的另一面

行为树在游戏行业的应用其实更早,育碧、Bungie 等大厂在《光环 2》《刺客信条》等作品中都广泛使用。

4.1 Unity 常用方案

  • Behavior Designer(Asset Store 付费):功能最全,支持可视化编辑、变量共享、协程动作。
  • NPBehave(开源):基于代码声明式构建,轻量级。
  • Unity Behavior(官方包,2024 起):Unity 官方推出的 muse 行为图,逐渐成为新标准。

4.2 NPBehave 代码示例

csharp 复制代码
using NPBehave;

public class EnemyAI : MonoBehaviour {
    private Root behaviorTree;

    void Start() {
        behaviorTree = new Root(
            new Selector(
                // 分支1:看到玩家就追击攻击
                new Sequence(
                    new Condition(() => CanSeePlayer()),
                    new Action(() => ChasePlayer()),
                    new Condition(() => InAttackRange()),
                    new Action(() => Attack())
                ),
                // 分支2:默认巡逻
                new Sequence(
                    new Action(() => PatrolNextWaypoint()),
                    new Wait(2.0f)
                )
            )
        );
        behaviorTree.Start();
    }
}

4.3 ROS vs Unity:同一思想的两种语境

维度 ROS 机器人 Unity 游戏
典型动作 导航、抓取、传感器读取 追击、攻击、寻路
Tick 频率 通常 10--50 Hz 与帧率绑定(60+ Hz)
执行模型 异步 Action(长耗时) 协程 / 帧驱动
黑板共享 ROS 参数 / Topic ScriptableObject / 内置 Blackboard
调试工具 Groot2 Behavior Designer Inspector

值得注意的是,Unity Robotics Hub 项目把 ROS 和 Unity 连接起来,可以用 Unity 做机器人仿真,再用 ROS 端的行为树驱动决策------两个世界正在融合。


五、行为树的进阶话题

掌握基础后,可以继续学习以下几个进阶方向:

  1. 黑板(Blackboard):节点之间通过共享的键值存储传递数据,避免硬耦合。
  2. 并行节点(Parallel):同时执行多个子节点,在"边走边说话"这类场景中很有用。
  3. 响应式 vs 一次性:是每个 tick 都重新评估条件,还是仅在状态切换时评估?
  4. 行为树 + 效用函数(Utility AI):用打分机制选择最优分支,比纯优先级更智能。
  5. 行为树 + LLM:2024 年起,已经有研究用大模型动态生成行为树,让机器人具备"听人话办事"的能力。

六、今日小结

行为树本质上是一种用树形结构组织"决策---执行"流程 的范式。它在 ROS 机器人 (Nav2、BehaviorTree.CPP)和 Unity 游戏 AI 中都是事实标准,因为它同时满足了模块化、可视化、可响应这三大需求。

给你的一个动手作业 🛠️:

用 BehaviorTree.CPP(或 NPBehave)实现一个"扫地机器人"行为树:在电量充足时清扫 → 检测到障碍则绕行 → 电量低于 20% 自动返航充电。先画 XML / 树图,再用代码实现,体验"先设计后编码"的流程。

明天见,继续我们的"每日一学"!🚀

相关推荐
郝学胜-神的一滴2 小时前
[简化版 GAMES 104] 现代游戏引擎 02:拆解现代游戏引擎5+1层级架构,吃透引擎底层核心逻辑
c++·unity·架构·游戏引擎·图形渲染·unreal engine·系统设计
德迅云安全-上官3 小时前
德迅云安全游戏盾与DDoS高防IP对比:差异、优势及选型指南
tcp/ip·游戏·ddos
REDcker4 小时前
机器人世界模型三类分类详解
分类·数据挖掘·机器人
LONGZETECH4 小时前
新能源汽车充电设备装配与调试仿真教学软件 技术架构与核心实现解析
大数据·算法·3d·unity·架构·汽车
code_pgf4 小时前
C++ 工程架构设计规范
c++·机器人
自动化智库4 小时前
OpenCvSharp读取、显示和写入图像
机器人
丁小未5 小时前
Unity 几种常见合批手段的要求
游戏·unity·合批·srpbatcher·动态合批·静态合批
光锥智能13 小时前
WAIC亮点|兼具泛化能力与作业效率的极智嘉机器人天团
人工智能·机器人
河南花仙子科技17 小时前
花仙子科技详解:小游戏合规开发完整要点
科技·游戏
chase。1 天前
【学习笔记】PointWorld:迈向通用机器人操控的3D世界模型
笔记·学习·机器人