1. 程式人生 > >AI 狀態機機制(虛幻三的做法)

AI 狀態機機制(虛幻三的做法)

調用 設有 mode 作用 self 信息 怪物 測試 pat

1.Nav Mesh Bounds Volume (Navigate導航,操縱)指的是可以導航(操作)的區域。

2.MVC的編程模式:(Model(模型)是應用程序中用於處理應用程序數據邏輯的部分。
  通常模型對象負責在數據庫中存取數據。

View(視圖)是應用程序中處理數據顯示的部分。
  通常視圖是依據模型數據創建的。

Controller(控制器)是應用程序中處理用戶交互的部分。
  通常控制器負責從視圖讀取數據,控制用戶輸入,並向模型發送數據。

MVC 分層有助於管理復雜的應用程序,因為您可以在一個時間內專門關註一個方面。例如,您可以在不依賴業務邏輯的情況下專註於視圖設計。同時也讓應用程序的測試更加容易。

MVC 分層同時也簡化了分組開發。不同的開發人員可同時開發視圖、控制器邏輯和業務邏輯。

3.創建一個Character命名為Enemy,將Mesh導入並添加至Character。調整位置和角度。

4.根據MVC思想,現在要創建一個Controller來寫入處理程序,當然,程序中的需要的數據還是要來自於View中,也就是Character的藍圖中。這裏為了方便就創建一個專門用於控制AI的控制器,AIController(BlueprintsClass)是Controller的子類。

5.接下來就要將控制器付給Character了,在self中找到Pawn中選擇AI Controller Class更改為剛剛創建的Aicontroller.

6.要對AIController寫入邏輯了,這裏設想一下分別有四種狀態,Patrol(巡邏),Chase(追捕),Attack(攻擊),Back(返回)。因為都是狀態,所以可以考慮將其寫成枚舉,通過SwitchOn來執行事件。

7.在Controller中創建一個枚舉變量,類型就是剛創建的枚舉,直接通過SwitchOn來控制函數,將每一種狀態都寫成一種函數,(這是大體的架構,內容一步一步寫)。默認是先進行第一個狀態(Patrol)通過改變枚舉來進行狀態的切換。(重點借鑒學習)

8.先進行Patrol的編輯,巡邏要以某一點為中心隨機改變方向運動,在AI中一般用到的移動節點有三個(通過輸入Move To都可以找到)各有不同第一個,是向著一個Actor移動,可以在Chase(追蹤)的時候使用,第二個向著一個位置運動,可以在Patrol(巡邏)的時候用,第三個一般在比較復雜的情況使用,但是Actor的優先級高於Location.

技術分享

9.在Patrol中使用Simple move to location,接著確定移向的點,在AI中的Navigation中有Get Random Point in Navigatable Radius.這裏就要輸入數據了,根據MVC編程模式,將數據放在V中。

10.在初始化的問題上,EventBeginPlay一般要用Character中的,比較穩定,以為Controller有時會在順序上跟Character不同,所以一致放在Character中。

11.設置好需要考慮的數據,例如移動速度,巡邏時間之類的。

12.完成基本的巡邏之後就要考慮發現敵人(Player)之後的Chase(追蹤)了。

13.追蹤的思路是在一定範圍內檢測到Player靠近,之後想Player移動。移動好解決,利用Simple Move To Actor就可以解決,那麽難點就是如何讓檢測Player的靠近,方法有很多,例如可以用Get Distance To獲得兩個物體之間的距離,通過距離來判斷Player的靠近。根據項目的需要也可以有Find Look at Rotation,當兩者的角度小於多少時完成判斷,還有就是Get Dot Product To(暫時不知如何用),還可以用射線來做,用一個球形射線,Sphere Trace For Object.

14.這裏用一種比較常用的方法,PawnSensing(角色檢測),跟射線差不多,調整數據達到要求。在Controller中添加PawnSeneing調整好數據後,右擊創建事件驅動,OnSeePawn,並將檢測到的Pawn升級為一個變量,以供後面使用。

15.在Patrol中引出另一個分支,檢測到目標的時候就要切換狀態至Chase(追蹤)。

16.在Chase中最基本的是跟隨著Player移動,simple move to Actor

17.那麽分析一下在 Chase中會發生什麽情況,一種是,因為速度的原因沒有追上,那麽就要回去繼續巡邏了(Back),一種是追上了,那麽要進行Attack。

18.先分析沒追上回去巡邏了,這裏需要一個距離數值,當兩者距離大於這個值時就要進入Back狀態,回去繼續巡邏。通過GetDistanceTo來獲得兩者之間的距離,與距離數值相比較,大於則進入Back狀態。

19接著分析追上了進入Attack狀態,這裏需要一個攻擊距離,當兩者之間的距離小於攻擊距離時,進入Attack狀態。

20.接著編輯Back狀態,在Back狀態中,基本功能是Enemy回到原地繼續巡邏,所以繼續SimpleMoveToLocation,目標就是HomeLocation,此時判斷,是否回到HomeLocation,回到則切換回巡邏狀態,但是經過驗證之間是有誤差的,所以說,要判斷當前的位置和Homelocation的距離(向量相減之後獲得Length)小於50(自定義,合理即可)時,進入巡邏狀態。

這裏有一點需要特別註意,當返回巡邏狀態後,進入巡邏,但此時巡邏狀態有個判定:當檢測到有Player接近時將Pawn付給CurrentPawn,當CurrentPawn有效時,則進入Chase狀態,所以當Enemy回去巡邏時,應該將CurrentPawn清空,不能讓其進入Chase模式。

21.接下來就要進行Attack狀態的操作了,首先準備好動畫,這裏實際是思路跟上面差不多,有一點註意的是Attack的動畫跟Walk的動畫之間的切換,通過布爾值切換,這個布爾值要設在Enemy中,方便Controller和動畫藍圖調用,進入Attack狀態下將布爾值設為真,此時也就滿足了由walk動畫進入Attack的條件,並在狀態下檢測兩者距離,如果脫離攻擊範圍,那麽進去Back狀態。從Attack動畫中回到Walk的條件是布爾值為假,這個要在動畫結束時添加一個事件,由這個事件去設置布爾值為假。

22.結束之後基本功能都實現了,下面進行優化,

1.會發現,在進行Attack動畫時兩者距離發生改變就會出現滑動的情況,這裏解決辦法各有千秋,可以在此動畫狀態下將移動速度設為0,動畫結束後再設回來,這樣顯得就麻煩了許多,可以這麽想,在進行這個擊打動畫時使整個Ai都不起作用,也就不會移動了,動畫結束時再起作用,這裏就要用一個布爾值來控制開關了,當然,開關要設在最初始的驅動上(EventTick),控制布爾值就要跟控制動畫的布爾值同步了,進入Attack狀態時將布爾值設為真,在動畫結束的事件中江布爾值設為假。(這裏還有一個BUG有待解決,就是這樣的話Attack就會進行兩次,產生的原因是,當進入Attack狀態時,就要關閉AI,這會使得不能及時反饋位置信息進入巡邏模式,只能在動畫結束後開啟AI才能獲得位置信息,然而此時也會再次進入動畫)解決:既然是出現在執行動畫的過程中進入了另一種狀態,那麽只需要在進入狀態是檢測動畫有沒有結束就OK了,在動畫的末尾添加一個事件觸發一個布爾值,在進入狀態時檢測一下布爾值就可以了,不需要完全關閉AI的。

2.CD問題,將兩次擊打之間設有一定的CD。這裏需要註意的是在CD過程中,兩者距離發生改變,那麽就要直接跳轉到巡邏狀態。(避免CD過程中改變了距離,不進入動畫也不切換狀態)

3.速度的問題。(通過倍數改變)

4.還有一個數據結構的問題(table)

數據結構,

每一種不同的怪物將會有不同的所需要的數據,而這些數據雖然數值不同但是,類型都相同,那麽就會用到DataTable,在建立DataTable之前要先建立一個結構體,將需要輸入的變量全部輸入,在Miscellaneous中創建一個DataTable。選擇剛剛創建的結構體,添加元素,輸入各項值,然後在目標初始化的過程中添加此數據,GetDataTableRow,(還有個GetDataTableRowName是獲得名字的),將OutRow Break後將數據一一付給變量。

在工作中,一般會將CSV格式的表格寫好數據之後導入UE,格式就是DataTable。

AI 狀態機機制(虛幻三的做法)