行为树(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 / 树图,再用代码实现,体验"先设计后编码"的流程。

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

相关推荐
数智工坊5 小时前
【ROS 2 全栈入门指南一】:从本质认知到环境搭建与核心原理解析
学习·机器人
AImatters5 小时前
原力灵机并购Atomix:让机器人在真实业务中长出数据飞轮
机器人·大模型·具身智能·atomix·原力灵机
Rauser Mack5 小时前
不懂编程,但是vibe coding一个扫雷游戏
人工智能·python·游戏·html·prompt
不知名的老吴5 小时前
Unity3D 2022安装教程及全流程下载步骤指南
unity·游戏引擎
Thomas_YXQ6 小时前
Unity3D Addressable 深度优化热更性能消耗
开发语言·3d·unity·微信
程序员也有头发6 小时前
如何使用AI工具开发Unity
unity·游戏引擎·ai编程
隔窗听雨眠6 小时前
从零开始的游戏开发入门指南
unity
数智工坊6 小时前
【ROS 2 全栈入门指南三】:Action、参数与Launch文件全链路指南
android·stm32·嵌入式硬件·学习·机器人
Agilex松灵机器人6 小时前
ROS 机械臂开发效率低?用 Agent + 具身智能重构开发流程
重构·机器人·自动驾驶
sinat_384503116 小时前
【无标题】
unity·webgl