BehaviorTree.CPP行为树BT的队列节点(三)
Sequences
(队列)
只要序列的所有子代返回SUCCESS,它便会对其进行Tick。
如果有任何子级返回FAILURE,则序列中止。
当前,该框架提供三种节点:
- Sequence
- SequenceStar
- ReactiveSequence
它们具有以下规则:
- 在
tick
第一个节点之前,节点状态为RUNNING
。 - 如果一个节点返回成功
SUCCESS
,将会tick
下一个节点。 - 如果最后一个节点也返回
SUCCESS
,所有的节点被暂停,并且序列返回SUCCESS
。
要了解三个ControlNode
有何不同,请参考下表:
Type of ControlNode | Child returns FAILURE | Child returns RUNNING |
---|---|---|
Sequence | Restart | Tick again |
ReactiveSequence | Restart | Restart |
SequenceStar | Tick again | Tick again |
“Restart”是指从列表的第一个子级开始重新启动整个序列。
“Tick again”是指下次对序列进行Tick
时,将再次对同一个孩子进行Tick
。 已经返回SUCCESS的先前的同级项不再被打勾。
Sequence
该树表示计算机游戏中狙击手的行为。
status = RUNNING;
// _index is a private member
while(_index < number_of_children)
{
child_status = child[_index]->tick();
if( child_status == SUCCESS ) {
_index++;
}
else if( child_status == RUNNING ) {
// keep same index
return RUNNING;
}
else if( child_status == FAILURE ) {
HaltAllChildren();
_index = 0;
return FAILURE;
}
}
// all the children returned success. Return SUCCESS too.
HaltAllChildren();
_index = 0;
return SUCCESS;
ReactiveSequence
该节点对于连续检查条件特别有用;但是用户在使用异步子级时也应小心,确保它们不会被tick
的频率超过预期。
ApproachEnemy
是一个异步操作,返回RUNNING
直到最终完成。
条件isEnemyVisible
将被调用很多次,并且如果条件为False
(即“失败”),则ApproachEnemy
被暂停。
status = RUNNING;
for (int index=0; index < number_of_children; index++)
{
child_status = child[index]->tick();
if( child_status == RUNNING ) {
return RUNNING;
}
else if( child_status == FAILURE ) {
HaltAllChildren();
return FAILURE;
}
}
// all the children returned success. Return SUCCESS too.
HaltAllChildren();
return SUCCESS;
SequenceStar
当您不想再次tick
已经返回SUCCESS
的子节点时,请使用此ControlNode:SequenceStar
。
范例:
这是巡逻代理/机器人,只能访问位置A,B和C一次。如果动作GoTo(B)
失败,GoTo(A)
将不再被勾选。
另一方面,必须在每个刻度上都检查isBatteryOK
,因此其父级必须为ReactiveSequence
。
status = RUNNING;
// _index is a private member
while( index < number_of_children)
{
child_status = child[index]->tick();
if( child_status == SUCCESS ) {
_index++;
}
else if( child_status == RUNNING ||
child_status == FAILURE )
{
// keep same index
return child_status;
}
}
// all the children returned success. Return SUCCESS too.
HaltAllChildren();
_index = 0;
return SUCCESS;
代码均为伪代码