news 2026/8/7 19:34:07

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
教程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。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/7 19:16:03

Day12 贝叶斯优化可视化和随机森林的解读

浙大疏锦行 一.元组&#xff1a; 1. 有序&#xff1a;可以通过索引取出来元素 2. 不可变&#xff0c;不可修改 3. 可迭代、可切片 创建元组&#xff1a; # 创建元祖 # 原始元组&#xff1a;(姓名, 年龄, 成绩) old_tuple ("张三", 25, 92.5)print(f"原始…

作者头像 李华
网站建设 2026/8/6 7:28:02

数据湖不是湖,是江湖:Delta Lake / Iceberg / Hudi 到底该选谁?

数据湖不是湖&#xff0c;是江湖&#xff1a;Delta Lake / Iceberg / Hudi 到底该选谁&#xff1f;很多同学一上来就问我一句话灵魂拷问&#xff1a;Echo&#xff0c;Delta、Iceberg、Hudi&#xff0c;我到底该用哪个&#xff1f; 现在不用是不是就“落后”了&#xff1f;说实话…

作者头像 李华
网站建设 2026/8/7 1:02:22

【LeetCode刷题】跳跃游戏

给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。示例 1&#xff1a;输入&am…

作者头像 李华
网站建设 2026/8/7 17:19:52

鸿蒙PC UI控件库 - PasswordInput 密码输入框详解

视频地址&#xff1a; https://www.bilibili.com/video/BV1jomdBBE4H/ &#x1f4cb; 目录 概述特性快速开始API 参考使用示例主题配置最佳实践常见问题总结 概述 PasswordInput 是控件库中专用于密码输入的组件&#xff0c;基于 TextInput 扩展而来&#xff0c;支持显示/…

作者头像 李华
网站建设 2026/8/6 5:27:03

day37简单的神经网络@浙大疏锦行

day37简单的神经网络浙大疏锦行 使用 sklearn 的 load_digits 数据集 (8x8 像素的手写数字) 进行 MLP 训练。 import torch import torch.nn as nn import torch.optim as optim from sklearn.datasets import load_digits from sklearn.model_selection import train_test_s…

作者头像 李华