unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中...
前言
因为Unity版本的更新迭代,老版本的A*插件在新版本Unity已经无法正常使用,包括一些运行时代码也已经过时,重新接入要花费很多时间,干脆接入一个新的寻路方案吧。
这里选择的是久负盛名的https://github.com/recastnavigation/recastnavigation,但因为他是基于C++的,所以我们要使用C#的P/Invoke来调用它的dll来实现寻路。
由于篇幅与操作复杂的原因,本文会更加注重大体的工作流程,而不会有太多细节上的图片,但是会有一个配套的详细教学视频供大家学习,视频链接:
接入C++版本recastnavigation寻路库到Unity/服务端中_哔哩哔哩 (゜-゜)つロ 干杯~-bilibiliwww.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-masterRecastDemoF: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);}}}}
得到的结果是
寻路次数 | 耗时 |
---|---|
100 | 1.4293ms |
10000 | 152.3692ms |
100000 | 1365.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/服务端中...相关推荐
- unity三维地图的经纬度如何在二维地图上表示_安全数据分析:数据点—地图—线性回归...
一次性进群,长期免费索取教程,没有付费教程. 教程列表见微信公众号底部菜单 进微信群回复公众号:微信群:QQ群:460500587 微信公众号:计算机与网络安全 ID:Computer-network ...
- unity三维地图的经纬度如何在二维地图上表示_三维GIS与游戏引擎的跨界融合,打造数字化孪生的平行世界...
▲点击关注,收获更多GIS精彩 游戏地图在游戏中起基础和关键作用,它承载游戏中的各种资源,是游戏系统中非常重要的组成部分(图1),所以游戏通常具有明显的地理意义.因此,虽然三维GIS与游戏引擎是两个不 ...
- skyline三维地图与arcgis二维地图联动
无论是二维控制三维,还是三维控制二维,都是通过事件来触发,只不过各自的事件有所区别就是了.这里所说的二维,是指arcgis for jsapi,三维指skyline,都是前端的内容. 其中二维控制三维 ...
- 01 创建一个二维地图
随着3.X系列版本新功能的不再增加,终于开始向4.X版本转变,其实说实话还是蛮不想转变的,因为相对于3.X版本的API,4.X版本里面的功能目前为止还是有点少的,但大势所趋,只能硬着头皮转了. 首先, ...
- maptalks+three.js+vue webpack项目实现二维地图上贴三维模型
我们不是走在坑里就是走在前往坑的路上_(:зゝ∠)_ 最终效果如图:(地图上添加一个"三维地图"的toolbar按钮,点击后在二维地图上贴上建好的三维模型点击显示弹框) 以下都在已 ...
- arcgis for android(二)显示二维地图
1.上一节讲了 arcgis for android 入门与提高(一)配置环境https://blog.csdn.net/HB_Programmer/article/details/119967868 ...
- Echarts 地图概述及二维地图初始化
Echarts 可以绘制中国.各省及世界地图,包括二维地图和三维地图,下面就如何生成地图做概要介绍. 1 地图功能概述 Echarts 中,如果需要将区域数据可视化,使用 series 中的地图组件 ...
- 二维地图展示爆管分析
作者:doremi 管线系统管理目前大多数都是使用三维客户端来实现的,爆管分析也是在三维客户端上展示的.但是最近有很多客户的来电询问如何在二维地图上实现管线的一些分析功能.因此,本文将介绍如何在二维地 ...
- 寻路优化(一)——二维地图上A*启发函数的设计探索
工作中需要优化A*算法,研究了一天,最后取得了不错的效果.看网上的朋友还没有相关的研究,特此记录一下.有错误欢迎大家批评指正.如需转载请注明出处,http://www.cnblogs.com/Leon ...
最新文章
- 无引脚表贴元器件焊接
- 牛逼哄哄的 RPC 框架,底层到底什么原理?
- Linux学习之用户管理和组管理
- java中将对象转为基本数据类型
- User Mode Driver Management 介绍(二)
- 谷歌的量子计算机速度,谷歌称其量子计算机速度比传统计算机快1亿倍
- php 测试数据整数,PHP中将字符串转化为整数(int) intval() printf() 性能测试
- PowerDesigner的基本使用
- 生成对抗网络系列—ACL-GAN
- C# 实现局域网的windows环境下的桌面分享
- android inflate,android inflate详解
- 【单片机笔记】STM32+ESP8266通过AT指令WIFI连接阿里云MQTT服务器
- 发送报警信息到微信公众号
- 触屏笔哪里便宜?高性价比第三方电容笔推荐
- AI轰鸣时代(一):苹果VS麒麟,今年的移动芯片究竟比什么?
- 在win2008中配置ServU
- 生而为人,我很抱歉!深夜爬虫, 我很抱歉 ,附微信 “ 网抑云” 公众号爬虫教程!
- 如何从iCloud共享iWork文档
- [超级码力在线编程大赛初赛(二)] 4.小栖的金字塔 施罗德数(超级卡特兰数)
- 比起简单的我爱你,我更爱从0开始拼搏的你