Behavior3JS 开源项目教程
1. 项目的目录结构及介绍
Behavior3JS 是一个用于 JavaScript 的行为树库。以下是其目录结构的详细介绍:
behavior3js/
├── docs/
│ └── theme/
├── src/
├── test/
├── .babelrc
├── .gitignore
├── .jshintrc
├── .npmignore
├── .travis.yml
├── CHANGES
├── LICENSE
├── README.md
├── bower.json
├── gulpfile.js
└── package.json
docs/: 包含项目的文档文件。
src/: 包含项目的源代码文件。
test/: 包含项目的测试文件。
.babelrc: Babel 配置文件。
.gitignore: Git 忽略文件配置。
.jshintrc: JSHint 配置文件。
.npmignore: NPM 忽略文件配置。
.travis.yml: Travis CI 配置文件。
CHANGES: 项目变更记录。
LICENSE: 项目许可证。
README.md: 项目说明文档。
bower.json: Bower 包管理配置文件。
gulpfile.js: Gulp 任务配置文件。
package.json: NPM 包管理配置文件。
2. 项目的启动文件介绍
Behavior3JS 的启动文件主要是 src/ 目录下的文件。以下是一些关键文件的介绍:
src/BehaviorTree.js: 行为树的核心实现文件。
src/Blackboard.js: 黑板系统的实现文件。
src/core/BaseNode.js: 节点基类的实现文件。
src/core/BehaviorTree.js: 行为树的实现文件。
src/core/Composite.js: 复合节点的实现文件。
src/core/Decorator.js: 装饰节点的实现文件。
src/core/Action.js: 动作节点的实现文件。
src/core/Condition.js: 条件节点的实现文件。
- 项目的配置文件介绍
Behavior3JS 的配置文件主要包括以下几个:
.babelrc: 用于配置 Babel 编译器,确保代码可以在不同环境中运行。
.jshintrc: 用于配置 JSHint 代码检查工具,帮助开发者遵循一致的代码风格。
gulpfile.js: 用于配置 Gulp 任务,自动化构建过程。
package.json: 包含了项目的元数据和依赖项,是 NPM 包管理的核心配置文件。
通过这些配置文件,开发者可以自定义项目的构建和运行环境,确保项目在不同开发和部署场景下的稳定性和一致性。
behavior3editor安装使用踩坑
官方文档:https://github.com/magicsea/behavior3editor/blob/master/BUILD.md
根据步骤需要先安装npm,但是注意了npm的版本不能过高,否则会与gulp冲突
目前gulp的版本不能高于4,因为项目gulpfile.js使用的函数只能支持4以下的版本.
在多次尝试以后,npm版本为v10.24.1,gulp版本为v3.9.1,可以正常运行项目
黑板(Blackboard)的作用
黑板是行为树的内存系统,用于在节点之间存储和共享数据。它提供了三种不同作用域的数据存储:
三种数据上下文
- 全局上下文(Global Context)
范围:所有行为树和所有节点都可访问
用法:
blackboard.set('testKey', 'value');
var value = blackboard.get('testKey');
- 每棵树上下文(Per Tree Context)
范围:同一棵树内的节点共享数据
用法:
blackboard.set('testKey', 'value', tree.id);
var value = blackboard.get('testKey', tree.id);
- 每节点每棵树上下文(Per Node Per Tree Context)
范围:只有特定节点在特定树中可访问
用法:
blackboard.set('testKey', 'value', tree.id, node.id);
var value = blackboard.get('testKey', tree.id, node.id);
内部实现结构
_baseMemory:存储全局数据
_treeMemory:存储每棵树的数据
_treeMemory[id].nodeMemory:动态创建的节点级存储
实际应用场景
// 全局:所有AI共享的配置
blackboard.set('maxHealth', 100);
// 每棵树:单个AI的当前状态
blackboard.set('currentHealth', 80, aiTree.id);
// 每节点:节点私有数据
blackboard.set('lastAttackTime', Date.now(), aiTree.id, attackNode.id);
在Behavior3行为树中,Composite(复合)节点是控制节点的一种,它们负责管理子节点的执行顺序和逻辑。以下是所有Composite节点的详细解释:
- Sequence(顺序节点)
javascript
// 按顺序执行子节点,直到所有成功或某个失败
行为:从左到右依次执行子节点
成功:所有子节点都成功执行
失败:任何一个子节点失败就立即停止
使用场景:需要按步骤顺序执行的任务序列
- MemSequence(记忆顺序节点)
javascript
// 带记忆的顺序节点,记住正在运行的节点
行为:类似Sequence,但会记住上次执行的节点
特点:当有子节点返回RUNNING时,下次tick会从该节点继续
使用场景:需要保持执行状态的顺序任务
- Priority(优先级节点 / Selector)
javascript
// 按优先级执行,直到找到成功的子节点
行为:从左到右执行,选择第一个成功的子节点
成功:任何一个子节点成功就停止
失败:所有子节点都失败
使用场景:条件分支选择、行为优先级
- MemPriority(记忆优先级节点)
javascript
// 带记忆的优先级节点
行为:类似Priority,但会记住上次返回RUNNING的节点
特点:下次tick优先执行上次运行中的节点
使用场景:需要保持运行状态的条件选择
执行流程对比
Sequence 示例:
text
子节点1(成功) → 子节点2(失败) → 停止(返回失败)
子节点1(成功) → 子节点2(成功) → 子节点3(成功) → 停止(返回成功)
Priority 示例:
text
子节点1(失败) → 子节点2(成功) → 停止(返回成功)
子节点1(失败) → 子节点2(失败) → 子节点3(失败) → 停止(返回失败)
实际应用示例
javascript
// 攻击行为的Sequence
new Sequence([
new CheckEnemyInRange(), // 条件:敌人在范围内
new AimAtTarget(), // 动作:瞄准目标
new FireWeapon() // 动作:开火
])
// 行为选择的Priority
new Priority([
new FleeFromDanger(), // 优先级1:逃离危险
new AttackEnemy(), // 优先级2:攻击敌人
new PatrolArea() // 优先级3:巡逻
])
记忆 vs 非记忆版本
非记忆:每次tick都从第一个子节点重新开始评估
记忆:会记住运行状态,适合长时间运行的任务
这些Composite节点是构建复杂行为逻辑的基础,通过组合它们可以创建出丰富的行为模式。
在Behavior3中,节点分为几种类型,包括Composite(组合节点)、Decorator(装饰节点)、Action(动作节点)和Condition(条件节点)。这里我们主要解释Decorators和Actions。
Decorators(装饰节点)
装饰节点是一种可以修改子节点行为的节点。它通常只有一个子节点。装饰节点可以对子节点的返回结果进行修改,或者根据条件决定是否执行子节点。
- Inverter(取反节点)
功能:将子节点的结果取反。如果子节点返回SUCCESS,则返回FAILURE;如果子节点返回FAILURE,则返回SUCCESS;如果子节点返回RUNNING,则返回RUNNING。
使用场景:当需要检查某个条件不成立时执行某个行为。
- Limiter(限制节点)
功能:限制子节点在指定时间内只能执行一定次数。通常用于防止某个行为被频繁执行。
使用场景:限制某个动作的执行频率,例如,限制攻击速度。
- MaxTime(最大时间节点)
功能:设置子节点的最大运行时间。如果子节点在指定时间内没有返回,则中断子节点并返回FAILURE。
使用场景:给某个行为设定时间限制,超时则视为失败。
- Repeater(重复节点)
功能:重复执行子节点一定次数或无限次。可以设置重复次数,直到达到指定次数才返回SUCCESS。
使用场景:需要重复执行某个动作,例如,连续攻击多次。
- RepeatUntilFailure(直到失败重复节点)
功能:重复执行子节点直到子节点返回FAILURE。如果子节点返回SUCCESS或RUNNING,则会再次执行子节点,直到失败。
使用场景:持续执行某个动作直到失败,例如,一直移动直到遇到障碍。
- RepeatUntilSuccess(直到成功重复节点)
功能:重复执行子节点直到子节点返回SUCCESS。如果子节点返回FAILURE或RUNNING,则会再次执行子节点,直到成功。
使用场景:持续执行某个动作直到成功,例如,一直尝试开门直到成功。
Actions(动作节点)
动作节点是行为树的叶子节点,它们实际执行具体的行为或动作。动作节点没有子节点。
- Wait(等待节点)
功能:等待指定的时间,然后返回SUCCESS。在等待期间返回RUNNING。
使用场景:需要等待一段时间,例如,冷却时间。
- Log(日志节点)
功能:在控制台输出一条日志信息,然后返回SUCCESS。
使用场景:调试行为树,输出一些状态信息。
- Runner(运行器节点)
功能:持续运行一段时间,然后返回SUCCESS。在运行期间返回RUNNING。
使用场景:执行一个需要时间的过程,例如,播放一段动画。
- Error(错误节点)
功能:立即返回FAILURE。用于测试或标记未实现的功能。
使用场景:占位或测试。
- Succeed(成功节点)
功能:立即返回SUCCESS。用于测试或标记总是成功的节点。
使用场景:占位或测试。
- Fail(失败节点)
功能:立即返回FAILURE。用于测试或标记总是失败的节点。
使用场景:占位或测试。
关键说明
行为树执行顺序 从左往右,从上往下
Sequence是顺序节点,相当于与行为 所有有子节点返回成功 则父节点成功,任意一子节点失败则父节失败, 任意一子节点为运行中,则父节点为运行中, 主要对成功敏感,成功则继续下一子节点,失败则返回到父节点
Priority是选择节点,相当于或行为,所有子节点返回失败,则父节点返回失败,任意一字节点成功则父节点返回成功,任意一子节点为运行中,则父节点运行中, 主要对失败敏感,失败则继续下一子节点,成功则返回父节点