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

前言

因为Unity版本的更新迭代,老版本的A*插件在新版本Unity已经无法正常使用,包括一些运行时代码也已经过时,重新接入要花费很多时间,干脆接入一个新的寻路方案吧。

这里选择的是久负盛名的https://github.com/recastnavigation/recastnavigation,但因为他是基于C++的,所以我们要使用C#的P/Invoke来调用它的dll来实现寻路。

由于篇幅与操作复杂的原因,本文会更加注重大体的工作流程,而不会有太多细节上的图片,但是会有一个配套的详细教学视频供大家学习,视频链接:

接入C++版本recastnavigation寻路库到Unity/服务端中_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com
e8fd6357f560d7740db5f61b4872ef34.png

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首页看到的逼格超高的图片

a17ad7effe729215b6d3777e239af155.png

好了,杯就先装到这,后面会详细介绍UI内容

构建用于P/Invoke的dll

让我们新建一个名为RecastNavDll的工程

包含CRecastHelper.cpp/h和RecastDll.cpp/h这四个文件,并编写其逻辑,主要是逻辑封装和为P/Invoke做准备。

然后添加项目Detour和Recast的引用。

最后编辑解决方案属性,准备将我们的RecastNavDll工程导出为x64的dll

be453396f7cd3ce2fc04cdbcdf58016a.png

提前测试

如果按照我给出的源码来编译的话,不会出现逻辑问题,但如果有魔改的需要,可能就需要在C++这边快速测试,所以还会提供一个测试工程MyTest,其中包含MyTest.cpp/h和tools.cpp/h,直接编译并且用终端装载命令行即可进行测试

1c8bacac4e392c208f4aaae26df25066.png

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来跟踪源码得知工作方式

  1. 初始化Recast引擎——recast_init
  2. 加载地图——recast_loadmap(int id, const char* path),id为地图的id,因为我们某些游戏中可能会有多个地图寻路实例,例如Moba游戏,每一场游戏中的地图寻路都是独立的,需要id来区分,path就是寻路数据的完整路径(包含文件名),这个寻路数据我们可以通过RecastDemo来得到
  3. 寻路——recast_findpath(int id, const float* spos, const float* epos),寻路的结果其实只是返回从起点到终点之间所有经过的凸多边形的序号,id为地图id,spos为起始点,epos为中点,我们可以把它们理解为C#中的Vector3
  4. 计算实际路径——recast_smooth(int id, float step_size, float slop),计算平滑路径,其实是根据findpath得到的【从起点到终点所经过的凸多边形的序号】,得到真正的路径(三维坐标),所以这一步是不可缺少的
  5. 得到凸多边形id序列——recast_getpathpoly(int id),得到pathfind以后,从起点到终点所经过的所有凸多边形id的序列
  6. 得到寻路路径坐标序列——recast_getpathsmooth(int id),得到smooth以后,路线的三维坐标序列
  7. 释放地图——recast_freemap(int id),游戏结束后记得释放地图寻路数据资源嗷
  8. 释放Recast引擎——recast_fini(),如果我们在客户端使用,游戏流程结束要使用这个释放Recast引擎

性能测试

大家一定很关心recastnavigation库的性能如何,我做了个压测

以这张地图为例,进行随机寻路(包括合法点和非法点)

a17ad7effe729215b6d3777e239af155.png
         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中进行读取并烘焙

  1. Sample-Solo Mesh
  2. Input Mesh-我们导出的obj文件,需要放到recastnavigation-masterRecastDemoBinMeshes目录下
  3. 调制参数,Build
  4. Save保存为nav文件,会导出为recastnavigation-masterRecastDemoBinsolo_navmesh.bin

通过对比我们发现它与Unity中坐标点差别就是x轴坐标是相反的,所以我们进行寻路的时候对数据进行了处理。

69f24eb56ca404ca213a4eb1f512927e.png

然后我们把导出的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);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512689.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dataphin功能:集成——如何将业务系统的数据抽取汇聚到数据中台

简介&#xff1a; 数据集成是简单高效的数据同步平台&#xff0c;致力于提供具有强大的数据预处理能力、丰富的异构数据源之间数据高速稳定的同步能力&#xff0c;为数据中台的建设打好坚实的数据基座。 数据中台是当下大数据领域最前沿的数据建设体系, 它并不是从零开始, 无中…

5G专网,路在何方?

作者 | 蜉蝣采采来源 | 无线深海话说你平常打电话、刷视频、玩游戏的4G和5G&#xff0c;一般也被叫做“公网”。这个“公”字的含义正是公开&#xff0c;公用的意思。也就是说&#xff0c;这个网络&#xff0c;不但你能用&#xff0c;你隔壁的张三也能用&#xff0c;张三的老乡…

如何开发 Node.js Native Add-on?

简介&#xff1a; 来一起为 Node.js 的 add-on 生态做贡献吧~ 作者 | 吴成忠(昭朗)这篇文章是由 Chengzhong Wu (legendecas)&#xff0c;Gabriel Schulhof (gabrielschulhof) &#xff0c;Jim Schlight (jimschlight)&#xff0c;Kevin Eady&#xff0c;Michael Dawson (mhdaw…

php范式,数据库三范式,轻松理解_PHP教程

网上搜罗了一大堆关于数据库范式理解的文章&#xff0c;都是千律一篇的复制粘贴&#xff0c;连例子都是一模一样&#xff0c;拜托有点创意好不&#xff0c;实在看不下去&#xff0c;自己写一篇个人理解三范式的文章。如果有理解上的不正确之处&#xff0c;请联系我&#xff1a;…

xxl子任务_XXL-JOB v2.1.2 发布,分布式任务调度平台

v2.1.2 Release Notes1、方法任务支持&#xff1a;由原来基于JobHandler类任务开发方式&#xff0c;优化为支持基于方法的任务开发方式&#xff1b;因此&#xff0c;可以支持单个类中开发多个任务方法&#xff0c;进行类复用XxlJob("demoJobHandler")public ReturnT …

程序员如何在业余时间提升自己?

简介&#xff1a; 在自省过程中&#xff0c;我们经常会问自己这么几个问题&#xff0c;这段时间我尝试了什么新事物、有了什么变化、得到什么成果。 近年来&#xff0c;出现越来越多“自主学习”、“业余提升" 的相关话题。 我们经常收到一些同学提问&#xff1a;程序员…

百度打造AIR智能道路系统,可降低90%交通事故

12月27日&#xff0c;百度Create 2021&#xff08;百度AI开发者大会&#xff09;在“希壤”APP召开&#xff0c;百度创始人、董事长兼CEO李彦宏在演讲中介绍了AIR&#xff08;AI Road&#xff09;智能道路系统。作为软硬一体的路端“自动驾驶系统”&#xff0c; AIR智能道路系统…

java jdbc 连接mysql数据库,Java 通过JDBC连接Mysql数据库

JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API&#xff0c;可以为多种关系数据库提供统一访问&#xff0c;它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准&#xff0c;据此可以构建更高级的工具和接口&#xff0c;使数据库开发…

云原生演进趋势下传统数据库升级实践

简介&#xff1a; 在数字化背景下&#xff0c;我们有许多思考。数据库跟以前那有什么不一样呢&#xff1f;什么是所谓的云原生数据库呢&#xff1f;作为使用数据库的开发者&#xff0c;对数据库的需求有什么变化&#xff1f;如今使用数据库我们一般会提什么样的诉求&#xff1f…

不小心把桌面进程结束了怎么办_微信不小心把天聊死怎么办?试试这3招,分分钟结束“尬聊”...

微信不小心把天“聊死”怎么办&#xff1f;试试这3招&#xff0c;分分钟结束“尬聊”&#xff01;我现在坐的各位小伙伴们应该都会有以下这种经历吧&#xff0c;那就是你明明和一个人好好的在聊天&#xff0c;但突然不小心把天聊死了&#xff0c;其实遇到这种情况下小伙伴千万不…

openGauss汇聚创新力量,共同打造最具创新力的数据库开源社区

[中国&#xff0c;北京&#xff0c;2021年12月28日] 今天&#xff0c;以“汇聚数据库创新力量 逐梦数字时代星辰大海”为主题的openGauss summit 2021在北京线上线下同步举办。大会现场&#xff0c;openGauss开源社区理事会和技术委员会升级&#xff0c;openGauss社区分委会正式…

matlab基本矩阵运算,matlab的矩阵基本运算问题已知A=[a,b,c;d,e,f;h,I,j],B=[l,m,n;x,y,z;q,o,p]...

共回答了22个问题采纳率&#xff1a;95.5%clear all;clc;syms a b c d e f h l j m n x y z o p qA[a,b,c;d,e,f;h,l,j];B[l,m,n;x,y,z;q,o,p];aasum(A);bbdiag(A);ccA*B;ddA.*B;eeAB;ffA/B;ggA.B;hhA.^B;-----------------ee和ff太长了,没写>> aaaa [ adh, bel, cfj]>…

测试功能范围_软件测试难学吗?

一、想要零基础学好软件测试&#xff0c;当然需要对测试有一个良好的认知。你可以大致的浏览一下标题&#xff0c;先看这些标题从理解上看有没有难度。然后在根据自己的情况来判断软件测试是否难学。1、什么是软件测试?软件测试(英语&#xff1a;Software Testing)&#xff0c…

Spring DefaultListableBeanFactory源码分析

DefaultListableBeanFactory源码分析文章目录 一、概述 二、关键结构与存储 Bean定义的存储结构ConcurrentHashMap的使用和意义 三、核心功能解析 四、总结 DefaultListableBeanFactory源码分析 一、概述 DefaultListableBeanFactory 是 Spring 框架中的一个核心类&#xff…

阿里巴巴代码平台架构的演进之路

简介&#xff1a; 这事儿和伽利略有关。 代码平台的发展之路 相信很多做后端服务的同学在看到单机、读写分离、分片这些字眼一定不会觉得陌生。没错&#xff0c;代码服务在发展的开始阶段面临的问题和其他web服务大体一致&#xff0c;所以使用的解决方案也大体一致。 单机服务…

从工具到平台|默安科技研发安全一体化管理平台正式发布

作者|默安科技 数字化转型浪潮下&#xff0c;软件研发安全的重要性毋庸置疑。 据第三方权威调查&#xff0c;接近92%的已知安全漏洞发生在软件应用程序中&#xff0c;且应用中每1000行代码至少出现一个业务逻辑缺陷。 在近年来如火如荼的攻防演练中&#xff0c;应用程序成为…

如何避免 Go 命令行执行产生“孤儿”进程?

简介&#xff1a; 在 Go 程序当中&#xff0c;如果我们要执行命令时&#xff0c;通常会使用 exec.Command &#xff0c;也比较好用&#xff0c;通常状况下&#xff0c;可以达到我们的目的&#xff0c;如果我们逻辑当中&#xff0c;需要终止这个进程&#xff0c;则可以快速使用 …

边缘指示函数matlab,matlab图像处理——傅立叶变换边缘提取

第一部分 图像的傅立叶变换一、 实验目的1.了解图像变换的意义和手段&#xff1b;2. 熟悉傅里叶变换的基本性质&#xff1b;3. 熟练掌握FFT的方法及应用&#xff1b;4. 通过实验了解二维频谱的分布特点&#xff1b;5. 通过本实验掌握利用MATLAB编程实现数字图像的傅立叶变换。二…

杭州南江机器人现在是否量产_传亚马逊正开发家庭机器人,高约1米可移动

点击右上角关注我&#xff0c;成为科技圈最靓的仔&#xff01;智东西(公众号&#xff1a;zhidxcom)编 | 王颖 导语&#xff1a;据外媒报道&#xff0c;亚马逊计划今年推出一款可移动家庭机器人&#xff0c;高度约为1米&#xff0c;可通过语音控制。智东西7月15日消息&#xff0…

OpenYurt 联手 eKuiper,解决 IoT 场景下边缘流数据处理难题

简介&#xff1a; 云计算的出现促使物联网实现爆炸式增长。在设备规模和业务复杂度不断攀升的趋势之下&#xff0c;边缘计算因其能够将计算能力更靠近网络边缘和设备&#xff0c;从而带来云性能成本的降低&#xff0c;也在这波浪潮之下得到快速发展。 作者 | OpenYurt 社区 云…