unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中...
前言
因?yàn)閁nity版本的更新迭代,老版本的A*插件在新版本Unity已經(jīng)無(wú)法正常使用,包括一些運(yùn)行時(shí)代碼也已經(jīng)過(guò)時(shí),重新接入要花費(fèi)很多時(shí)間,干脆接入一個(gè)新的尋路方案吧。
這里選擇的是久負(fù)盛名的https://github.com/recastnavigation/recastnavigation,但因?yàn)樗腔贑++的,所以我們要使用C#的P/Invoke來(lái)調(diào)用它的dll來(lái)實(shí)現(xiàn)尋路。
由于篇幅與操作復(fù)雜的原因,本文會(huì)更加注重大體的工作流程,而不會(huì)有太多細(xì)節(jié)上的圖片,但是會(huì)有一個(gè)配套的詳細(xì)教學(xué)視頻供大家學(xué)習(xí),視頻鏈接:
接入C++版本recastnavigation尋路庫(kù)到Unity/服務(wù)端中_嗶哩嗶哩 (゜-゜)つロ 干杯~-bilibili?www.bilibili.comC++/C#的橋接源碼也會(huì)以在碼云開(kāi)源的形式分享給大家,完整的示例可以在我的Moba項(xiàng)目 https://gitee.com/NKG_admin/NKGMobaBasedOnET 中看到。
通過(guò)本文和配套視頻你將能學(xué)習(xí)到recastnavigation的大體設(shè)計(jì)思路,使用方式,Unity/服務(wù)器接入recastnavigation的完整流程。
感謝@footman大佬在我學(xué)習(xí)過(guò)程中給予的支持!本文中部分內(nèi)容也來(lái)自大佬的文章。
前置內(nèi)容
Premake認(rèn)識(shí):https://blog.csdn.net/wuguyannian/article/details/92175725
SDL認(rèn)識(shí):https://baike.baidu.com/item/SDL/224181?fr=aladdin
P/Invoke認(rèn)識(shí):https://zhuanlan.zhihu.com/p/30746354
環(huán)境
VS 2019以及完整的C++編譯環(huán)境
Rider For Unreal Engine 2020.2(下面簡(jiǎn)稱Rider)
Unity 2019.4.8 lts
.Net Core 2.2
recastnavigation master:https://github.com/recastnavigation/recastnavigation/commit/9337e124182697de93acb656ef25766486738807
正文
下載并運(yùn)行recastnavigation Demo
先將下載的SDL庫(kù)放到
recastnavigation-masterRecastDemoContrib并且需要改名為SDL,應(yīng)該得到如下目錄
recastnavigation-masterRecastDemoContribSDLlibx64然后將下載premake.exe放入
recastnavigation-masterRecastDemo然后通過(guò)命令行控制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).然后目錄中會(huì)生成一個(gè)Build文件夾,里面是我們編譯出來(lái)的sln工程
recastnavigation-masterRecastDemoBuildvs2019recastnavigation.sln我們用Rider打開(kāi)新生成的sln文件,不出意外的話我們直接就可以構(gòu)建并運(yùn)行RecastDemo工程,也就是我們?cè)谒腉ithub首頁(yè)看到的逼格超高的圖片
好了,杯就先裝到這,后面會(huì)詳細(xì)介紹UI內(nèi)容
構(gòu)建用于P/Invoke的dll
讓我們新建一個(gè)名為RecastNavDll的工程
包含CRecastHelper.cpp/h和RecastDll.cpp/h這四個(gè)文件,并編寫其邏輯,主要是邏輯封裝和為P/Invoke做準(zhǔn)備。
然后添加項(xiàng)目Detour和Recast的引用。
最后編輯解決方案屬性,準(zhǔn)備將我們的RecastNavDll工程導(dǎo)出為x64的dll
提前測(cè)試
如果按照我給出的源碼來(lái)編譯的話,不會(huì)出現(xiàn)邏輯問(wèn)題,但如果有魔改的需要,可能就需要在C++這邊快速測(cè)試,所以還會(huì)提供一個(gè)測(cè)試工程MyTest,其中包含MyTest.cpp/h和tools.cpp/h,直接編譯并且用終端裝載命令行即可進(jìn)行測(cè)試
Unity客戶端/.Net Core服務(wù)端接入
如果是Unity接入recast很簡(jiǎn)單,直接將我們導(dǎo)出的RecastNavDll.dll放入Plugins目錄下即可。
如果是服務(wù)端,我們需要新建子工程,并且添加RecastNavDll.dll鏈接,并且將csproj文件中CopyToOutputDirectory設(shè)置為Always。
<ItemGroup><None Include="F:Downloadrecastnavigation-masterrecastnavigation-masterRecastDemoBuildvs2019x64ReleaseRecastNavDll.dll"><Link>RecastNavDll.dll</Link><CopyToOutputDirectory>Always</CopyToOutputDirectory></None></ItemGroup>dll導(dǎo)入之后我們就可以在C#這邊搭橋了,我們通過(guò)一個(gè)RecastInterface.cs文件作為P/Invoke的橋梁
recastnavigation工作流程
我們可以通過(guò)官方自帶的RecastDemo來(lái)跟蹤源碼得知工作方式
性能測(cè)試
大家一定很關(guān)心recastnavigation庫(kù)的性能如何,我做了個(gè)壓測(cè)
以這張地圖為例,進(jìn)行隨機(jī)尋路(包括合法點(diǎn)和非法點(diǎn))
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);}}}}得到的結(jié)果是
| 100 | 1.4293ms |
| 10000 | 152.3692ms |
| 100000 | 1365.5992ms |
完全可以滿足服務(wù)器尋路需求,另外這還是單線程尋路,可以自己做多線程優(yōu)化
ET框架接入recastnavigation
我們要替換服務(wù)端的尋路組件,最后只需要RecastPathComponent和RecastPathProcessor兩個(gè)文件即可完成尋路。
完整工作流
我們要先在Unity中使用NavMesh烘焙,然后使用NavMesh/Export Scene工具導(dǎo)出obj文件,然后在RecastDemo中進(jìn)行讀取并烘焙
通過(guò)對(duì)比我們發(fā)現(xiàn)它與Unity中坐標(biāo)點(diǎn)差別就是x軸坐標(biāo)是相反的,所以我們進(jìn)行尋路的時(shí)候?qū)?shù)據(jù)進(jìn)行了處理。
然后我們把導(dǎo)出的bin文件放到我們ET項(xiàng)目中,路徑隨意,只要在程序里定義好就行,比如我這里是 項(xiàng)目根目錄ConfigRecastNavDatasolo_navmesh.bin
服務(wù)端程序中讀取就是讀取的這個(gè)路徑
/// <summary>/// 5v5地圖的Nav數(shù)據(jù)路徑/// </summary>public const string Moba5V5MapNavDataPath = "../Config/RecastNavData/solo_navmesh.bin";進(jìn)行尋路即是
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 因?yàn)槟壳半A段只有一張地圖,所以默認(rèn)mapId為10001recastPathComponent.SearchPath(10001, self.RecastPath);總結(jié)
以上是生活随笔為你收集整理的unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux grub 下载,GRUB 2
- 下一篇: .net 批量更新_Revit二次开发—