01 作用

条件中止能够让行为树动态响应变化。使用 Interrupt/Perform tasks 也能实现,但是会降低行为树的可读性。这个功能有点像 UE4 中的 Oserver Aborts。大多数行为树会在每个 tick 重新评估整个行为树,条件中止能够避免这点,只需重新评估条件(Conditional)task。
image.png
如上图,当 Conditional task 返回 success 时,Sequence task 会执行 Wait task。Wait task 的功能是等待 10 秒,如果在等待过程中,Conditional task 的状态变成了 failure,则:

  • Sequence 没有配置条件中止:等待 Wait task 的等待 10 秒执行完,再重新评估
  • Sequence 配置了条件中止:Conditional task 被重新评估,然后发起一个中止,立即中止 Wait task 的执行

任何组合(Composite)类型的 task 都可以配置条件中止。

注意:发起中止的条件是 Conditional task 状态的改变。上面举的例子是 Conditional task 从 success 变成了 failure。如果 Conditional task 从 failure 变成了 success,也会被重新评估,并发起中止。

Conditional task 在被重新评估时,标记如下所示:
image.png

02 类型

上例中,Sequence 将 Abort Type 配置为 Self 类型,如图:
image.png
条件中止有四种类型:

None
image.png
Conditional task 不会被重新评估,不会发起中止
Self
image.png
当 Conditional task 父节点下,有 task 处于激活状态时,则重新评估当前组合节点。此时 Conditional task 能够中止相同父节点下的其他 tasks
Lower Priority
image.png
**当 Conditional task 父节点的右侧,有分支处于激活状态时,则重新评估当前组合节点。此时 Conditional task 能够中止父节点右侧(优先级更低)的 tasks

| Both
image.png
Self 和 Lower Priority 的结合** |

03 嵌套

image.png
条件中止可以嵌套,如上图。

Selector 的状态由 Can See Object 和 Can Hear Object 两个 Conditional task 决定,只要有一个 task 返回 success,Selector 的状态就是 success。所以这里的 Selector 可以看做是一个复合的 Conditional task。

而我们希望当 Sequence 下的 Conditional task 状态有变化时,进行重新评估,并中止 Sequence 右侧的其他分支。因此 Sequence 需要配置 Low Priority 类型的条件中止。

然而虽然说“这里的 Selector 可以看做是一个复合的 Conditional task”,但它并不是。因此如果仅仅给 Sequence 配置条件中止,不会起任何作用。因此 Selector 也需要配置 Low Priority(或 Both)类型的条件中止。于是,当 Can See Object 和 Can Hear Object 的状态有变化时,Selector 会发起重新评估,如果状态有变化,会发起针对 Action 的条件中止;同时触发 Sequence 的重新评估,进而发起针对 Sequence 右侧的其他分支的条件中止。(以上是根据官方文档,自己总结的。官方文档说的没有这么清楚)