日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Unreal 寻路网格

發(fā)布時(shí)間:2023/12/20 编程问答 68 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unreal 寻路网格 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • Agent 的挑選
    • Nav Data是什么
    • NavLinkProxy是什么
    • 尋路網(wǎng)格算法
    • Build Path 流程
    • 虛幻Recast dtNavMesh Build流程
    • 修改尋路網(wǎng)格
    • 動態(tài)修改尋路
      • DynamicModifiersOnly
    • 優(yōu)化動態(tài)修改尋路
    • 大世界下尋路網(wǎng)格的使用
      • 1 老辦法
      • 2 只在周圍生成
      • 3 world-partitioned做法
        • 操作
        • 原理

Agent 的挑選

在項(xiàng)目設(shè)置內(nèi),Navigation System 內(nèi)可以配置一些Agents

在尋路過程中,使用移動組件內(nèi)的配置去匹配所有Agents

具體的函數(shù)如下:

const ANavigationData* UNavigationSystemV1::GetNavDataForProps(const FNavAgentProperties& AgentProperties) const

匹配的規(guī)則:

  • 首先判斷 Preferred Nav Data 是否匹配:

    return (PreferredNavData == Other.PreferredNavData || PreferredNavData.IsNull() || Other.PreferredNavData.IsNull());
  • 然后用 AgentRadius 和 AgentHeight 進(jìn)行匹配(默認(rèn)-1,表示使用膠囊體),挑出最匹配的那個(gè)

    • 單項(xiàng)更優(yōu)判斷:較大的優(yōu)先(Agent 比目標(biāo)大,至少不會出現(xiàn)卡住的情況),都比目標(biāo)大或者小的情況下,較接近的優(yōu)先
    • 若不符合兩項(xiàng)都較優(yōu)或相同,且之前的Agent不合法(兩項(xiàng)有一項(xiàng)是小于目標(biāo)的),則先使用半徑判斷,若相同再用高度判斷,只有有一項(xiàng)是較優(yōu)則替換
    • 所以,Agent的設(shè)置和實(shí)際的相同或者大一些
    • 注意這里兩項(xiàng)相同的情況也會替換,而List本身是項(xiàng)目設(shè)置內(nèi)的逆序,所以默認(rèn)的Agent排在上面
    ExcessRadius = NavIt.AgentRadius - AgentProperties.AgentRadius; ExcessHeight = bSkipAgentHeightCheckWhenPickingNavData ? 0.f : (NavIt.AgentHeight - AgentHeight);const bool bExcessRadiusIsBetter = ((ExcessRadius == 0) && (BestExcessRadius != 0)) || ((ExcessRadius > 0) && (BestExcessRadius < 0))|| ((ExcessRadius > 0) && (BestExcessRadius > 0) && (ExcessRadius < BestExcessRadius))|| ((ExcessRadius < 0) && (BestExcessRadius < 0) && (ExcessRadius > BestExcessRadius)); const bool bExcessHeightIsBetter = ((ExcessHeight == 0) && (BestExcessHeight != 0))|| ((ExcessHeight > 0) && (BestExcessHeight < 0))|| ((ExcessHeight > 0) && (BestExcessHeight > 0) && (ExcessHeight < BestExcessHeight))|| ((ExcessHeight < 0) && (BestExcessHeight < 0) && (ExcessHeight > BestExcessHeight)); const bool bBestIsValid = (BestExcessRadius >= 0) && (BestExcessHeight >= 0); const bool bRadiusEquals = (ExcessRadius == BestExcessRadius); const bool bHeightEquals = (ExcessHeight == BestExcessHeight);bool bValuesAreBest = ((bExcessRadiusIsBetter || bRadiusEquals) && (bExcessHeightIsBetter || bHeightEquals)); if (!bValuesAreBest && !bBestIsValid) {bValuesAreBest = bExcessRadiusIsBetter || (bRadiusEquals && bExcessHeightIsBetter); }if (bValuesAreBest) {BestFitNavAgent = NavIt;BestExcessHeight = ExcessHeight;BestExcessRadius = ExcessRadius; }

Nav Data是什么

在 Build Path 時(shí),World 內(nèi)會為每一個(gè) Agent 生成一份 NavigationData,用于這種類型角色的尋路。具體流程是:A 在尋路時(shí),根據(jù)(PreferredNavData、AgentRadius、AgentHeight)找到最符合的 Agent,然后使用該 Agent 對應(yīng)的 NavigationData,進(jìn)行路徑搜索,最后找出 N 個(gè)點(diǎn),就是尋找到的路徑,然后 AI 就按照這條路徑操縱移動組件進(jìn)行移動(移動流程參考UE4:AI‘s MoveTo——代碼分析)

而每個(gè) Agent 有自己的 Nav Data Class,也就是說同樣體型不同 Nav Data Class 的情況下需要兩個(gè) Agent,以飛行為例,我們需要兩個(gè) Agent,一個(gè)Walk,一個(gè)Fly,當(dāng)需要進(jìn)行飛行尋路時(shí),就需要找到 Fly 這個(gè) Agent。而 Fly Agent 生成的 NavigationData,就是用于飛行尋路的基礎(chǔ)數(shù)據(jù)。

NavLinkProxy是什么

有一些游戲機(jī)制(例如傳送門),使得我們的路徑?jīng)]法使用單純自動生成的尋路網(wǎng)格,需要增加一些處理。這種情形下我們會用到NavLinkProxy,將兩個(gè)點(diǎn)之間聯(lián)通(可選單向),我們的尋路就會將這兩個(gè)點(diǎn)聯(lián)通。

當(dāng)AI到達(dá)點(diǎn)A時(shí),會觸發(fā)NavLinkProxy的Receive Smart Link Reached,這里我們可以自定義AI所需要觸發(fā)的函數(shù),例如響應(yīng)傳說。

尋路網(wǎng)格算法

https://zhuanlan.zhihu.com/p/359376662

https://zhuanlan.zhihu.com/p/74537236

Build Path 流程

在Build - Build Path,進(jìn)入到UNavigationSystemV1::Build()

UNavigationSystemV1::Build()

  • void UNavigationSystemV1::SpawnMissingNavigationData()
  • void UNavigationSystemV1::RebuildAll(bool bIsLoadTime)
  • FNavDataGenerator::RebuildAll

就是對每個(gè)NavData,運(yùn)行NavDataGenerator的RebuildAll函數(shù)

虛幻Recast dtNavMesh Build流程

https://docs.unrealengine.com/4.27/en-US/API/Runtime/Navmesh/Detour/dtNavMesh/

修改尋路網(wǎng)格

將 DirtyArea 塞入 DirtyAreasController 的 TArray<FNavigationDirtyArea> DirtyAreas

然后在 void UNavigationSystemV1::Tick(float DeltaSeconds) 內(nèi),調(diào)用

  • RebuildDirtyAreas(DeltaSeconds)
  • DefaultDirtyAreasController.Tick
  • NavData->RebuildDirtyAreas(DirtyAreas)

將這些 DirtyArea 傳遞給 ANavigationData 的 FNavDataGenerator 處理

以Recast為例,就是將與 FNavigationDirtyArea 相交的 Tile 進(jìn)行重建


注意,RebuildDirtyAreas(DeltaSeconds) 有一個(gè)前提是 IsNavigationBuildingLocked() == false,而當(dāng)編輯器設(shè)置內(nèi)的 Update Navigation Automatically 為 False 時(shí),NavBuildingLockFlags 會加上 ENavigationBuildLock::NoUpdateInEditor,所以這種情況下除非主動調(diào)用 RebuildAll,也就是 Build - Build Path,否則NavData是不會變化的

動態(tài)修改尋路

DynamicModifiersOnly

將ProjectSetting內(nèi),NavigationMesh的RuntimeGeneration改為DynamicModifiersOnly

針對會移動的障礙,將障礙的StaticMeshComponent的Can Ever Affect Navigation改為False,并且給障礙加上NavModifierComponent。

注意,由于是障礙物,所以需要把NavModifierComponent的AreaClass改為NavArea_Null。

優(yōu)化動態(tài)修改尋路

https://zhuanlan.zhihu.com/p/566846141

大世界下尋路網(wǎng)格的使用

1 老辦法

直接加載所有的塊,然后build path,注意,為了避免之后加載塊導(dǎo)致的build path,在編輯器設(shè)置內(nèi)關(guān)閉自動更新導(dǎo)航

2 只在周圍生成

只在Invoker周圍動態(tài)生成尋路數(shù)據(jù)

參考:
https://www.youtube.com/watch?v=DMe536X4IT0
https://www.youtube.com/watch?v=Smuy2d7y7mA&list=PLNTm9yU0zou7kKcN7091Rdr322Qge5LNA&index=47

第一個(gè)視頻 核心是開啟這個(gè)選項(xiàng)(還是需要尋路體積的)

下面的參數(shù)是更新周期

然后給中心物體(Pawn)加上Navigation Invoker Component

這樣子就會在這個(gè)物體周圍生成尋路數(shù)據(jù)了

內(nèi)部有兩個(gè)Tile Generation Radius和Tile Removal Radius,表示當(dāng)區(qū)域進(jìn)入Generation 范圍就會生成,離開Removal 范圍就會刪除

第二個(gè)視頻是說,如果目標(biāo)太遠(yuǎn)了,就在周圍找一個(gè)目標(biāo)方向的點(diǎn)過去,靠這種方式慢慢接近

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

原理

生成的尋路數(shù)據(jù)會保存到ChunkActor,對于Recast來說就是對應(yīng)區(qū)域內(nèi)的FRecastTileData

當(dāng)區(qū)塊被加載的時(shí)候,會同時(shí)加載ANavigationDataChunkActor,這個(gè)時(shí)候會對每個(gè)尋路數(shù)據(jù),調(diào)用OnStreamingNavDataAdded

以Recast為例,會調(diào)用URecastNavMeshDataChunk::AttachTiles,對于存儲在ChunkActor內(nèi)的所有FRecastTileData, 使用NavMesh->addTile附加到NavMesh內(nèi)

總結(jié)

以上是生活随笔為你收集整理的Unreal 寻路网格的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久九九爱 | jizzjizz日本人| 中文字幕第九页 | 日本久久久久久久久久 | 午夜在线成人 | 国产一区二区三区精品在线观看 | 亚洲久久在线观看 | 无码人妻精品一区二区三区99不卡 | 欧美久久精品一级黑人c片 1000部多毛熟女毛茸茸 | 日韩在线不卡av | 久久久国产成人一区二区三区 | 欧美福利视频在线 | 自拍视频网址 | 国产a久久 | 中文字幕久久熟女蜜桃 | 黑人玩弄人妻一区二区三区四 | 日韩在线中文字幕 | 少妇人妻丰满做爰xxx | 欧洲亚洲成人 | 久久久久国产精品夜夜夜夜夜 | wwwwww国产 | 97超碰精品| 尤物久久| av大片网站 | 依人综合 | 欧美日本道 | 农村妇女毛片 | 夜夜夜久久久 | 91av国产在线 | www.色视频| 色综合久久久久久 | 欧美日韩一区不卡 | 欧美日韩国产区 | 国产成人在线免费观看视频 | 国产精品一色哟哟哟 | 99精品人妻无码专区在线视频区 | 嫩草视频在线免费观看 | 波多野在线 | 黄网站免费大全入口 | 久久黄色一级 | 毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 国产一区二区在线精品 | 亚洲片国产一区一级在线观看 | 日韩av网站在线观看 | 亚洲国产精品激情在线观看 | 欧美性猛交乱大交 | 久久国产精品久久精品国产 | 一区二区毛片 | 麻豆一区二区三区在线观看 | 免费黄网站在线看 | 麻豆视频在线看 | 亚洲天堂久久久久 | 亚洲高潮 | 337p亚洲精品色噜噜噜 | 少妇人妻丰满做爰xxx | 欧美日韩国产精品一区二区三区 | 少妇高潮一区二区三区喷水 | 国产在线色站 | 国产午夜精品在线 | 农村老熟妇乱子伦视频 | 一区二区三区有限公司 | 国产亚洲精品成人无码精品网站 | 黄色三级a| 91手机在线播放 | 熟妇人妻系列aⅴ无码专区友真希 | 免费无码毛片一区二区app | 色综合日韩 | 中文字幕xxxx | 国产一区二区免费在线观看 | 五级 黄 色 片 | 9999re| 成人夜视频 | 加勒比色综合 | 久久99热这里只频精品6学生 | 亚洲高清不卡 | 欧美精品久久久久久久 | 特黄视频免费看 | 久久久久成人精品无码中文字幕 | 亚洲第三色 | 日韩av在线导航 | 好吊色欧美一区二区三区视频 | 欧洲性生活视频 | 亚洲成av人影院 | 亚洲欧美国产视频 | av在线黄色 | 99精品人妻国产毛片 | www.超碰在线观看 | 中文字幕在线乱 | 日日射av| 人人妻人人澡人人爽人人dvd | 超黄av| 国产精品88久久久久久妇女 | 午夜在线成人 | 卡通动漫亚洲综合 | 97超碰人人看 | 精品人妻一区二区三 | 国产av精国产传媒 | 少妇又紧又色又爽又刺激视频 | 国产剧情av在线 |