翻译自:https://www.behaviortree.dev
Sequences [序列]
A Sequence ticks all its children as long as they return SUCCESS. If any child returns FAILURE, the sequence is aborted. [只要返回 SUCCESS,Sequence 就会对它的所有子代tick。如果任何孩子返回 FAILURE,则序列被中止。]
Currently the framework provides three kinds of nodes: [目前该框架提供了三种节点:]
- Sequence [序列]
- SequenceStar [标记序列]
- ReactiveSequence [再激活序列]
They share the following rules: [他们共享以下规则:]
-
Before ticking the first child, the node status becomes RUNNING. [在tick第一个子节点之前,节点状态变为 RUNNING。]
-
If a child returns SUCCESS, it ticks the next child. [如果一个孩子返回 SUCCESS,它会tick下一个孩子。]
-
If the last child returns SUCCESS too, all the children are halted and the sequence returns SUCCESS. [如果最后一个孩子也返回 SUCCESS,则所有孩子都停止并且序列返回 SUCCESS。]
To understand how the three ControlNodes differ, refer to the following table: [要了解三个 ControlNode 有何不同,请参阅下表:]
Type of ControlNode | Child returns FAILURE | Child returns RUNNING |
---|---|---|
Sequence | Restart | Tick again |
ReactiveSequence | Restart | Restart |
SequenceStar | Tick again | Tick again |
-
“Restart” means that the entire sequence is restarted from the first child of the list. [“重新开始”意味着整个序列从列表的第一个孩子重新开始。]
-
“Tick again” means that the next time the sequence is ticked, the same child is ticked again. Previous sibling, which returned SUCCESS already, are not ticked again. [“再次tick”意味着下一次tick序列时,再次tick相同的孩子。已经返回 SUCCESS 的前一个兄弟不再tick。]
Sequence
This tree represents the behavior of a sniper in a computer game. [这棵树代表了电脑游戏中狙击手的行为。]
example “See the pseudocode”
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
This node is particularly useful to continuously check Conditions; but the user should also be careful when using asynchronous children, to be sure that they are not ticked more often that expected. [该节点对于连续检查条件特别有用;但是用户在使用异步子节点时也应该小心,以确保它们不会比预期的更频繁。]
Let’s take a look at another example: [让我们看另一个例子:]
ApproachEnemy
is an asynchronous action that returns RUNNING until it is, eventually, completed. [ApproachEnemy 是一个异步操作,它返回 RUNNING 直到最终完成。]
The condition isEnemyVisible
will be called many times and, if it becomes false (i,e, “FAILURE”), ApproachEnemy
is halted. [条件 isEnemyVisible 将被多次调用,如果它变为假(即“FAILURE”),则 ApproachEnemy 将停止。]
example “See the pseudocode”
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
Use this ControlNode when you don’t want to tick children again that already returned SUCCESS. [当您不想再次tick已返回 SUCCESS 的子项时,请使用此 ControlNode。]
Example:
This is a patrolling agent/robot that must visit locations A, B and C only once. If the action GoTo(B) fails, GoTo(A) will not be ticked again. [这是一个巡逻代理/机器人,必须只访问位置 A、B 和 C 一次。如果动作 GoTo(B) 失败,则不会再次tick GoTo(A)。]
On the other hand, isBatteryOK must be checked at every tick, for this reason its parent must be a ReactiveSequence
. [另一方面,isBatteryOK 必须在每次tick时检查,因此它的父级必须是 ReactiveSequence。]
example “See the pseudocode”
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;