使用AI行爲樹開發任務系統

·本篇日誌是http://gad.qq.com/article/detail/39709的後續擴展日誌,感謝AI分享站的啓發。


任務系統在遊戲開發過程當中伴隨着DEMO版本一直修改到RELEASE版本,無時無刻都在修改,時刻反覆經受着策劃和運營的折磨。無數的慘痛教訓使我痛定思痛,放棄傳統的硬編碼方式轉而尋求一種動態的實現方式,一種設計優秀的任務系統在這個過程當中能讓程序員獨善其身,任憑風浪起,穩坐釣魚船。這就是我想說的行爲樹任務設計思想。
 
下面咱們來簡單描述一下任務系統,任務系統通常能夠分紅這3個部分
·可執行任務的條件,例如:角色等級,職業限制等等。這部分在detect中斷定
·任務執行過程當中的細節,此處能拆分出若干項行爲
·任務的完成條件,有些任務是服務器判斷完成條件的(殺怪等), 有些是客戶端判斷完成條件的(和NPC完成一次對話等)
 
任務能夠拆分出的各類細節,每個能夠抽象成行爲樹的行爲節點,這樣根據任務的具體細節設計出一棵行爲樹。各個行爲節點中的內嵌腳本能夠交於策劃填寫具體的邏輯。程序部分的工做主要是實現角色的基本邏輯單元以及一些黑板功能,邏輯單元之間的組合交織就經過腳本實現。本來繁雜易修改的邏輯脫離出硬編碼方式,這樣的好處顯而易見了。
 
咱們看一下這個簡單的例子:
有一個簡單的任務:尋找NPC,而後和NPC對話至完成對話,並完成該任務
 
這個任務的具體細節有3步,第一步:尋路找到地圖上的NPC,第二步:與該NPC對話,第三步:完成對話。這3步之間的執行順序是依次前後執行的,所以咱們設計出這棵行爲樹結構以下圖:
 
這個任務的3步細節能夠放在這棵樹的三個順序執行節點上,以此執行。
第一步尋路至NPC的XLUA腳本以下
--[[
    基本信息:Name:Run2Npc Type:ACTION Weight:1
--]]
--進入條件檢測
function detect()
    return true
end
--進入調用
function enter()
    self.UserData:Run2Npc(self.UserData.Task.TargetNpc)
end
--每隔dt秒更新
function update(dt)
end
--事件監聽
function trigger(type,obj)
    if type=="MoveFinish"
        self:Break()
end
--退出調用
function exit()
end
這個腳本執行了角色在地圖上尋找該NPC的操做,注意這一個行爲是個持續性的動做,在trigger方法中監聽了外部事件「MoveFinish」即角色尋路完成的事件,在腳本監聽到事件以後尋路NPC的行爲完成,轉而執行接下來的行爲,接下來就是第二步。
--[[
    基本信息:Name:ShowDialog Type:ACTION Weight:1
--]]
--進入條件檢測
function detect()
    return true
end
--進入調用
function enter()
    self.UserData:ShowDialog(self.UserData.Task.Msg)
end
--每隔dt秒更新
function update(dt)
end
--事件監聽
function trigger(type,obj)
    if type=="DialogFinish"
        self:Break();
end
--退出調用
function exit()
end
第二步的腳本做用是打開與該NPC對話的邏輯,一樣的須要監聽DialogFinish事件,最後是第三步完成對話
--[[
    基本信息:Name:TaskFinish Type:ACTION Weight:1
--]]
--進入條件檢測
function detect()
    return true
end
--進入調用
function enter()
    self.UserData:NotifyServer(self.UserData.Task.ID)
    self:Break();
end
--每隔dt秒更新
function update(dt)
end
--事件監聽
function trigger(type,obj)
end
--退出調用
function exit()
end

NotifyServer方法是和服務器定義的通知消息,做用是告知服務器這個任務已經作完,服務器得知消息後處理後續的遊戲邏輯。程序員

 
這樣整個簡單的任務流程就走完了,經過行爲樹的設計方式實現任務系統,能夠說是很是簡潔易維護的。行爲樹任務系統在遇到很是複雜的任務細節時依然可以清晰的表達出來,關鍵之處在於任務細節能經過了行爲節點很好的抽象封裝起來。
相關文章
相關標籤/搜索