unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中...
前言
因為Unity版本的更新迭代,老版本的A*插件在新版本Unity已經無法正常使用,包括一些運行時代碼也已經過時,重新接入要花費很多時間,干脆接入一個新的尋路方案吧。
這里選擇的是久負盛名的https://github.com/recastnavigation/recastnavigation,但因為他是基于C++的,所以我們要使用C#的P/Invoke來調用它的dll來實現尋路。
由于篇幅與操作復雜的原因,本文會更加注重大體的工作流程,而不會有太多細節上的圖片,但是會有一個配套的詳細教學視頻供大家學習,視頻鏈接:
接入C++版本recastnavigation尋路庫到Unity/服務端中_嗶哩嗶哩 (゜-゜)つロ 干杯~-bilibili?www.bilibili.comC++/C#的橋接源碼也會以在碼云開源的形式分享給大家,完整的示例可以在我的Moba項目 https://gitee.com/NKG_admin/NKGMobaBasedOnET 中看到。
通過本文和配套視頻你將能學習到recastnavigation的大體設計思路,使用方式,Unity/服務器接入recastnavigation的完整流程。
感謝@footman大佬在我學習過程中給予的支持!本文中部分內容也來自大佬的文章。
前置內容
Premake認識:https://blog.csdn.net/wuguyannian/article/details/92175725
SDL認識:https://baike.baidu.com/item/SDL/224181?fr=aladdin
P/Invoke認識:https://zhuanlan.zhihu.com/p/30746354
環境
VS 2019以及完整的C++編譯環境
Rider For Unreal Engine 2020.2(下面簡稱Rider)
Unity 2019.4.8 lts
.Net Core 2.2
recastnavigation master:https://github.com/recastnavigation/recastnavigation/commit/9337e124182697de93acb656ef25766486738807
正文
下載并運行recastnavigation Demo
先將下載的SDL庫放到
recastnavigation-masterRecastDemoContrib并且需要改名為SDL,應該得到如下目錄
recastnavigation-masterRecastDemoContribSDLlibx64然后將下載premake.exe放入
recastnavigation-masterRecastDemo然后通過命令行控制premake編譯recastnavigation為sln工程
C:UsersAdministrator>f:?F:>cd F:Downloadrecastnavigation-masterrecastnavigation-masterRecastDemo?F:Downloadrecastnavigation-masterrecastnavigation-masterRecastDemo>premake5 vs2019Building configurations...Running action 'vs2019'...Generated Build/vs2019/recastnavigation.sln...Generated Build/vs2019/DebugUtils.vcxproj...Generated Build/vs2019/DebugUtils.vcxproj.filters...Generated Build/vs2019/Detour.vcxproj...Generated Build/vs2019/Detour.vcxproj.filters...Generated Build/vs2019/DetourCrowd.vcxproj...Generated Build/vs2019/DetourCrowd.vcxproj.filters...Generated Build/vs2019/DetourTileCache.vcxproj...Generated Build/vs2019/DetourTileCache.vcxproj.filters...Generated Build/vs2019/Recast.vcxproj...Generated Build/vs2019/Recast.vcxproj.filters...Generated Build/vs2019/RecastDemo.vcxproj...Generated Build/vs2019/RecastDemo.vcxproj.user...Generated Build/vs2019/RecastDemo.vcxproj.filters...Generated Build/vs2019/Tests.vcxproj...Generated Build/vs2019/Tests.vcxproj.user...Generated Build/vs2019/Tests.vcxproj.filters...Done (150ms).然后目錄中會生成一個Build文件夾,里面是我們編譯出來的sln工程
recastnavigation-masterRecastDemoBuildvs2019recastnavigation.sln我們用Rider打開新生成的sln文件,不出意外的話我們直接就可以構建并運行RecastDemo工程,也就是我們在它的Github首頁看到的逼格超高的圖片
好了,杯就先裝到這,后面會詳細介紹UI內容
構建用于P/Invoke的dll
讓我們新建一個名為RecastNavDll的工程
包含CRecastHelper.cpp/h和RecastDll.cpp/h這四個文件,并編寫其邏輯,主要是邏輯封裝和為P/Invoke做準備。
然后添加項目Detour和Recast的引用。
最后編輯解決方案屬性,準備將我們的RecastNavDll工程導出為x64的dll
提前測試
如果按照我給出的源碼來編譯的話,不會出現邏輯問題,但如果有魔改的需要,可能就需要在C++這邊快速測試,所以還會提供一個測試工程MyTest,其中包含MyTest.cpp/h和tools.cpp/h,直接編譯并且用終端裝載命令行即可進行測試
Unity客戶端/.Net Core服務端接入
如果是Unity接入recast很簡單,直接將我們導出的RecastNavDll.dll放入Plugins目錄下即可。
如果是服務端,我們需要新建子工程,并且添加RecastNavDll.dll鏈接,并且將csproj文件中CopyToOutputDirectory設置為Always。
<ItemGroup><None Include="F:Downloadrecastnavigation-masterrecastnavigation-masterRecastDemoBuildvs2019x64ReleaseRecastNavDll.dll"><Link>RecastNavDll.dll</Link><CopyToOutputDirectory>Always</CopyToOutputDirectory></None></ItemGroup>dll導入之后我們就可以在C#這邊搭橋了,我們通過一個RecastInterface.cs文件作為P/Invoke的橋梁
recastnavigation工作流程
我們可以通過官方自帶的RecastDemo來跟蹤源碼得知工作方式
性能測試
大家一定很關心recastnavigation庫的性能如何,我做了個壓測
以這張地圖為例,進行隨機尋路(包括合法點和非法點)
public static void BenchmarkSample(){BenchmarkHelper.Profile("尋路100000次", BenchmarkRecast, 100000);}?private static void BenchmarkRecast(){if (RecastInterface.FindPath(100,new System.Numerics.Vector3(-RandomHelper.RandomNumber(2, 50) - RandomHelper.RandFloat(),RandomHelper.RandomNumber(-1, 5) + RandomHelper.RandFloat(), RandomHelper.RandomNumber(3, 20) + RandomHelper.RandFloat()),new System.Numerics.Vector3(-RandomHelper.RandomNumber(2, 50) - RandomHelper.RandFloat(),RandomHelper.RandomNumber(-1, 5) + RandomHelper.RandFloat(), RandomHelper.RandomNumber(3, 20) + RandomHelper.RandFloat()))){RecastInterface.Smooth(100, 2f, 0.5f);{int smoothCount = 0;float[] smooths = RecastInterface.GetPathSmooth(100, out smoothCount);List<Vector3> results = new List<Vector3>();for (int i = 0; i < smoothCount; ++i){Vector3 node = new Vector3(smooths[i * 3], smooths[i * 3 + 1], smooths[i * 3 + 2]);results.Add(node);}}}}得到的結果是
| 100 | 1.4293ms |
| 10000 | 152.3692ms |
| 100000 | 1365.5992ms |
完全可以滿足服務器尋路需求,另外這還是單線程尋路,可以自己做多線程優化
ET框架接入recastnavigation
我們要替換服務端的尋路組件,最后只需要RecastPathComponent和RecastPathProcessor兩個文件即可完成尋路。
完整工作流
我們要先在Unity中使用NavMesh烘焙,然后使用NavMesh/Export Scene工具導出obj文件,然后在RecastDemo中進行讀取并烘焙
通過對比我們發現它與Unity中坐標點差別就是x軸坐標是相反的,所以我們進行尋路的時候對數據進行了處理。
然后我們把導出的bin文件放到我們ET項目中,路徑隨意,只要在程序里定義好就行,比如我這里是 項目根目錄ConfigRecastNavDatasolo_navmesh.bin
服務端程序中讀取就是讀取的這個路徑
/// <summary>/// 5v5地圖的Nav數據路徑/// </summary>public const string Moba5V5MapNavDataPath = "../Config/RecastNavData/solo_navmesh.bin";進行尋路即是
RecastPathComponent recastPathComponent = Game.Scene.GetComponent<RecastPathComponent>();RecastPath recastPath = ReferencePool.Acquire<RecastPath>();recastPath.StartPos = unit.Position;recastPath.EndPos = new Vector3(target.x, target.y, target.z);self.RecastPath = recastPath;//TODO 因為目前階段只有一張地圖,所以默認mapId為10001recastPathComponent.SearchPath(10001, self.RecastPath);總結
以上是生活随笔為你收集整理的unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux grub 下载,GRUB 2
- 下一篇: binaryviewer java_用j