行为树可视化搭建平台Groot2使用说明文档
前言:行为树是部署全自动机器人行为决策的重要工具,而在行为树搭建过程中树形结构的形成是最为具象化的表现。在行为树系统中,由行为节点构成的树形结构信息被记录在.xml行为树配置文件中。编写行为树配置文件是极为重要的一步,如果选择手搓xml代码,难度较大且出错率较高;正因如此,易与ROS/ROS2系统集成的行为树库BehaviorTree.CPP提供了简化行为树搭建过程的可视化搭建平台Groot2,借此高效搭建行为树。然而在调研学习该可视化平台的使用方法的过程中,我发现很少有集成的、系统的节点使用说明,大多零散且不详,因此经过实践整理出此篇比较详细周全的行为树可视化搭建平台Groot2使用说明文档,供决策者参考,也请对错误之处进行指正。另,本篇使用说明针对V3版本,V4版本的节点使用方法会有不同。
一、Action动作节点
1. AlwaysFailure
(1)样式

(2)功能:该节点能够确保无论它的子节点执行结果如何,节点本身都会返回失败状态。如有特殊需要可始终置failure。
2. AlwaysSuccess
(1)样式

(2)功能:与AlwaysFailure相反,该节点能够确保无论它的子节点执行结果如何,节点本身都会返回成功状态。如有特殊需要可始终置success。
3. SetBlackboard
(1)样式

(2)功能:SetBlackboard节点用于修改行为树中的黑板数据。该节点允许将一个新的值设置到黑板的某个键上,或更新现有的值。
(3)参数及填写说明
1)IN: value:这个参数用于指定要存储在黑板上的实际数据值,可以是常量,也可以是从其他节点中传递过来的变量。IN类型标识表示数据值参数只能被传入。
2)IN/OUT: output_key:这个参数决定了上面的数据值要传入的位置,即黑板中的键。IN/OUT类型标识表示键参数能从接口被传入,也能被读取。
注意:
官方提供的SetBlackboard节点比较局限,只允许为类型为字符串的黑板变量进行赋值,否则行为树执行过程中会意外中断并出现如下错误提示:
what(): Blackboard::set() failed: once declared, the type of a port shall not change. Declared type [int] != current type [std::string]
这个错误表明在尝试将某个值设置到黑板(Blackboard)时,类型不匹配。具体来说,黑板中已经声明了一个 int 类型的键,但你在代码中尝试用 std::string 类型来设置它。其中的原因就在于SetBlackboard节点只接受字符串类型的数据。
如果要对黑板中的其他类型的数据进行设置,建议自己写赋值节点。
二、Condition条件节点
Groot2V3版本未提供任何现成的条件节点,均需自定义。自定义规则见“六、节点添加准则”。
三、Control控制节点
1. Parallel
(1)样式

(2)功能:Parallel节点是一个控制节点,它允许并行执行多个子节点,并根据子节点的执行结果来决定整个Parallel节点的状态。
(3)参数及填写说明
1)IN:failure_threshold:指定了失败的容忍度,表示在并行执行的子节点中,最多有多少个子节点失败时,整个 Parallel 节点才会返回 FAILURE。填入一个整数。
2)IN:success_threshold:指定了成功的要求,表示在并行执行的子节点中,至少有多少个子节点成功时,整个 Parallel 节点才会返回 SUCCESS。填入一个整数。
注意:
你所填的节点数量不能比Parallel所连接的子节点数量还要多(IN<=child)!否则这个节点可能将永远无法结束,且在运行行为树时会导致行为树意外中断并有如下错误提示:
Starting behavior tree terminate called after throwing an instance of 'BT::LogicError' what(): Number of children is less than threshold. Can never fail. [ros2run]: Aborted
4)运行效果:
在功能上,Parallel的确能使其子节点同时运行,但实际上每个子节点运行的频率是不一样的,子节点运行频率尤其受到其他子节点运行状态的影响(在概率上可以称这些节点不是相互独立的,而是相互耦合牵连的)。例如前一个子节点所连接的子树正在执行循环结构,那么该循环结构的执行频率会被拉高,整棵树可能会阻塞在该循环处,导致其他平行节点的执行频率被拉低,此时如果统一订阅消息的节点被习惯性地写在主树之外的平行节点处,就会因为执行频率低而导致消息收发严重延时,影响行为执行对时变条件的响应速度。
解决方法:
建议少用甚至不用Parallel节点,将需要并行处理的节点写成多线程的方式,多线程能保证并行节点之间的相互独立,频率之间互不影响,且能灵活设置调整任一线程的执行频率。
FYI:感觉ros2多线程结构简洁、复杂度较低、调试简单有效。
2. Fallback
(1)样式

(2)功能与执行逻辑:
Fallback 节点通常用于行为树中的选择结构,它类似于条件语句中的“如果…否则”(if...else...)的逻辑。首先顺序执行其子节点,只要某个子节点返回成功(Success),Fallback 节点就会停止执行后续子节点,并返回成功。如果所有子节点都返回失败(Failure),Fallback 节点本身才会返回失败。
3. IfThenElse
(1)样式

(2)功能:
该节点的工作机制类似if...else... 语句,根据给定条件的结果来决定执行路径。如果条件成立(即返回成功),就执行Then路径;如果条件不成立(即返回失败),则执行Else路径,而在该节点中不提供专门连接else分支的接口,因此执行else也即结束该节点的运行、跳出。节点实现了分支判断、执行功能。
(3)连接准则:
在Groot2中,IfThenElse节点能连接两个或三个节点,其中一个是条件节点,用于IfThenElse的条件判断,另一个是动作节点,对应满足if条件后Then分支下执行的动作节点。
两个节点连接IfThenElse节点的顺序不能被打乱,左右顺序应严格遵守逻辑顺序。规则为:
左边的节点应为条件节点,右边的节点对应条件成立时Then后对应的动作节点。
节点连接示例如下:

这样的连接对应的逻辑代码如下:

逻辑即为:
If ParameterCheck==True:
执行 TurnHeadAction;
Else:
结束、跳出;
连接建议:
尽量只连接两个节点(即If与Then的部分),根据调试经验,能保证If…Then…的部分一定能执行到,此时若不满足则会直接跳出;而如果连了三个节点,3.x版本的行为树内部执行机制可能仍然会直接跳过后面的部分,尽管看似连接了Else的部分也会被忽略。
如果要表达Else的逻辑,甚至是分支嵌套的逻辑,建议用Fallback组织多分支的行为选择。Fallback与IfThenElse的结合就能表达分支的嵌套。
4. ManualSelector
(1)样式

(2)功能
ManualSelector是特殊的选择节点,它允许手动控制行为树中某些选择的执行。与普通的Selector节点自动选择子节点不同,该节点使开发者可以通过外部输入来指定应该执行哪个子节点。即可以在运行时人为、手动、强制地选择执行一个特定动作节点,而不是随着行为树的执行自动运行。
(3)参数及填写说明
IN: repeat_last_selection:
该节点只有这一个参数。参数类型是bool类型,用于控制是否重复执行上次选择的子节点。
若repeat_last_selection = true,继续执行上一次被选择的子节点,这对于希望重复执行某个操作或保持上一状态的场景非常有用。
若repeat_last_selection = false或不设置,则执行该节点时,都会根据手动输入选择新的子节点来执行。
(4)连接准则与外部传入选择方法
1)连接准则:在ManualSelector节点下可以并排连接若干动作节点,每个动作节点都会作为一个手动选择的选择项。连接示例如下:

行为树配置中代码逻辑如下:

2)外部选择传入选择方法:具体的外部传入选择的方式通常是由行为树执行逻辑或外部控制系统来提供,比如通过用户的键盘输入、UI 按钮或其他触发条件。这涉及到控制代码与用户的实时交互,即用户需要从外部传递一个值,如动作编号或标识符,来决定选择哪个动作节点。外部输入选择示例代码如下:(大概是这个逻辑,但具体实现代码不能完全参考下面这个)
# 假设我们有一个逻辑来根据玩家输入设置选择
if player_input == "Attack":
manual_selector_input = 0 # 假设 0 对应 Attack
elif player_input == "RunAway":
manual_selector_input = 1 # 假设 1 对应 RunAway
# 将这个输入值传递给 ManualSelector 来选择动作
manual_selector.set_input(manual_selector_input)
5. ReactiveFallback
(1)样式

(2)功能与执行逻辑:
ReactiveFallback节点的执行流程与Fallback相似,当节点被触发时,均会开始遍历其子节点,当子节点返回Success或Running时,会继续执行。二者的主要区别在于当子节点返回Failure时,ReactiveFallback有特殊的重试机制,具有更强的反应性以及更灵活的错误恢复。
传统的Fallback在子节点执行失败时只能切换至下一个子节点,而ReactiveFallback会立即重新尝试执行该子节点。这种机制使得行为树可以更加灵活地应对运行时的异常情况,提高了行为树的适应性和容错性。在Groot2中,若不进行另外配置,该节点的默认重试次数为无限次,但这样执行进程可能会在面对一个屡次重试始终返回失败状态的子节点时卡在同一个节点上而无法进行下去,影响行为树的执行。因此在使用该节点时一般需要在xml配置文件中配置ReactiveFallback的重试次数max_retries,配置代码示例如下:
<ReactiveFallback max_retries="3">
<-- 待执行的动作子节点 -->
</ReactiveFallback>
6. Sequence
(1)样式

(2)功能与执行逻辑
Sequence节点提供了一种串行执行的控制流,用于按照顺序执行一组子节点。节点执行逻辑遵循“成功时继续,失败时终止”的原则,会依次执行其子节点,直到所有子节点都成功执行才返回成功。如果某个子节点失败,Sequence会立即停止执行,并返回失败。
7. ReactiveSequence
(1)样式

(2)功能与执行逻辑
ReactiveSequence的整体执行逻辑与Sequence相同,均为当所有子节点返回成功时ReactiveSequence才返回成功,只要有一个子节点返回失败整体就返回失败。
但与传统Sequence节点相比,ReactiveSequence有较强的反应性与灵活的重试机制,即在一个节点失败后不会立即返回Failure,而会重新执行该子节点直到返回成功或重试次数达到上限后再返回失败。同样,若不另外配置重试次数,Groot2中的重试次数默认为无限次,为保证行为树的正常执行,一般需要在xml配置文件中配置重试次数,示例代码如下:
<ReactiveSequence max-retries="3">
<-- 待执行的动作子节点 -->
</ReactiveSequence>
8. SequenceStar
(1)样式

(2)功能
该节点主要用于处理 重复执行 的任务。它的功能与常规的Sequence节点类似,但是SequenceStar会不断地 重复执行子节点,即会在所有子节点成功后循环执行,直到满足某些条件或外部干预。它通常用于那些需要不断执行的任务,如循环检查、持续移动等。
(3)执行逻辑
与Sequence类似,SequenceStar同样采用顺序执行子节点,只有当前一个子节点返回成功,才会执行下一个节点。
而SequenceStar的特点在于其重复执行机制,即一旦所有子节点都成功执行,该节点会重新从第一个子节点开始循环执行。这一过程会持续进行直到某个子节点失败,导致SequenceStar停止执行并返回失败;或需要外部逻辑来强制停止循环(例如超时或手动中断)。
从以上描述中可以总结出该节点的失败逻辑:如果其中一个子节点失败,SequenceStar 会立即停止执行并返回失败,且在失败时不会继续执行后续节点。
9. Switch2 / Switch3 / Switch4 / Switch5 / Switch6
(1)样式

(2)功能
这类节点可以视为一种 条件分支 控制结构,根据不同的输入条件(输入的变量variable的值)来选择不同的执行路径。Switch2 / Switch3 / Switch4 / Switch5 / Switch6分别对应可以处理2/3/4/5/6个(不同数量)的条件分支,根据variable与case_n的等式判断条件是否成立,并执行成立的条件对应的动作节点。
(3)参数及填写说明
1)IN:case_n(case_1,case_2,case_3,...):这些参数用于定义分支条件。每个 case_n 表示一个 特定值,该值用于与 IN: variable 进行对比,判断某个条件是否成立。
2)IN:variable:variable变量是用于判断条件的变量。应该填入一个能够决定路径选择的 变量,通常是一个 整数或枚举(enum)类型的参数。该变量的值会被与 case_1, case_2, ..., case_n 中定义的条件进行对比,以决定哪个子节点会被执行。
(4)连接规则
应在SwitchN节点后面连接n个动作节点,分别对应case_n条件成立时对应需执行的行为。此外还有一个问题,即使用SwitchN进行分支条件的判断与行为执行时,我们需要的等式通常是黑板中的某个变量与常量之间的比较,也就涉及将黑板中的参数传入IN:variable中的问题。
根据Groot2的官方文档:
![]()
如果使用的不是Groot2的PRO版本(要花钱或获取license key),则无法通过黑板视图查看黑板中的参数内容,也无法直接通过参数的链接直接链到黑板中的参数。此时唯一能告诉行为树参数IN:variable处传入的是黑板中的参数的写法是:{参数名},这表明此处填入的是从黑板中获取的“参数名”对应的数值。填写示例如下:

对应的xml配置代码如下:

在这个示例中,当黑板中的参数game_progress的值满足等于1时,对应执行TurnHeadAction;当等于2时,对应执行SubscriptionNode。
10. WhileDoElse
(1)样式

(2)功能
WhileDoElse节点是一种循环节点,其主要功能是根据是否满足一定条件决定是否循环执行Do分支内的行为,或是在不满足条件时跳出Do分支而进入Else分支,但由于该节点未提供专门对应else分支的接口,因此条件不满足时将表现为结束Do分支中行为的循环执行,直接跳出该节点。
(3)连接规则
WhileDoElse下面只能连接两个节点,一个是条件节点,一个是动作节点,且连接顺序要严格遵守左条件右动作的顺序。连接示例如下:

对应的配置代码为:

其执行逻辑为:当条件节点ParameterCheck==true时,循环执行TurnHeadAction,否则直接结束、跳出。
注意:对于WhileDoElse节点是否能实现循环逻辑,目前无法确定,根据调试经验,这里的WhileDoElse可能并没有执行循环的功能,他跟IfThenElse的关系就类似Fallback与ReactiveFallback的关系,WhileDoElse也是增加了反应机制,但本质上仍然是IfThenElse的功能。
如果要实现循环的功能,建议使用Repeat(重复规定次数)或KeepRunningUntilFailure节点;如果涉及到行为中需要反复复用循环逻辑的情况,则建议直接写在行为节点的实现中。
四、Decorator装饰节点
1. BlackboardCheckBool
(1)样式

(2)功能
BlackboardCheckBool的功能是对黑板中存储的布尔值进行检查,通过比较黑板上的两个布尔值来决定是否执行其子节点。如果比较结果符合设定的条件(相等或不相等),则允许子节点继续执行;否则,子节点会被阻止执行。具体来说,它会检查黑板上两个值(value_A 和 value_B)的布尔状态,并根据设置的 return_on_mismatch 参数来决定节点状态。
(3)参数说明
1)IN: return_on_mismatch:该参数类型是布尔值,用于控制当 value_A 和 value_B 不匹配时节点的状态,参数可填写为SUCCESS或FAILURE。当设置为SUCCESS时,即使value_A 和 value_B 不相等,节点将仍然返回SUCCESS状态,但由于先判条件不成立,仍然不允许子节点执行。当设置为FAILURE时,value_A 和 value_B 不相等时节点状态返回FAILURE状态,子节点不会执行。注意要明确的一点是,无论这个参数设置为什么,只要value_A和value_B不相等,子节点都不会被执行,这个参数改变的只是当前节点返回的状态。
2)IN:value_A:该参数类型是布尔值,代表待检查的布尔变量,通常需要填入一个黑板变量,作为检查条件。填写格式为:{变量名},填写后变量显示深蓝色,即说明填入的是一个黑板中的变量。
3)IN:value_B:该参数类型是布尔值,代表待检查的另一个布尔变量,通常也需要填入一个黑板变量,作为检查条件。填写格式为:{变量名},填写后变量显示深蓝色,即说明填入的是一个黑板中的变量。
(4)节点连接准则
BlackboardCheckBool作为检查条件是否相等的装饰器,必须连接且仅能连接一个子节点。他下面通常会连接到一个实际的行为节点或条件节点,如ActionNode、ConditionNode 或 SequenceNode等类型的节点。有BlackboardCheckBool的控制,下面的节点不会直接被执行,而是根据黑板上的布尔值条件比较来决定是否继续执行其子节点。
下面是一个连接示例及其对应的xml配置代码示例:


该示例表示首先比较两个整型参数黑板变量game_progress与1是否相等。若相等,则执行下面的顺序结构,即当满足变量game_progress等于1时顺序执行AreaSelector和ChaseAction行为;若不相等,由于参数return_on_mismatch设置为SUCCESS,即使后面的顺序节点不会被执行,整个节点仍然返回SUCCESS状态,也就不会跳出前面的“KeepRunningUntilFailure”节点。
2. BlackboardCheckDouble
(1)样式

(2)说明
BlackboardCheckDouble节点的作用与BlackboardCheckBool完全相同,唯一区别是在条件检查中比较的两个参数(变量)的类型为double长浮点型。因此不进行重复的细节解释。
3. BlackboardCheckInt
(1)样式

(2)说明
BlackboardCheckInt节点的作用与BlackboardCheckBool完全相同,唯一区别是在条件检查中比较的两个参数(变量)的类型为int整型。因此不进行重复的细节解释。
4. BlackboardCheckString
(1)样式

(2)说明
BlackboardCheckString节点的作用与BlackboardCheckBool完全相同,唯一区别是在条件检查中比较的两个参数(变量)的类型为string字符串类型。因此不进行重复的细节解释。
注意:前面的BlackboardCheckBool、BlackboardCheckInt、BlackboardCheckDouble等参数检查节点只能检查黑板中特定参数的值与期望值是否相等,而无法比较参数值与期望值的大于、小于、大于等于、小于等于等关系。如果要实现多样的参数比较,那么需要自己编写一个集成的ParameterCheck参数比较条件节点。
5. Delay
(1)样式

(2)功能
Delay 节点的主要功能是用于创建延迟效果,控制任务执行的时间。该节点通常用于在行为树中实现一定的延时,其下游节点就会延迟执行。
(3)参数说明
IN:delay_msec:该节点只有这一个参数,用于设置延迟时间,时间单位为毫秒。
(4)连接规则
Delay节点上游父节点连接任何可能触发延时的行为,下游则应连接被延迟的行为。
6. ForceFailure
(1)样式

(2)功能
ForceFailure 节点的功能是强制该节点的子节点返回失败状态。具体来说,ForceFailure 节点不执行任何动作,而是直接让它子节点的执行结果为 Failure,除非子节点返回正在进行状态(RUNNING),这种情况下ForceFailure装饰器也会返回正在进行。这在一些需要控制行为树状态或令某行为强制失败的情况中有一定用处。
(3)连接规则
该节点的上游节点连接正常的行为树控制流,其下游节点则连接等待强制返回失败的子节点。连接示例及xml配置代码如下:


以上示例中ForceFailure下面连接的TurnHeadAction的执行状态将强制返回失败。
7. ForceSuccess
(1)样式

(2)说明:功能类型与ForceFailure相同,唯一区别在于ForceSuccess节点用于强制它的子节点返回成功状态。细节不做详述。
8. Inverter
(1)样式

(2)功能
Inverter 节点是一个逻辑反转节点,其功能是将输入节点的结果进行反转。也就是说,如果它的子节点(输入节点)执行成功(Success),Inverter 会将其结果反转为失败(Failure);如果子节点执行失败(Failure),Inverter 会将其结果反转为成功(Success)。该节点本质上是将行为树中状态的逻辑进行反转,用于在特定场景下改变节点的执行结果,实现“失败则成功”或“成功则失败”的特殊控制流。
(3)连接规则
上游节点连接:Inverter 节点的上游节点可以是条件节点(如果不满足条件则执行,或如果满足条件则不执行)或控制流节点,如选择节点、并行节点等,即连接的是等待被反转结果的节点。但注意,Inverter的上游节点不建议连接行为节点,因为行为节点本身已经基于实际情况作出了判断,反转并没有什么实际意义,甚至可能导致决策失误。
下游节点连接:Inverter节点的下游应该连接一个行为节点(且只能连接一个节点),其执行逻辑为,当Inverter对上游节点的反转结果为Success时,下游节点将被执行;而反转后的结果为Failure时下游节点不执行。
9. KeepRunningUntilFailure
(1)样式

(2)功能
KeepRunningUntilFailure 节点的作用是 持续执行其下游节点,直到该节点返回 Failure 状态。它将在每次更新时不断执行其子节点,并且一旦子节点返回 Failure,KeepRunningUntilFailure 会立即停止执行其子节点并返回 Failure。如果子节点返回 Success 或 Running,KeepRunningUntilFailure 会继续执行该子节点,直到收到 Failure 为止。
(3)连接规则
KeepRunningUntilFailure 节点上游连接正常的控制流节点,其上游节点本身与该节点的执行逻辑无关。
KeepRunningUntilFailure 节点下游连接的是需要持续执行直到失败的行为节点或条件节点。
这个节点在实现循环逻辑时比较理想。
10. Repeat
(1)样式

(2)功能
Repeat 节点是一个控制流节点,通常用于在行为树中重复执行其下游的子节点指定次数,直到达到预定的重复次数为止。
(3)参数填写说明
IN:num_cycles:该节点只有这个唯一的参数,参数表示行为的重复次数,应该填入一个整数以表示重复次数。
(4)连接的规则
该节点的上游可连接任何类型的控制流节点,本身与Repeat节点的执行逻辑并不相关。而该节点的下游节点则是连接等待被重复的行为节点(动作节点)。
11. RetryUntilSuccessful
(1)样式

(2)功能
RetryUntilSuccessful 节点是一个常用的控制流节点,主要用于重复地尝试执行下游的操作,直到该操作成功为止。当然,重复的次数不是毫无限制的,该节点提供了最大重试次数参数,以保证行为树的后续逻辑能够正常执行。
(3)参数说明
IN:num_attempts:该节点只提供了这唯一的参数,表示下游行为的最大重试次数,填写时应填入一个整数。
(4)连接规则
上游可正常连接任何控制流节点,其本质上与RetryUntilSuccessful 节点的执行逻辑没有关系。该节点的下游节点应是这步决策中希望重复尝试直至成功的行为节点。
12. Timeout
(1)样式

(2)功能
Timeout 节点是一个控制流节点,主要用于限制下游节点执行的最大时间,并确保该节点在指定的时间内完成。如果下游节点的执行时间超过设定的最大时间限制,Timeout 节点会停止下游节点的执行,并返回 Failure。
(3)参数填写说明
IN:msec:Timeout节点仅提供了该唯一参数,表示最大超时时间限制,单位为毫秒(ms),填写时应填入一个整数。
(4)连接规则
同样上游可正常连接任何控制流节点。而下游节点应连接需要设定动作执行时间限制的行为节点,如MoveTo,Attack,Patrol等带有明显时间限制特征的行为。
注意:使用超时节点一定要注意超时后要中断原行为执行逻辑。例如正在执行前往某一坐标点的行为时,由于障碍物阻挡而无法及时到达指定位置,一段时间后触发了超时节点,则执行树的指针会跳出当前的执行模块、执行超时后的下一步逻辑,但是行为树逻辑中断不代表行为中断,此时执行前往的行为节点可能因为检测到机器人未到达指定点而仍然在一直给机器人发送原坐标点。
此时我们需要及时在前往行为的执行逻辑中(针对行为代码,不是树的逻辑!)添加超时检测与及时中断,从而达到超时时树的逻辑与当前执行的行为都能及时中断的效果。
五、SubTree子树
Groot2未提供任何可直接引用的子树,但这里会存储人为编辑的所有树作为可用子树。在编辑主树时,可以拖动任一一棵树作为主树的子树。
此处附将某棵树设置为主执行树的方法:
首先右击Project栏你想设置为主树的树,如下:

点击“Set as ‘main_tree_to_execute’”,即可设置完成,设置后该树名称旁边将出现星标:
![]()
若想取消主树设置,则再次右击你想选择的树,点击“Remove ‘main_tree_to_execute’”即可:

六、节点添加准则
1. 动作节点添加准则
首先右键单击Models菜单Action栏,点击“Add Action Model”:

动作节点添加编辑界面如下:

首先在“Name”处填入该自定义动作节点的名称,如果这个动作节点执行过程中不涉及任何黑板中的参数,那么确认即可。
若涉及参数,点击参数栏左上角加号“+”添加参数。在“Port Name”处填入参数名称。在“Direction”处有三个选项——“Input”“Output”和“In/Out”,若该行为执行过程中只需要某参数的输入接口,则选择Input;若只需要输出接口,则选择Output;若同时涉及这个参数的输入与输出,则选择In/Out。
“Default Value”处填入参数默认值,“Description”处可以备注上该参数的一些描述说明,方便使用。设置完成后确认即可。
2. 条件节点添加准则
同样首先右键单击Models菜单Condition栏,点击“Add Condition Model”:

条件节点添加编辑界面如下:

编辑规则与动作节点完全一样,不再赘述。
与前两种节点基本类似,控制节点与装饰节点的添加中除了节点类型不同,其余待填参数均相同,因此根据前面的相同规则填入即可,不再赘述。
3. SubTree栏相关
如果右击SubTree一栏,并不会出现Add Tree Model选项,只有“Remove Orphans”选项,如下:

该选项的作用是删除孤立节点,即移除当前行为树中所有存在于树中但不与任何节点相连、没有实际参与到树的执行流程中的节点(孤立节点)。
更多推荐
所有评论(0)