当前位置: 首页 > news >正文

教程5:子树的使用-–-behaviac

原文

本文档描述的是3.6及以后版本,对于3.5及以前的老版本请参考分类“3.5”。

子树可以用来复用已有的行为树。通过子树节点,一个行为树可以作为另一个行为树的子树,而作为子树的那个行为树将被父树所“调用”。

子树还可以类似编程语言中的函数调用一样通过传递参数来使用。

类似动作节点,子树节点根据子树的执行结果也会返回一样的执行结果(即成功、失败或正在执行),其父节点按照自己的控制逻辑来控制接下来的运行。

1. 编辑类型信息

首先,我们需要添加一个Agent类,后面会利用这个Agent类来创建行为树。

打开类型信息浏览器,分别为Agent类“FirstAgent”添加成员属性、方法和任务。

添加int类型的成员属性p1,如下图所示:

添加成员方法Say,该方法带有一个string&类型的参数,如下图所示:

添加任务t1,该任务带有一个int类型的参数,如下图所示:

2. 不带参数的子树

首先给出子树最直接的用法——不带参数的子树:

首先,创建行为树“subtree”,将动作节点的方法Say的参数设置为“Hello subtree!”,如下图所示:

Say方法的功能是输出指定的字符串,如下代码所示:

voidFirstAgent::Say(behaviac::string&param0){///<<< BEGIN WRITING YOUR CODE Sayprintf("\n%s\n\n",param0.c_str());///<<< END WRITING YOUR CODE}

然后,创建行为树“maintree”,并将行为树列表中的节点“subtree”直接拖拽到该树中,如下图所示:

这样,行为树“maintree”就可以“调用”子树“subtree”了。

加载并执行行为树“maintree”后,结果如下图所示:

可以看到,输出了“Hello subtree!”字符串,说明子树“subtree”得到了正确的调用和执行。

3. 带参数的子树

有时候,我们可能需要给子树传递参数来使用,这样子树会更加模块化。

对于这种需要传参的子树,可以按照如下操作进行:

首先,创建行为树“subtree_task”,并为其添加的第一个子节点必须是任务节点,如下图所示:

为上图中的任务节点,在其属性窗口中配置其“任务”参数为“t1”,如下图所示:

由于任务“t1”带有参数“param0”,所以在上面行为树“subtree_task”的条件节点中可以使用该参数“param0”,如上图所示。可以借鉴程序语言的说法,该参数“param0”就类似于函数的形参。

然后,创建行为树“maintree_task”,并将行为树列表中的节点“subtree_task”直接拖拽到该树中,如下图所示:

选中上图中的子树节点,配置任务的参数值“param0”为2(这个参数类似于函数中的实参),如下图所示:

这样,行为树“maintree_task”就可以“调用”子树“subtree_task”,并为该子树传递参数了。

加载并执行行为树“maintree_task”后,结果如下图所示:

可以看到,输出了“Hello subtree_task!”字符串,说明子树“subtree_task”得到了正确的调用和执行。

4. 添加子树节点的补充说明

  • 如上所述,可以从编辑器左侧的行为树节点列表中,通过鼠标选择并拖拽一棵行为树到另一棵行为树中来生成子树节点。被拖拽的行为树的路径被设置到引用文件名。需要指出的是,并非任意一个行为树都可以作为另外一个行为树的子树。3.6.32及之前版本,作为子树的Agent类型必须是父树的Agent类型的同类或父类。而3.6.33及之后版本,作为子树的Agent类型可以是父树的Agent类型的同类或父类或子类,但是需要保证执行该父树的Agent实例是父树和子树的Agent类型的子类或更低子类的实例(例如,假设父树的Agent类型是A,子树的Agent类型是B:如果A是B的子类,那么执行该父树的Agent实例必须是A或者A的子类的实例;如果B是A的子类,那么执行该父树的Agent实例必须是B或者B的子类的实例)。

  • 另外,也可以像添加其他节点那样,在节点列表中选取子树,拖拽到相应的位置,然后点击该子树节点,在右侧的属性窗口中配置引用文件名任务

  • 如果手工配置的子树的路径是空的或无效的,在检查错误时会报错,表示该树不允许被导出。如果配置的是属性或方法,在编辑器中无法知其是否有效,只有运行的时候才会报运行时错误,如果运行过程中该值无效。

本教程相关的工作区和代码工程详见源码包的目录tutorials/tutorial_5。

http://www.cnnetsun.cn/news/42736.html

相关文章:

  • Day12 贝叶斯优化可视化和随机森林的解读
  • 数据湖不是湖,是江湖:Delta Lake / Iceberg / Hudi 到底该选谁?
  • 告别开题报告模板拼凑!虎贲等考 AI 智能生成,让选题逻辑从模糊想法变身可执行研究计划
  • 【LeetCode刷题】跳跃游戏
  • 鸿蒙PC UI控件库 - PasswordInput 密码输入框详解
  • day37简单的神经网络@浙大疏锦行
  • 【水果识别】基于机器视觉苹果和香蕉的成熟度和大小检测附Matlab代码
  • JAVA的平凡之路——此峰乃是最高峰JVM-附加小菜-04
  • 【电力系统】电力系统优化与控制热液调度附Matlab代码和报告
  • 基于6种最新算法(小龙虾优化算法COA、MSA、RTH、NOA、BFO、SWO)求解机器人路径规划研究附Matlab代码
  • Golang实战:构建综合多头(逾期+反欺诈)风险查询的高性能客户端
  • 【TSP问题】基于蜣螂算法DBO和改进的蜣螂算法FADBO求解旅行商TSP问题(可根据自己的经纬度设置自己想要到达的地区)附Matlab代码
  • 【太阳能学报EI复现】基于粒子群优化算法的风-水电联合优化运行分析附Matlab代码
  • 数据结构:二叉排序树,平衡二叉树,红黑树的介绍
  • 软件复用的分类与实现
  • google服务
  • 进程PCB
  • 实战教程:1小时掌握逆向Unity游戏 (共13课时)
  • [从零构建操作系统]08 函数调用时栈的底层行为解析
  • 力扣hot100:搜索插入位置
  • Java冷启动全指南:从原理到实战优化
  • 测试 - 单元测试(JUnit)
  • C++中多态
  • c++经典练习题-多分支
  • qt为什么转向用cmake放弃qmake
  • 云屋音视频 SDK 凭何成为信创技术困局的 “破局者”?
  • 纯电动汽车动力经济性仿真:Cruise与Simulink联合仿真(2015版),包含BMS、再...
  • 【怎么理解maven中的镜像和仓库?】
  • comsol枝晶生长,沉积模型,包括:典型,形状成核,随机成核,均匀沉积,雪花晶形成过程。 适...
  • 终极指南:Qwen3-30B-A3B多GPU分布式推理完整解决方案