Unreal 寻路网格
文章目錄
- Agent 的挑選
- Nav Data是什么
- NavLinkProxy是什么
- 尋路網格算法
- Build Path 流程
- 虛幻Recast dtNavMesh Build流程
- 修改尋路網格
- 動態修改尋路
- DynamicModifiersOnly
- 優化動態修改尋路
- 大世界下尋路網格的使用
- 1 老辦法
- 2 只在周圍生成
- 3 world-partitioned做法
- 操作
- 原理
Agent 的挑選
在項目設置內,Navigation System 內可以配置一些Agents
在尋路過程中,使用移動組件內的配置去匹配所有Agents
具體的函數如下:
const ANavigationData* UNavigationSystemV1::GetNavDataForProps(const FNavAgentProperties& AgentProperties) const匹配的規則:
-
首先判斷 Preferred Nav Data 是否匹配:
return (PreferredNavData == Other.PreferredNavData || PreferredNavData.IsNull() || Other.PreferredNavData.IsNull()); -
然后用 AgentRadius 和 AgentHeight 進行匹配(默認-1,表示使用膠囊體),挑出最匹配的那個
- 單項更優判斷:較大的優先(Agent 比目標大,至少不會出現卡住的情況),都比目標大或者小的情況下,較接近的優先
- 若不符合兩項都較優或相同,且之前的Agent不合法(兩項有一項是小于目標的),則先使用半徑判斷,若相同再用高度判斷,只有有一項是較優則替換
- 所以,Agent的設置和實際的相同或者大一些
- 注意這里兩項相同的情況也會替換,而List本身是項目設置內的逆序,所以默認的Agent排在上面
Nav Data是什么
在 Build Path 時,World 內會為每一個 Agent 生成一份 NavigationData,用于這種類型角色的尋路。具體流程是:A 在尋路時,根據(PreferredNavData、AgentRadius、AgentHeight)找到最符合的 Agent,然后使用該 Agent 對應的 NavigationData,進行路徑搜索,最后找出 N 個點,就是尋找到的路徑,然后 AI 就按照這條路徑操縱移動組件進行移動(移動流程參考UE4:AI‘s MoveTo——代碼分析)
而每個 Agent 有自己的 Nav Data Class,也就是說同樣體型不同 Nav Data Class 的情況下需要兩個 Agent,以飛行為例,我們需要兩個 Agent,一個Walk,一個Fly,當需要進行飛行尋路時,就需要找到 Fly 這個 Agent。而 Fly Agent 生成的 NavigationData,就是用于飛行尋路的基礎數據。
NavLinkProxy是什么
有一些游戲機制(例如傳送門),使得我們的路徑沒法使用單純自動生成的尋路網格,需要增加一些處理。這種情形下我們會用到NavLinkProxy,將兩個點之間聯通(可選單向),我們的尋路就會將這兩個點聯通。
當AI到達點A時,會觸發NavLinkProxy的Receive Smart Link Reached,這里我們可以自定義AI所需要觸發的函數,例如響應傳說。
尋路網格算法
https://zhuanlan.zhihu.com/p/359376662
https://zhuanlan.zhihu.com/p/74537236
Build Path 流程
在Build - Build Path,進入到UNavigationSystemV1::Build()
UNavigationSystemV1::Build()
- void UNavigationSystemV1::SpawnMissingNavigationData()
- void UNavigationSystemV1::RebuildAll(bool bIsLoadTime)
- FNavDataGenerator::RebuildAll
就是對每個NavData,運行NavDataGenerator的RebuildAll函數
虛幻Recast dtNavMesh Build流程
https://docs.unrealengine.com/4.27/en-US/API/Runtime/Navmesh/Detour/dtNavMesh/
修改尋路網格
將 DirtyArea 塞入 DirtyAreasController 的 TArray<FNavigationDirtyArea> DirtyAreas
然后在 void UNavigationSystemV1::Tick(float DeltaSeconds) 內,調用
- RebuildDirtyAreas(DeltaSeconds)
- DefaultDirtyAreasController.Tick
- NavData->RebuildDirtyAreas(DirtyAreas)
將這些 DirtyArea 傳遞給 ANavigationData 的 FNavDataGenerator 處理
以Recast為例,就是將與 FNavigationDirtyArea 相交的 Tile 進行重建
注意,RebuildDirtyAreas(DeltaSeconds) 有一個前提是 IsNavigationBuildingLocked() == false,而當編輯器設置內的 Update Navigation Automatically 為 False 時,NavBuildingLockFlags 會加上 ENavigationBuildLock::NoUpdateInEditor,所以這種情況下除非主動調用 RebuildAll,也就是 Build - Build Path,否則NavData是不會變化的
動態修改尋路
DynamicModifiersOnly
將ProjectSetting內,NavigationMesh的RuntimeGeneration改為DynamicModifiersOnly
針對會移動的障礙,將障礙的StaticMeshComponent的Can Ever Affect Navigation改為False,并且給障礙加上NavModifierComponent。
注意,由于是障礙物,所以需要把NavModifierComponent的AreaClass改為NavArea_Null。
優化動態修改尋路
https://zhuanlan.zhihu.com/p/566846141
大世界下尋路網格的使用
1 老辦法
直接加載所有的塊,然后build path,注意,為了避免之后加載塊導致的build path,在編輯器設置內關閉自動更新導航
2 只在周圍生成
只在Invoker周圍動態生成尋路數據
參考:
https://www.youtube.com/watch?v=DMe536X4IT0
https://www.youtube.com/watch?v=Smuy2d7y7mA&list=PLNTm9yU0zou7kKcN7091Rdr322Qge5LNA&index=47
第一個視頻 核心是開啟這個選項(還是需要尋路體積的)
下面的參數是更新周期
然后給中心物體(Pawn)加上Navigation Invoker Component
這樣子就會在這個物體周圍生成尋路數據了
內部有兩個Tile Generation Radius和Tile Removal Radius,表示當區域進入Generation 范圍就會生成,離開Removal 范圍就會刪除
第二個視頻是說,如果目標太遠了,就在周圍找一個目標方向的點過去,靠這種方式慢慢接近
3 world-partitioned做法
操作
https://docs.unrealengine.com/5.0/en-US/world-partitioned-navigation-mesh/
https://docs.unrealengine.com/5.1/en-US/world-partition-in-unreal-engine/
Command: UnrealEditor.exe “C:\Users\user.name\Documents\Unreal Projects\MyProject\MyProject.uproject” “/Game/ThirdPersonBP/Maps/OpenWorldTest” -run=WorldPartitionBuilderCommandlet -AllowCommandletRendering -builder=WorldPartitionNavigationDataBuilder -SCCProvider=None
原理
生成的尋路數據會保存到ChunkActor,對于Recast來說就是對應區域內的FRecastTileData
當區塊被加載的時候,會同時加載ANavigationDataChunkActor,這個時候會對每個尋路數據,調用OnStreamingNavDataAdded
以Recast為例,會調用URecastNavMeshDataChunk::AttachTiles,對于存儲在ChunkActor內的所有FRecastTileData, 使用NavMesh->addTile附加到NavMesh內
總結
以上是生活随笔為你收集整理的Unreal 寻路网格的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 交换机千兆和百兆对网速影响_交换机千兆和
- 下一篇: 概率论与数理统计习题——第五讲——等可能