上次提到了一些行爲樹的基本概念,包括行爲節點,控制節點(選擇,序列,並行),此次來更多,更深刻的討論行爲樹的一些東西,若是對行爲樹不是很瞭解,請參看這裏。 程序員
一. 關於選擇節點的討論 數據結構
咱們說過選擇節點的定義是經過判斷子節點的前提條件來選擇一個節點執行,這就牽涉到判斷順序的問題,是自左向右,仍是隨機選擇,或者其餘的一些規則等等,這樣就延伸出各類各樣的選擇節點。 dom
這些就是經常使用的選擇節點類型,咱們能夠根據須要,定義更多的選擇節點的選擇行爲,其實咱們能夠看到,不一樣的選擇行爲對於子節點前提的要求會有略微的不一樣,這是在咱們搭建行爲樹的時候須要注意的地方。 編輯器
二. 關於並行節點結束條件的討論 工具
咱們每一個節點都會有一個運行狀態,來表示當前行爲是否結束。對於控制節點來講,它的運行狀態就是其子節點的運行狀態,選擇節點和序列節點比較好處理,由於對於這兩種控制節點來講,每時刻,只會有一個子節點在運行,只要返回在運行的這個子節點的狀態便可。但對於並行節點來講,它同時刻會有多個子節點運行,那咱們如何來處理並行節點的運行狀態問題呢?通常有兩種: 測試
爲何要須要有節點的運行狀態呢? 優化
對於第二點,能夠舉個例子,好比咱們有一個行爲是「走到A點」,假設這個行爲是不可被打斷的,那當咱們在走向A點的過程當中,行爲樹的運行狀態就是「正在執行」,當到達A點時,行爲樹就返回「已完成」,這樣,對外部來講,當咱們看到行爲樹是「正在執行」的時候,咱們就不須要作任何新的行爲(爲了優化,或者爲了行爲抖動等等),當看到「已完成」的時候,咱們就能夠作新的決策或者行爲了。這樣一個運行狀態還有助於咱們檢測行爲樹的狀態,幫助調試。 google
三.關於具體實現的討論 spa
行爲樹的實現能夠有多種多樣,我這邊提出一些建議,通常來講,行爲樹每一個節點須要有進入(Enter),離開(Exit),運行(Execute)等部分,須要有行爲節點(ActionNode),控制節點(ControlNode),前提(Precondition)等基類,而後,還須要定義行爲樹的輸入(InputParam)和輸出(OutputParam),通常來講,咱們但願行爲樹是一個黑盒,也就是說,它僅依賴於預約義的輸入。輸入能夠是黑板(Blackboard),工做池(Working Memory)等等數據結構,輸出能夠是請求(Request),或者其餘自定義的數據結構,以下圖: 插件
代碼的話,就不寫了,由於blog沒有代碼插件,寫代碼效果不是很好,之後我會在TsiU裏面發佈一個行爲樹的庫的版本。
四.關於繪製和調試的討論
看到行爲樹的定義後,做爲程序員的直覺,咱們很天然的就會想到,這好像應該能作一個工具來輔助行爲樹的建立和調試,咱們能夠把預約義好的前提和節點,在一個可視化的編輯器裏搭建成行爲樹,而後再導出成數據給遊戲用。對於調試來講,咱們可讓工具和遊戲通訊,而後實時的檢測行爲樹的運行情況,好比當前在哪一個分支中等等。因爲行爲樹的邏輯是可見的,而且是靜態的,因此咱們看其選擇的路徑,咱們就能夠知道AI爲何會做出這樣的決策了。當我剛接觸到行爲樹的時候,就在想作這樣一個編輯器,但迫於項目壓力,一直沒有時間作(工做量仍是挺大的),有興趣,有時間的朋友,能夠考慮作一個。順便說一句,我如今對於行爲樹的搭建都是在代碼中完成的,雖然沒有數據驅動那麼「先進」,但經過宏定義,排版等方式,仍是能很是清晰的表示樹的總體結構。
關於行爲樹,我想這個系列就到這裏了。在使用行爲樹的過程當中,可能還會碰到這樣和那樣的問題,包括我本身在實踐中的一些經驗,我想就先不包括在這個系列裏了,之後再單獨拿出來聊,這個系列做爲行爲樹的入門,但願對你們有所幫助,歡迎指教和討論。