BehaviorTree.CPP行为树BT的队列节点(三)

Sequences(队列)

只要序列的所有子代返回SUCCESS,它便会对其进行Tick

如果有任何子级返回FAILURE,则序列中止。

当前,该框架提供三种节点:

  1. Sequence
  2. SequenceStar
  3. 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

该树表示计算机游戏中狙击手的行为。

image

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的频率超过预期。

image

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

image

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;

代码均为伪代码

原文

posted @ 2020-12-19 10:38  hokori  阅读(1328)  评论(0编辑  收藏  举报