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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中...

發布時間:2024/9/27 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

因為Unity版本的更新迭代,老版本的A*插件在新版本Unity已經無法正常使用,包括一些運行時代碼也已經過時,重新接入要花費很多時間,干脆接入一個新的尋路方案吧。

這里選擇的是久負盛名的https://github.com/recastnavigation/recastnavigation,但因為他是基于C++的,所以我們要使用C#的P/Invoke來調用它的dll來實現尋路。

由于篇幅與操作復雜的原因,本文會更加注重大體的工作流程,而不會有太多細節上的圖片,但是會有一個配套的詳細教學視頻供大家學習,視頻鏈接:

接入C++版本recastnavigation尋路庫到Unity/服務端中_嗶哩嗶哩 (゜-゜)つロ 干杯~-bilibili?www.bilibili.com

C++/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來跟蹤源碼得知工作方式

  • 初始化Recast引擎——recast_init
  • 加載地圖——recast_loadmap(int id, const char* path),id為地圖的id,因為我們某些游戲中可能會有多個地圖尋路實例,例如Moba游戲,每一場游戲中的地圖尋路都是獨立的,需要id來區分,path就是尋路數據的完整路徑(包含文件名),這個尋路數據我們可以通過RecastDemo來得到
  • 尋路——recast_findpath(int id, const float* spos, const float* epos),尋路的結果其實只是返回從起點到終點之間所有經過的凸多邊形的序號,id為地圖id,spos為起始點,epos為中點,我們可以把它們理解為C#中的Vector3
  • 計算實際路徑——recast_smooth(int id, float step_size, float slop),計算平滑路徑,其實是根據findpath得到的【從起點到終點所經過的凸多邊形的序號】,得到真正的路徑(三維坐標),所以這一步是不可缺少的
  • 得到凸多邊形id序列——recast_getpathpoly(int id),得到pathfind以后,從起點到終點所經過的所有凸多邊形id的序列
  • 得到尋路路徑坐標序列——recast_getpathsmooth(int id),得到smooth以后,路線的三維坐標序列
  • 釋放地圖——recast_freemap(int id),游戲結束后記得釋放地圖尋路數據資源嗷
  • 釋放Recast引擎——recast_fini(),如果我們在客戶端使用,游戲流程結束要使用這個釋放Recast引擎
  • 性能測試

    大家一定很關心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);}}}}

    得到的結果是

    尋路次數耗時
    1001.4293ms
    10000152.3692ms
    1000001365.5992ms

    完全可以滿足服務器尋路需求,另外這還是單線程尋路,可以自己做多線程優化

    ET框架接入recastnavigation

    我們要替換服務端的尋路組件,最后只需要RecastPathComponent和RecastPathProcessor兩個文件即可完成尋路。

    完整工作流

    我們要先在Unity中使用NavMesh烘焙,然后使用NavMesh/Export Scene工具導出obj文件,然后在RecastDemo中進行讀取并烘焙

  • Sample-Solo Mesh
  • Input Mesh-我們導出的obj文件,需要放到recastnavigation-masterRecastDemoBinMeshes目錄下
  • 調制參數,Build
  • Save保存為nav文件,會導出為recastnavigation-masterRecastDemoBinsolo_navmesh.bin
  • 通過對比我們發現它與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/服务端中...的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。