来,讲个故事

硬核游戏开发 - 使用BehaviorTree实现游戏AI决策的开发详解

:video_game: 一个让策划抓狂的Bug

“这个BOSS太蠢了!它明明看到玩家了,为什么还在那里发呆?”

这是我在某公司实习时,听到最多的一句话。那是一个魔幻RPG项目,我负责实现一个"智能"的龙王BOSS。按照策划的设计文档,这个BOSS应该能够:

  • :mag: 侦察阶段:在玩家进入领域前巡逻,警戒四周
  • :crossed_swords: 战斗阶段:发现玩家后立即进入战斗状态,根据距离选择近战或远程攻击
  • :drop_of_blood: 血怒阶段:血量低于30%时进入狂暴模式,攻击力翻倍
  • :shield: 防御阶段:受到大量伤害时短暂防御,恢复少量血量
  • :dash: 逃跑阶段:血量极低时尝试逃跑,寻找掩体

听起来很简单对吧?我天真地用了一堆 if-else 语句:

function updateBoss() {
    if (boss.hp < 0.1 * boss.maxHp) {
        if (canEscape()) {
            escape();
        } else if (canDefend()) {
            defend();
        } else {
            attack();
        }
    } else if (boss.hp < 0.3 * boss.maxHp) {
        if (playerInRange()) {
            berserkerAttack();
        } else {
            moveToPlayer();
        }
    } else if (playerDetected()) {
        if (playerDistance() < 5) {
            meleeAttack();
        } else {
            rangedAttack();
        }
    } else {
        patrol();
    }
}

结果? 一场灾难!

  • BOSS经常在攻击和防御之间疯狂切换
  • 有时候明明发现了玩家,却突然开始巡逻
  • 血怒状态下居然还会尝试逃跑
  • 最要命的是:每次策划要求调整优先级,我都要重写整个逻辑!

三个通宵后,我的代码变成了一个800行的意大利面条,连我自己都看不懂了。更糟糕的是,每次修复一个bug,就会产生三个新bug。

直到我遇到了行为树…

一周后,同样的BOSS逻辑,我用行为树重新实现了:

龙王BOSS行为树:
根节点(优先选择器)
├── 逃跑分支(血量 < 10%)
│   ├── 寻找掩体
│   └── 快速移动
├── 防御分支(受到重击)
│   ├── 播放防御动画
│   └── 恢复少量血量
├── 血怒分支(血量 < 30%)
│   ├── 进入狂暴状态
│   └── 疯狂攻击
├── 战斗分支(发现玩家)
│   ├── 距离判断
│   ├── 近战攻击 OR 远程攻击
│   └── 追击玩家
└── 巡逻分支(默认行为)
    ├── 沿路径移动
    └── 警戒四周

奇迹发生了!

  • :white_check_mark: BOSS行为逻辑清晰,优先级明确
  • :white_check_mark: 策划可以直接看懂并提出修改意见
  • :white_check_mark: 新增行为只需要添加新分支,不影响现有逻辑
  • :white_check_mark: 调试时可以清楚看到每一步的决策过程
  • :white_check_mark: 代码从800行缩减到200行,可读性提升10倍!

更重要的是,当策划说"能不能让BOSS在血量50%时召唤小怪"时,我只需要在行为树中插入一个新分支,5分钟搞定!


这就是行为树的魅力。

作为一名游戏开发者,你是否也遇到过类似的问题?当游戏中的怪物、NPC需要表现出复杂行为时——巡逻、追击、逃跑、施法、观察环境并做出判断——背后往往不应该是一条又一条 if-else 的堆叠,而是一套清晰、可扩展、可调试的决策框架:行为树(Behavior Tree)

本指南将带你从零开始认识行为树,让你也能构建出让策划赞不绝口的游戏 AI 决策系统!

一、开篇

行为树是一种用于描述 AI 决策逻辑的树形结构:由根节点驱动,组合节点(如「选择器」「序列」)负责控制流程,装饰节点用于修饰行为,叶子节点则执行具体动作或进行条件判断。相较有限状态机(FSM),行为树更易组合与复用,能自然表达“尝试 A 否则 B”“按顺序执行直到成功”等复杂模式,并且非常适合可视化编辑与热更新。

二、行为树执行流程 - 一个哥布林的日常决策

想象一下,你是一只聪明的哥布林守卫,正在洞穴门口值班。每一秒钟,你的大脑都在运转着一套复杂的决策系统——这就是行为树!

1. 三种人生状态(节点状态)

就像人生一样,行为树中的每个节点都只有三种可能的状态:

  • 成功 :white_check_mark: - “太好了!任务完成!”
  • 失败 :x: - “唉,这条路走不通…”
  • 运行中 :hourglass_flowing_sand: - “别催,我还在努力呢!”

这就像你在思考"今晚吃什么"时的状态:要么想到了(成功),要么放弃了(失败),要么还在纠结中(运行中)。

2. 决策节点大家族 - 每个都有自己的性格

2.1 选择节点 - “备胎专家”

性格特点:永不放弃的乐观主义者,总是有Plan B、Plan C…

想象你是个饿肚子的哥布林,面前有三个选择:

  1. 去厨房找剩菜
  2. 去花园抓虫子
  3. 啃树皮充饥

选择节点就像一个不死心的你:

  • 先试试厨房有没有剩菜(第一个子节点)
  • 如果厨房空空如也(失败),那就去花园抓虫子(第二个子节点)
  • 虫子也没有?那就啃树皮吧(第三个子节点)
  • 只要有一个成功了,选择节点就满意地说:“搞定!”

执行规则

从左到右挨个试:
✅ 子节点成功 → "太好了!" → 选择节点成功
❌ 子节点失败 → "下一个!" → 继续尝试
⏳ 子节点运行中 → "等等..." → 选择节点也运行中

2.2 顺序节点 - “完美主义者”

性格特点:严格按计划执行,一步都不能错

还是那只饿肚子的哥布林,但这次你决定做一顿大餐:

  1. 先洗手
  2. 然后准备食材
  3. 接着开火做饭
  4. 最后享用美食

顺序节点就像一个强迫症患者:

  • 必须先洗手,洗不干净就不继续
  • 洗手成功了,才能准备食材
  • 食材准备好了,才能开火
  • 任何一步失败,整个计划泡汤!

执行规则

严格按顺序来:
✅ 子节点成功 → "很好,下一步!" → 继续执行
❌ 子节点失败 → "完蛋了!" → 顺序节点失败
⏳ 子节点运行中 → "慢慢来..." → 顺序节点等待

2.3 行为节点 - “实干家”

性格特点:话不多说,撸起袖子就是干

这是真正干活的节点,比如:

  • “巡逻10秒钟”
  • “攻击敌人”
  • “播放死亡动画”

行为节点就像一个靠谱的员工,给它一个任务,它会:

  • 立即开始执行(返回"运行中")
  • 完成后汇报结果(“成功"或"失败”)
  • 有些任务需要时间,会持续返回"运行中"

2.4 条件节点 - “侦察兵”

性格特点:眼观六路,耳听八方,专门负责收集情报

条件节点就像哨兵,负责观察环境:

  • “敌人在视野内吗?”
  • “血量低于30%吗?”
  • “身上有钥匙吗?”

它们动作很快,瞬间给出答案:要么"是"(成功),要么"不是"(失败),没有"也许"。

3. 一个完整的哥布林决策故事

让我们看看一只哥布林守卫的完整思考过程:

哥布林的行为树:
根节点(选择)
├── 战斗分支(顺序)
│   ├── 条件:发现敌人?
│   ├── 行为:冲向敌人
│   └── 行为:攻击
├── 巡逻分支(顺序)
│   ├── 条件:在巡逻路径上?
│   └── 行为:继续巡逻
└── 待机分支
    └── 行为:原地等待

执行过程

  1. 第一轮思考

    • 选择节点:“让我看看该做什么…”
    • 尝试战斗分支 → 检查"发现敌人?" → 没有敌人(失败)
    • 尝试巡逻分支 → 检查"在巡逻路径上?" → 是的(成功)→ 开始巡逻(运行中)
  2. 第二轮思考(巡逻进行中):

    • 选择节点:继续之前的决策
    • 巡逻分支:巡逻还在进行中…
  3. 第三轮思考(突然发现敌人):

    • 选择节点:重新评估
    • 尝试战斗分支 → “发现敌人?” → 有敌人!(成功)→ 冲向敌人(运行中)

这就是行为树的魅力:每一帧都在重新评估,动态调整策略,就像一个真正在思考的智能体!

4. 可视化流程图 - 让抽象变具体

看完了哥布林的故事,让我们用更直观的方式来理解行为树的执行过程。

4.1 一颗简单的行为树结构

这就是我们刚才讲的哥布林决策树的可视化版本。每个方块代表一个节点,箭头表示执行流向。

4.2 执行流程的"心跳"

行为树就像一颗跳动的心脏,每一帧(通常是1/60秒)都会从根节点开始"心跳"一次:

执行流程就像这样

  1. 心跳开始 - 从根节点开始
  2. 向下探索 - 根据节点类型决定如何执行子节点
  3. 状态回传 - 叶子节点的结果层层向上传递
  4. 等待下次心跳 - 一帧结束,等待下一帧继续

这种"心跳式"的执行方式让AI能够:

  • :arrows_counterclockwise: 实时响应:每帧都重新评估环境
  • :dart: 优先级明确:重要的行为总是先被考虑
  • :wrench: 易于调试:可以清楚看到每一步的决策过程
  • :rocket: 性能友好:只执行必要的节点,避免浪费

小贴士:想象行为树就像一个永不疲倦的大脑,每一瞬间都在问自己:"现在最应该做什么?"然后立即行动!

9赞

厉害:+1:t2:学习了

上demo,我是伸手党

https://github.com/gongxh0901/kunpocc-behaviortree

git仓库在这

自从有了AI,你的文采都变好了呢

哈哈哈哈哈哈

好文好文好文

bro你不用的哪个版本类


你说的是这个吧

cocos的版本

cocos 我用的一直都是3.8.6

你这搞错了
你打开的应该是行为树的源码

里边有个bt-demo文件夹,是demo工程

好了。u are good man!!!!!!!!!!!

怎么能发好人卡呢,你又不是妹子

还好我删的快~

这也太利索了吧,,都不好意思了

随便用
核心实现里边有,可以用代码构建行为树
我们几个中重度的游戏都是代码写的

编辑器没提供,那个是收费项目哟,也是最近刚做的,准备下个项目用的,代码写行为树写吐了
哈哈


感兴趣可以加个群
也可以加我个人微信,我的资料里边个人网站中有联系方式

1赞