行為樹 behavior3go

參考
游戲AI - 行為樹Part1:簡介
游戲AI - 行為樹Part2:框架
https://github.com/f15gdsy/BT-Framework
http://www.u77.com/game/3067

一、有限狀態(tài)機

游戲中的AI,大多數(shù)都是按照規(guī)則設(shè)定好的,沒有太多花哨的技術(shù)。原因有幾個:

  • 一是出于風險成本的考慮,用一個新技術(shù),需要程序員開發(fā)相應(yīng)的算法和框架,游戲設(shè)計師重新上手設(shè)計方法和摸索算法的適用范圍,小團隊承受不起這樣的開銷,大團隊又怕做壞名聲;
  • 二是“高級”的AI算法并不直觀,難以設(shè)計。舉一個例子,怎么利用神經(jīng)網(wǎng)絡(luò)來訓練一個士兵AI?我見過的一個例子是設(shè)計師用幾個按鍵來操作士兵移動攻擊,然后程序自動記錄敵我雙方的數(shù)據(jù)和設(shè)計師的操作,最后利用這些信息作為input構(gòu)建一個行為樹。這個方法的問題有三個,一是效率奇慢,因為如果數(shù)據(jù)不夠,行為樹就可能覆蓋不了所有情況,但多少才是“夠”,又沒有定論;二是錯誤的操作也會被記錄下來,當然可以開發(fā)一個功能來刪除設(shè)計師的某個動作;三是行為樹的結(jié)果是無法解釋的,相當于一個黑箱。

由于上述的原因,一般的公司都會使用比較傳統(tǒng)的有限狀態(tài)機。

雖然第一次聽的話可能會拗口,其實有限狀態(tài)機的意思其實很簡單,它包含了有限個的狀態(tài)和狀態(tài)間的轉(zhuǎn)換條件。最直白的說法就是幾個if...else...語句。為了弄明白這個概念,我們講一個英雄的故事:

從前有一個膽小如鼠的英雄,

  • 他看到哥布林就會跑過去打它;
  • 他看到半獸人就會逃跑;
  • 他看不到哥布林也看不到半獸人就會休息;
  • 他看到哥布林也看到半獸人也會跑。

我們可以從中抽象出這樣的一個有限狀態(tài)機:


image.png

有限狀態(tài)機很符合我們的認知,但它有一個致命的缺點——它隨著狀態(tài)和轉(zhuǎn)換條件的增多而急速地變得錯綜復雜,以至于很難對它做出改動(想象一下,多加一個狀態(tài),則需要增加幾條轉(zhuǎn)換線,越多狀態(tài),需要增加的轉(zhuǎn)換線越多)。也由于這個原因,比較多的開發(fā)者投入了行為樹的懷抱。

二、行為樹

行為樹的概念會比狀態(tài)機要復雜些——行為樹是一個包含邏輯節(jié)點和行為節(jié)點的樹結(jié)構(gòu),每次需要找出一個行為的時候,會從樹的根節(jié)點出發(fā),遍歷各個節(jié)點,找出第一個和當前數(shù)據(jù)相符合的行為。很拗口對吧,下面來一個生動點的解釋,繼續(xù)上面的英雄的故事,但是是用行為樹表達出來:


image.png

這個行為樹是等價于之前的有限狀態(tài)機的。其中Root是根節(jié)點,每次需要尋找行為的時候都必須從這里開始。

Priority Selector是一個邏輯節(jié)點,它的意思是從左到右遍歷自己的子節(jié)點,如果子節(jié)點的準入條件符合信息的話,就執(zhí)行該子節(jié)點。如果英雄只看到哥布林,那么Orc in sight這個準入條件不符合,Escape不執(zhí)行;Globlin in sight符合,于是執(zhí)行Fight;因為Fight在Idle的左邊,所以Fight的優(yōu)先程度更高,于是Idle不執(zhí)行。在我們的例子中,Idle可以看作是default behavior。

1.優(yōu)點

從簡單的行為樹和有限狀態(tài)機的對比,我們就可以看出,行為樹由于引入了邏輯節(jié)點,它的轉(zhuǎn)換條件更加少(線更少,更清晰),讓拓展AI變得更加容易。行為樹還有另外一個優(yōu)點:行為的重用(reuse)。例如,Escape有一個跑的行為,而Fight則有跑的行為,和砍怪的行為。請看圖:


image.png

Sequence同樣是一個邏輯節(jié)點,它的意思是從左到右按順序執(zhí)行子節(jié)點,并且僅僅在一個子節(jié)點執(zhí)行完成后才執(zhí)行下一個子節(jié)點。在例子中,Do Run需要有一個自己判斷到達目的地的方法,當該方法返回end的時候,才會執(zhí)行Do Slash。

Escape和Fight的Do Run行為節(jié)點是一樣的,只是Fight多了一個Do Slash行為節(jié)點而已。所以Do Run是一個可以重用的節(jié)點。在行為樹中,我們能夠編寫好Do Run,Do Slash這些基礎(chǔ)的行為節(jié)點,和設(shè)定一些準入條件,就可以組成千變?nèi)f化的AI了!

我們希望英雄在逃跑的時候群眾發(fā)出噓聲,而在攻擊的時候出現(xiàn)歡呼聲:


image.png

省略了其他部分,只畫Escape部分。Parallel是一個邏輯節(jié)點,它的意思是讓所有子節(jié)點同時運行,那它什么時候結(jié)束呢,可以使當所有子節(jié)點都完成的時候結(jié)束,也可以讓任一子節(jié)點完成時結(jié)束,視乎需要來做出選擇。那么在攻擊當中會是怎么樣實現(xiàn)的呢?大家可以嘗試畫出來,習慣一下行為樹的思維方式。

三、行為樹關(guān)鍵詞

在展開之前,我們先定義幾個關(guān)鍵詞(基本都以BT作為前綴...是Behavior Tree之意,別誤會了...),會在下面的框架用到。

BTNode:所有節(jié)點的base class。定義了一些節(jié)點的基本功能,并提供一些可繼承的函數(shù)。

BTAction:行為節(jié)點,繼承于BTNode。具體的游戲邏輯應(yīng)該放在這個節(jié)點里面。

BTPrecondition:節(jié)點的準入條件,每一個BTNode都會有一個。具體的游戲邏輯判斷可以繼承于它。

BTPrioritySelector:Priority Selector邏輯節(jié)點,繼承于BTNode。每次執(zhí)行,先有序地遍歷子節(jié)點,然后執(zhí)行符合準入條件的第一個子結(jié)點??梢钥醋魇歉鶕?jù)條件來選擇一個子結(jié)點的選擇器

BTSequence:Sequence邏輯節(jié)點,繼承于BTNode。每次執(zhí)行,有序地執(zhí)行各個子結(jié)點,當一個子結(jié)點結(jié)束后才執(zhí)行下一個。嚴格按照節(jié)點A、B、C的順序執(zhí)行,當最后的行為C結(jié)束后,BTSequence結(jié)束。

BTParallel:Parallel邏輯節(jié)點,繼承于BTNode。同時執(zhí)行各個子結(jié)點。每當任一子結(jié)點的準入條件失敗,它就不會執(zhí)行。

BTParallelFlexible:Parallel的一個變異,繼承于BTNode。同時執(zhí)行各個子節(jié)點。當所有子結(jié)點的準入條件都失敗,它就不會執(zhí)行。

BTTree:將所有節(jié)點組合起來的地方。

Database黑板,一個存放共享數(shù)據(jù)的地方,可以看成是一個Key-Value的字典。為什么需要黑板呢?因為設(shè)計良好的行為邏輯,應(yīng)該是獨立的,可以在行為樹的任何位置部署的。也就是說行為A和行為B并沒有直接的溝通方法。黑板的作用就是作為一個行為樹的“數(shù)據(jù)庫”,讓各個行為節(jié)點都可以儲存數(shù)據(jù)進去,供感興趣的行為節(jié)點利用。(同時,在Unity3d的語境下,Database繼承MonoBehavior,可以提供各種Component給節(jié)點使用。)

UML類圖:


image.png
四、行為樹對于游戲的意義

如果沒有可視化的編輯工具,如果沒有artist能接手AI編輯,那么行為樹的效果將大打折扣。因為行為樹將耦合降低之后,如果沒有可視化的編輯器調(diào)試工具,那么后人維護擴展這個模塊的效率是很低的。比較明顯的一點就是,調(diào)試BUG的時候,需要整個流程,各個可能會激活的節(jié)點都斷好點,不然無法弄清整個流程。變成一段我最不希望看到的,只有調(diào)試才能知道結(jié)果的代碼。所以這個成本需要設(shè)計人員仔細斟酌,如果要采用沒有編輯器的行為樹,應(yīng)該怎么簡化,怎么控制,且要想清楚對自己的游戲來說劃不劃算。
.
從業(yè)這幾年來,面過的人中,大多都知道或者用過行為樹。但當我詢問行為樹或者準確的說行為樹的這種解決問題的思想,還能用在哪些地方的時候,大多答不上來,幾乎都局限于做游戲AI。其實“行為樹”(引號標注此處不特指行為樹,而是行為樹背后所包含的設(shè)計思想)對游戲的很多其他模塊,都有借鑒的地方。游戲中復用情況較多、修改變化頻繁的模塊,都可以用上“行為樹”。比如我們的新手引導模塊,MMORPG的任務(wù)模塊等,都可以用到“行為樹”,來幫我們管控變化,加速模塊的構(gòu)建與迭代。

五、Tencent/behaviac
  • behaviac是游戲AI的開發(fā)框架組件,也是游戲原型的快速設(shè)計工具
  • 支持行為樹BT,狀態(tài)機FSM,HTN等多種范式
  • 方便的編輯,實時和離線調(diào)試
  • 支持全平臺,適用于客戶端和服務(wù)器,助力游戲快速迭代開發(fā)
  • 官方網(wǎng)站是文檔,教程,API,F(xiàn)AQ,源碼,下載等一切的入口
  • 您可以加入我們的QQ群433547396獲得即時的幫助或者信息反饋。
六、magicsea behavior3go

golang behavior tree,from https://github.com/behavior3

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容