Unity BehaviorDesigner的Conditional Abort机制解读

发表于2018-03-06
评论1 5.9k浏览
Conditional Abort 机制
译文:
Conditional Abort允许你的行为树,动态的响应变化,而不是通过各种中断,搞的你的树乱七八糟。
很多行为树,都会在每帧重新评估整颗树。ConditionAbort是一个优化算法,让你不必每次返回整颗树。

如下图:

当这棵树运行的时候,Conditional会返回Success,然后Sequence会执行下一个子节点,Wait。
Wait节点会等待10秒钟。
当Wait节点正在运行的时候,假定Condition发生了变化,Conditional节点返回了Failure。
如果Condtional Abort被激活,那么Conditional节点会发起一个abort,并且中断wait的执行。
Condtional Abort可以被任何的组合节点获取。

我的解读:
Conditional Abort,只能由条件节点发起,这是因为只有条件节点会判断当前条件,并且在条件变化时,发起中断信息,终止一个正在Runing的节点。
那么再次解读一下:
  1. 存在 Conditonal 节点
  2. 存在Action节点,并且这个节点不是立刻返回,而是需要返回 Runing的。
  3. Action的节点的运行,依赖于Conditional节点的返回值,返回True才能运行。
  4. 当条件变化时,Conditional节点返回一个abort请求
  5. 那么谁来捕获这个Conditional变化呢?可以是任意的Composite节点。比如Conditonal的父节点,或者是Conditional父节点的兄弟节点。
  6. 当捕获到Abort之后干什么呢?中断当前running的节点,从新评估整颗树。
  7. 好处是什么呢?每帧只需要重新评估,带有Abort机制的Composite节点下面的Conditional节点,并且重新计算Conditional节点,来决定后面的节点如何运行,而不必每帧重新评估整颗树。

然后我们再来看看几种中断类型。
None,
不会中断,一旦Wait开始运行,他就必须傻了吧唧的运行完10秒钟,哪怕期间条件变化了。
比如,你发现周围没人,决定休息10秒,然后敌人来了,你还在休息,敌人把毫无反抗的你给啪啪啪了。

Self,
Conditional和Action必须拥有相同的父节点(孙子也算)
你刚决定休息,休息了不到1秒,敌人来了。你决定中断休息这个行为,开始做点什么,而不是坐以待毙。

Lower Priority,
行为树,越靠左边,优先级越高,越靠右边,优先级越低。Lower Priority意义在于
当一个高优先级的Condiontal发生变化,他可以中断一个低优先级的行为。注意同级的是不能被中断的。

假设一个AI包含有 回避 攻击 休息四个模块
  1. 你正在攻击,这时候有人朝你开枪了,回避模块发现了这个问题,要求你先保命,于是中断了你的攻击行为。
  2. 而如果你正在回避,这时候回避模块发生了变化——攻击你的人死了——他不会中断你当前的回避行为。

Both
综合Self和Lower Priority
  1. 你正在攻击,这时候有人朝你开枪了,回避模块发现了这个问题,要求你先保命,于是中断了你的攻击行为。
  2. 而如果你正在回避,这时候回避模块发生了变化——攻击你的人死了——那你还回避干屁,于是回避行为也终止了。

最后在总结一下干货:
Conditional Abort由 Conditonal节点发起,由Composite节点截获,并决定是否要abort。
如果决定Abort,会从发起Abort的节点开始,重新评估。

Self是只同根的节点
而Lower 节点,则是指,和发起Abort的父节点(Composite)相对而言,是低优先级的节点。
Abort Type是指,针对当前正在Runing的节点,相对而言,我有没有权利去中断他。
例如,Self是不允许你去中断一个,非同根父节点的Action的Running状态的。

Conditional Abort条件是可以嵌套的,如下图:
当能看见,和能听见,任何一个节点返回True的时候,将执行Action。
一个恰当的栗子,比如,一个守卫,当他看见敌人,或者听到异常声音的时候,他会开始巡逻一圈。

Selector被设置成LowerPriority,这样,当条件变化时,可以中断巡逻
比如敌人不见踪影,也没了声音,守卫开始怀疑自己是不是幻听幻视了。

Sequence被设置成LowerPriority,是希望Selector被重新评估时,他可以中断其他节点上正在运行的动作。
比如,现在CanSee和HanHear都是返回False的,因此巡逻Action是不执行的。
再假设Sequence的兄弟节点,有个抽烟的动作正在Runing。

这时候风吹草动了,如果Sequence是Self而不是LowerPriority的话。那么即使人物正在抽烟,他也不会开始巡逻。
这里LowerPriority改成Both也是可以的,虽然这并没有多大意义。

而Selector,如果他没有被设置为Both或者LowerPriority,那么这两个条件,根本不会被重新评估,自然中断也就无法进行了。
来自:http://blog.csdn.net/wanghaodiablo/article/details/54906847

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: