Unity BehaviorDesigner BehaviorTree 的Conditional Abort機制解讀

之前寫的博客,留了一個坑,今天把坑填了。


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,那麼這兩個條件,根本不會被重新評估,自然中斷也就無法進行了。


發佈了54 篇原創文章 · 獲贊 50 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章