本文档描述的是3.6.34及以后版本,对于3.5及以前的老版本请参考分类“3.5”。

并行节点用于一般意义上并行的执行所有子节点,相关的功能和属性说明详见手册《并行节点》。

并行节点容易在其属性配置上产生误用,本文将结合行为树中对并行节点的实际使用来加以说明。

1. 首先创建Agent子类“FirstAgent”及其成员属性p1和成员方法Say(behaviac::string& value, bool isLatent),Say()方法用于打印指定的参数,如下图所示:

Say()方法表示对于isLatent为真的情况,在第三帧后返回成功,前两帧返回正在执行;而对于isLatent为假的情况,在第一帧就直接返回成功,其实现代码如下所示:

behaviac::EBTStatus FirstAgent::Say(behaviac::string& value, bool isLatent)
{
///<<< BEGIN WRITING YOUR CODE Say
    if (isLatent && behaviac::Workspace::GetInstance()->GetFrameSinceStartup() < 3)
    {
        printf("\n%s [Running]\n\n", value.c_str());

        return behaviac::BT_RUNNING;
    }

    printf("\n%s [Success]\n\n", value.c_str());

    return behaviac::BT_SUCCESS;
///<<< END WRITING YOUR CODE
}

其中,当前帧数在主循环代码中每帧进行累加,如下代码所示:

void UpdateLoop()
{
    LOGI("UpdateLoop\n");

    behaviac::Workspace::GetInstance()->SetFrameSinceStartup(0);

    behaviac::EBTStatus status = behaviac::BT_RUNNING;

    while (status == behaviac::BT_RUNNING)
    {
        behaviac::Workspace::GetInstance()->SetFrameSinceStartup(behaviac::Workspace::GetInstance()->GetFrameSinceStartup() + 1);

        LOGI("frame %d\n", behaviac::Workspace::GetInstance()->GetFrameSinceStartup());

        status = g_FirstAgent->btexec();
    }
}

2. 创建行为树“ParallelBT”,其中并行节点有3个子节点,第一个是条件节点,第二和三个都是动作节点,如下图所示:

3. 该并行节点的的属性默认配置如下图所示:

  • 失败条件:FAIL_ON_ONE表示一个子节点返回失败,那么并行节点就返回失败。
  • 成功条件:SUCCEED_ON_ALL表示所有子节点都返回成功,并行节点才返回成功。这里需要注意,失败条件优先于成功条件。
  • 子节点结束继续条件:CHILDFINISH_LOOP表示子节点结束后会重新再循环执行。
  • 退出行为:EXIT_ABORT_RUNNINGSIBLINGS表示当并行节点的成功或失败条件满足并返回成功或失败后,会终止掉其他还在运行的子节点。

4. 执行该行为树,结果如下图所示:

5. 将并行节点的属性“子节点结束继续条件”改为CHILDFINISH_ONCE,表示子节点结束后不再执行(除非重入该并行节点),如下图所示:

6. 再执行该行为树,结果如下图所示:

从上图可以看到,虽然一共循环了3次,但ID为7的动作节点只执行了一次,而ID为0的动作节点由于前两帧执行时返回Running,得到持续执行,直到第三帧返回Success或Failure。

7. 将并行节点的属性“失败条件”改为FAIL_ON_ALL,并将“成功条件”改为SUCCEED_ON_ONE,如下图所示:

8. 再执行该行为树,结果如下图所示:

从上图可以看到,一共循环了1次,并行节点的所有子节点也都执行了1次。

本教程相关的工作区和代码工程详见源码包的目录tutorials/tutorial_12

发表评论

电子邮件地址不会被公开。 必填项已用*标注