AI邏輯實現-取舍行為樹還是狀態機


AI邏輯實現-選擇行為樹還是狀態機? 
關注AI的朋友可能會看過賴勇浩翻譯的《有限狀態機時代終結的10大理由》 ,里面談到了狀態機的諸多弊端。同時在ppt(附上下載地址)中述說了行為樹的諸多優點,這里就不在贅述了。更多得是想總結一下自己玩了一陣子行為樹后的一些實踐體會。

個人體會: 
狀態機來實現AI更符合我們思維的朴素表達,我想任何一個有經驗的coder都能直觀得去寫一個自己的AI狀態機。它用於一些簡單的ai其實是沒有大問題的,(搜索敵人,靠近,攻擊,死亡)用狀態機其實更加便捷。但是面對一些復雜的ai邏輯實現就會顯得比較繁雜。同時,當需要對現有行為邏輯進行擴展的時候,代碼上就會顯得比較吃力,因為要維護的狀態量會成倍增加。 
這里寫圖片描述 
行為樹,實現AI的過程更加得有技巧,框架設計者較為全面考慮了我們可能會遇到的種種情況,把每種情況都抽象成了一個類型的節點,而我們要做的就是按照規范去寫節點,然后把節點連接成一顆行為樹。更加得具有面向對象的味道,行為模塊間的藕合度相對較低。

舉個粗糙的例子來比較一下兩者的不同: 
AI行為:吃飯 睡覺 打豆豆(很消耗體力和腦力的;)

1.打豆豆 HP -= 5 / 秒 MP -= 3 / 秒 
2.吃飯 HP += 10/秒 MP -= 1 / 秒 
3.睡覺 MP += 15/秒 HP -= 2/秒 
4.吃飯和睡覺是不可打斷的動作(pending),必須執行到吃飽(HP = 100) or 睡飽(MP = 100) 
5.打豆豆是瞬發動作,每幀都可以執行一次

狀態機的實現邏輯圖: 
這里寫圖片描述 
行為樹的實現邏輯圖: 
這里寫圖片描述 
其實不管你知不知道什么是selector,condition都不要緊,至少從上圖,應該可以看出來,行為樹節點間的聯系並不像狀態機那樣得“緊密”。

選擇兩種不同的ai實現方法,也決定了具體行為的實現邏輯。 
比如對於sleep動作的實現,如果是狀態機: 
function sleep() = 
if Y == 100 then 
AwakeEvent() 
return 
end 
HP -= X 
MP += Y 
end 
然后每一幀執行sleep()

如果是選擇行為樹: 
function sleep() 
local sleepTime = (100/15) 
–不好意思亂入了一段cocos2dx的代碼 
self:runAction(cc.Sequence:create(cc.DelayTime:create(sleepTime),cc.CallFunc:create(cancelPending))) 
local cancelPending = function() 
pending = false 
end 
end

羅列一下行為樹的概念: 
對於有限狀態機而言,必須明確 狀態的轉換方式;對於行為樹,必須明確狀態前提:前提條件 
每一個行為必須有“前提條件” ,這決定了該行為是否被選擇。 
行為樹的運算也是通過幀循環的update來驅動,不一定是每幀都update,但是要周期性update。 
每一次run從根節點(root)開始,每一運行都會選擇一個可行的子節點運行,這種選擇可以是隨機方式,也可以是預設好優先條件 
行為樹由葉子節點和中間節點組成,葉子節點是最基本的行為(如跑動,攻擊),中間節點代表邏輯單元(巡邏,逃跑)。 
當一個葉子節點被選擇后,就會激活其對應的基本的行為 
最基本的行為可能執行成功也可能失敗。 
高等級的行為(中間節點)是否執行成功依賴於他們的孩子節點是否執行成功。 
一個子節點失敗可能導致父母節點選擇另外一個孩子。 
除了選擇(selector)一個單獨的子節點行為,一個節點還可能順序(sequence)or並行(concurrent)得運行他的所有子節點。 
一個行為除了有前提條件,可能還有上下文條件(父節點or孩子節點可能存儲一定的狀態變量)。 
高優先級的行為可能搶占低優先級的行為

轉載一段akara的行為樹實現方案:

  • Composite Node 組合節點
  • Decorator Node 裝飾節點
  • Condition Node 條件節點
  • Action Node 行為節點

各種節點的詳細描述: 
* Selector Node 選擇節點 
描述:從頭到尾,按順序選擇第一個執行條件為真的子節點,遇到True停止。 
處理流程:當執行本類型Node時,它將從begin到end迭代執行自己的Child Node:如遇到一個Child Node執行后返回True,那停止迭代,本Node向自己的Parent Node也返回True;否則所有Child Node都返回False,那本Node向自己的Parent Node返回False。

  • Sequence Node 序列節點 
    描述:從頭到尾,按順序執行每一個子節點,遇到False停止。 
    處理流程:當執行本類型Node時,它將從begin到end迭代執行自己的Child Node:如遇到一個Child Node執行后返回False,那停止迭代,本Node向自己的Parent Node也返回False;否則所有Child Node都返回True,那本Node向自己的Parent Node返回True。

  • Parallel Node 並行節點 
    描述:從頭到尾,平行執行它的所有子節點。 
    Parallel Selector Node: 有一個子節點True返回True,否則返回False。 
    Parallel Sequence Node: 有一個子節點False返回False,否則返回True。 
    Parallel Fall On All Node: 所有子節點False才返回False,否則返回True。 
    Parallel Succeed On All Node: 所有子節點True才返回True,否則返回False。 
    Parallel Hybird Node: 指定數量的子節點返回True或False后,才決定結果。

  • Decorator Node 裝飾節點 
    描述:裝飾節點一般用來作為額外的附加條件。例如,時間間隔控制,次數控制,頻率控制,結果取反,錯誤處理等。

  • Condition Node 條件節點 
    描述:顧名思義,就是對應條件的節點。

  • Action Node 行為節點 
    描述:顧名思義,就是用於完成某種動作的節點。

從代碼實現的角度來談下優缺點

優點: 
1. 行為邏輯和狀態數據分離,任何節點寫好以后可以反復利用 
2. 重用性高,可用通過重組不同的節點來實現不同的行為樹 
3. 呈線性的方式擴展,易於擴展 
4. 可配置,把工作交給designer 
5. 能夠勝任”AI” “掉寶”等等場景。

缺點: 
1. 每一幀都從root開始,有可能會訪問到所以的節點,相對State Machine消耗更多的cpu 
2. 任何一個簡單的操作都必須要使用節點

原文地址:http://blog.csdn.net/u011484013/article/details/52369313


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM