在3D MMO或者其他类型的游戏中,通常需要进行寻路处理,地图针对寻路有多种方案,比如划分格子,凸多边形等,本篇介绍一种比较常用的navigation mesh的方式来进行寻路。不过整套navmesh的算法比较复杂,没有深入的研究写不出来,我们使用网上开源的解决方案,google的recast方案。我们使用的开发环境是win7 + vs2013.

一、服务器端recast的安装和使用

1、先从github上面下载recast的源代码

2. 源代码下载下来之后,需要我们自己进行编译,recast使用预编译工具premake,需要premake.lua。先下载lua,然后单独下载premake5,否则premake5.lua不能使用。将下载好的premake.exe放到和premake5.lua的同一目录下,然后在控制台运行premake.exe vs2013(根据自己的IDE版本号),就会生成vs2013的解决方案sln文件。

2. recast的测试程序中,用到了SDL的相关库,这个比较简单,下载一个SDL-devel的库就可以了,然后看下RecastDemo里面的配置目录,copy进去就可以编译通过了。中间编译的时候,可能由于vs2013版本,会提示min,max这些函数没有定义,只要#include对应的STL库头文件就可以了

3. 成功编译了recast相关的库,Detour,Recast等,我们一开始对于如何使用recast可能一点概念都没有,不过recast已经考虑到了这一点,工程中有一个RecastDemo程序,是用来示例如何使用recast的。

4. 使用recastDemo,我们可以根据场景的.obj文件,来生成navmesh,和导入我们自己生成的navmesh,不过这都是我们通过recast开源工具生成的。实际的游戏中,我们需要的是从客户端生成的navmesh,然后导入到服务器中进行解析。

二、Unity3D客户端的navmesh生成

unity3D是自带navmesh agent的,可以自己生成navmesh,并且导出navmesh,不过它的导出navmesh,我查下来是需要自己写代码的,而且navmesh agent是修改过导出navmesh文件格式的,也就是说我们recast C++代码是不能直接使用的。后来我又搜索了一下recast for Unity这个插件,这个插件是有源代码的,不过如果正常购买需要$50。

对于这个插件当时研究了比较长的时间,一开始导出了一下它的navmesh格式,然后用C++recast导入试了一下,发现格式肯定是不一样的了。然后就仔细研究了一下两边生成navmesh时的格式差异,针对TileMesh存储的时候,两边是不一致的,本来想直接修改C#代码来达到两边一致,不过由于对C#的序列化不够熟悉,就放弃了。不过应该可以直接改成一致,这个后面有时间可以再深入研究一下。

后来使用了KBEngine修改过的CritterAI,它导出来的navmesh文件,在KBEngine中是能直接使用的。然后把我们服务器中解析navmesh的格式,改成和KBEngine一致就可以了。代码还是非常简单的,代码如下:

bool NavMeshLoader::load_cai(const char*path) {

FILE* fp = fopen(path, "rb");if (!fp) return false;//Read header.

NavMeshSetHeader_CAI header;

size_t readLen= fread(&header, sizeof(NavMeshSetHeader_CAI), 1, fp);if (readLen != 1)

{

fclose(fp);return false;

}if (header.version !=NAVMESHSET_VERSION)

{

fclose(fp);return false;

}

dtNavMesh* mesh =dtAllocNavMesh();if (!mesh)

{

fclose(fp);return false;

}

dtStatus status= mesh->init(&header.params);if(dtStatusFailed(status))

{

fclose(fp);return false;

}//Read tiles.

for (int i = 0; i < header.tileCount; ++i)

{

NavMeshTileHeader tileHeader;

readLen= fread(&tileHeader, sizeof(tileHeader), 1, fp);if (readLen != 1)

{

fclose(fp);return false;

}if (!tileHeader.tileRef || !tileHeader.dataSize)break;

unsignedchar* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM);if (!data) break;

memset(data,0, tileHeader.dataSize);

readLen= fread(data, tileHeader.dataSize, 1, fp);if (readLen != 1)

{

fclose(fp);return false;

}

mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0);

}

fclose(fp);

m_navMesh=mesh;

m_navQuery=dtAllocNavMeshQuery();

status= m_navQuery->init(m_navMesh, 2048);if(dtStatusFailed(status))

{return false;

}return true;

}

KBEngine中和RecastDemo中解析navmesh主要就是NavMeshSetHeader头结构不一致,其他的都一样,所以还是比较简单的。

能正常解析navmesh文件之后,就是对地图进行寻路了,在这里主要使用了RecastDemo中寻路的代码,进行了本地化的修改。

三、 使用recast navigation遇到的问题

1、其中有段时间,我对于客户端生成的navmesh,和服务器生成的navmesh在坐标系上不一致,感觉很困惑,甚至想要不要自己用3DMax之类的工具重新导入地图模型,然后修改坐标系,这现在看来很可笑,主要还是对于navmesh的生成原理不是很懂。其实客户端生成的navmesh是带有自身坐标系和相对坐标的。之前之所以有那种困惑,是因为服务器用的是recastDemo中生成的navmesh,客户端生成了自己的,根本就是两种世界,两种坐标,当然不一致了!!

2、其实CritterAI的底层是C++写的dll,通过unity导入进工程,然后生成navmesh的,只要符合unity使用dll的规则,我们其实也可以使用recast的源码,然后改成unity能够使用的dll来导出navmesh。这个后面可以试试

java navmesh_服务器使用recast navigation相关推荐

  1. CritterAI插件CritterAI与Recast Navigation寻路

    引用: https://www.cnblogs.com/MarkWoo/p/5211035.html Unity中为一个GameObject添加导航信息 首先,需要为GameObject添加一个Nav ...

  2. Unity:CritterAI与Recast Navigation寻路

    Unity的导航信息,可以在客户端使用,也可以导出NavMesh信息后,在服务器端进行加载几何映射,实现在服务器端进行导航,例如KBEngine,摸索了几天,把整个流程搞清楚,CritterAI可以简 ...

  3. java云服务器系统选择,java云服务器系统选择

    java云服务器系统选择 内容精选 换一换 登录Windows操作系统弹性云服务器时,无法正常进入系统.自启动系统修复模式,但选择修复选项后报错,无法继续进行系统恢复.Windows文件已损坏.登录管 ...

  4. Java游戏服务器系列之Netty详解

    今天带大家来学习Java游戏服务器的相关知识,文中对Netty作了非常详细的介绍,对正在学习java的小伙伴们有很好的帮助,需要的朋友可以参考下 一.简介 Java的底层API逐渐复杂,而开发者面对的 ...

  5. 一个简单的Java web服务器实现

    前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...

  6. Linux Java Web 服务器搭建之tomcat安装

    Linux Java Web 服务器搭建之tomcat安装 一 Tomcat 简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是 ...

  7. java获得服务器路径的几中方法

    2019独角兽企业重金招聘Python工程师标准>>> java获得服务器路径的几中方法 在JavaBean里可以这样: this.getClass().getClassLoader ...

  8. 服务器读取本地文件,java远程服务器访问本地文件

    java远程服务器访问本地文件 内容精选 换一换 云服务器网络异常.防火墙未放行本地远程桌面端口.云服务器CPU负载过高等场景均可能导致云服务器无法正常登录.本节操作介绍无法登录Linux弹性云服务器 ...

  9. java web服务器tomcat介绍【转载】

    机器矩阵2016-08-10 22:14 java程序员亲切地称他为tom猫,看到这只猫可以说明1 服务器部署成功了 ,2 网络是联通的. 到底这只猫是什么来头呢? tomcat是Apache基金会下 ...

最新文章

  1. java 库存 进销存 商户 多用户管理系统 SSM springmvc 项目源码
  2. Spark弹性式数据集RDDs
  3. 云调用,小程序鉴权正确姿势
  4. 小程序消息服务器webapi,小程序订阅消息
  5. iOS 开发学习之 User Interface(4)UIView 与 UIViewController【二】
  6. SpringCloud Gateway 服务网关,断言
  7. android 加密显示银行卡号,Android银行卡输入框与卡号显示
  8. 华为手机鸿蒙系统手机_华为推出鸿蒙系统2.0 明年华为手机将适配支持
  9. pyqgis iface AttributeError: ‘NoneType‘ object has no attribute ‘mapCanvas‘
  10. 仿手机端京东商城html源码_我用手机写了一个Python爬虫,爬下了凡人修仙传……...
  11. Hbuilder开发APP(一)——底部导航条简单实现
  12. 计算机打字键盘怎么控制,电脑键盘打字技巧
  13. 红孩儿编辑器的模块设计5
  14. 鸿蒙支持手机型号,推出鸿蒙,放弃安卓?华为新机入网,鸿蒙首发机型确定!...
  15. c语言患者住院管理系统,住院系统-中小医院医疗套装软件管理系统_九明珠信息科技...
  16. workbench导入excel
  17. 鸿蒙王者荣耀想要转区吗,王者荣耀开放转区 转区转角色服务要求条件汇总
  18. 2012年每周推荐阅读汇总
  19. MySQL数据库中插入图片
  20. linux 之 echo命令用法

热门文章

  1. 一文带你悉知JDBC
  2. Java Swing 界面学习笔记
  3. (附源码)基于nodejs购物系统app-计算机毕设90766
  4. 英语演讲计算机ppt模板,关于计算机的英语演讲稿.docx
  5. 按下鼠标滚轮c语言,苹果多点鼠标怎么实现普通鼠标滚轮按下功能
  6. Vue3: vue3 props接多个不同类型的参数,默认false
  7. 防止windows 10系统崩溃的几种操作
  8. Python 中的GIL
  9. javascript和php中的正则
  10. 【博客515】k8s中为什么需要br_netfilter与net.bridge.bridge-nf-call-iptables=1