Unity BehaviorDesigner的Conditional Abort机制解读
发表于2018-03-06
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的节点。
那么再次解读一下:
- 存在 Conditonal 节点
- 存在Action节点,并且这个节点不是立刻返回,而是需要返回 Runing的。
- Action的节点的运行,依赖于Conditional节点的返回值,返回True才能运行。
- 当条件变化时,Conditional节点返回一个abort请求
- 那么谁来捕获这个Conditional变化呢?可以是任意的Composite节点。比如Conditonal的父节点,或者是Conditional父节点的兄弟节点。
- 当捕获到Abort之后干什么呢?中断当前running的节点,从新评估整颗树。
- 好处是什么呢?每帧只需要重新评估,带有Abort机制的Composite节点下面的Conditional节点,并且重新计算Conditional节点,来决定后面的节点如何运行,而不必每帧重新评估整颗树。
然后我们再来看看几种中断类型。
None,
不会中断,一旦Wait开始运行,他就必须傻了吧唧的运行完10秒钟,哪怕期间条件变化了。
比如,你发现周围没人,决定休息10秒,然后敌人来了,你还在休息,敌人把毫无反抗的你给啪啪啪了。
Self,
Conditional和Action必须拥有相同的父节点(孙子也算)
你刚决定休息,休息了不到1秒,敌人来了。你决定中断休息这个行为,开始做点什么,而不是坐以待毙。
Lower Priority,
行为树,越靠左边,优先级越高,越靠右边,优先级越低。Lower Priority意义在于
当一个高优先级的Condiontal发生变化,他可以中断一个低优先级的行为。注意同级的是不能被中断的。
假设一个AI包含有 回避 攻击 休息四个模块
- 你正在攻击,这时候有人朝你开枪了,回避模块发现了这个问题,要求你先保命,于是中断了你的攻击行为。
- 而如果你正在回避,这时候回避模块发生了变化——攻击你的人死了——他不会中断你当前的回避行为。
Both
综合Self和Lower Priority
- 你正在攻击,这时候有人朝你开枪了,回避模块发现了这个问题,要求你先保命,于是中断了你的攻击行为。
- 而如果你正在回避,这时候回避模块发生了变化——攻击你的人死了——那你还回避干屁,于是回避行为也终止了。
最后在总结一下干货:
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