前言

在游戏开发过程中,寻路可能是大多数游戏都必不可少的功能。2d游戏中最常用的就是A* 寻路了。在3d游戏中,对于一些简单的,没有高度地面A* 寻路同时也是可以使用的,但是对于一些地面比较复杂的游戏,寻路功能怎样实现比较好呢!

效果展示


1.RecastNavigation

相信了解过3d寻路的小伙伴都有听说过RecastNavigation。RecastNavigation是一款非常强大的寻路系统,被广泛的应用于各大游戏引擎中。如Unreal,Unity等。

NavMesh的生成基本原理:

  1. 体素化。从源几何体构造实心的高度场,用来表示不可行走的空间。
  2. 生成地区。将实心高度场的上表面中连续的区间合并为地区。
  3. 生成轮廓。检测地区的轮廓,并构造成简单多边形。
  4. 生成多边形网格。将轮廓分割成凸多边形。
  5. 生成高度细节。将多边形网格三角化,得到高度细节。

感兴趣的小伙伴们可以去了解一下,甚至可以去了解了解源码。源码也去看过,奈何自己C++实在太差

2.耳切法+A*

大概了解了导航寻路的原理,觉得整个寻路的关键可以分为两部分:网格画与寻路,所以决定自己尝试一下,现从最简单的没有高度的地图入手

大概步骤:

  • 1.基于耳切法实现地图的网格化
  • 2.基于A* 实现寻路
  • 3.基于漏斗算法将三角形集合进行路径最优解

    在最终的尝试下,基本的寻路功能是实现了,但是在路径的优化方面会存在一些问题,所以决定去寻找一些现成的js库来实现这个功能

3.NavMesh 导航

在github闲逛的时候发现了recast.js这个库,于是乎就开始花时间去了解了一下具体功能和API,同时还发现在Babylon.js这个3d游戏引擎中已经将其集成进去了,并且这个游戏引擎也是开源的,简直太完美了,

3.1 Cocos Creator3.x

花了点时间,成功将recast.js 移到了Cocos Creator3.x

  • recast.js js库
  • NavMesh.ts 功能实现

3.2 基础功能实现

1.初始化

import Recast from "./lib/recast.js"
...
public init(cb: Function = null):void{new Recast().then((recast) => {this._recast = recast;this._navMesh = new this._recast.NavMesh();this.setDefaultConfig();this._tempVec=new this._recast.Vec3();this._tempVec1=new this._recast.Vec3();this._tempVec2=new this._recast.Vec3();if (cb) cb();});
}

2.添加静态物体

/*** 添加静态的模型*/
public addStaticModle(node: Node): void {if(!node||!node.getComponent(MeshRenderer)) return;let render: MeshRenderer = node.getComponent(MeshRenderer);if (!render || !render.mesh) return;let matrix: math.Mat4 = node.getWorldMatrix();this.updateBaseDatas(render.mesh, matrix);
}

场景中一些固定不变的,比如地面,障碍物之类的可以通过这个结构进行添加,代码中对传入节点的网格信息进行处理,处理为recast所需要的格式,

3.生成导航网格

/*** 构建导航网格*/
public build(): void {var rc = new this._recast.rcConfig();rc.cs = this._config.cs;rc.ch = this._config.ch;....this._navMesh.build(this._positions, this._positions.length / 3, this._indices, this._indices.length, rc);
}

导航网格构建成功,对返回的导航数据进行了一些额外的处理,将其处理为cocos支持的网格数据形式,将导航网格部分最终显示到界面上(红色部分)

/*** 获取导航网格数据*/
public getNavMeshDebugData(): NavMeshData {...return { positions: positions, normals: normals }
}
/**创建网格*/
private createDebugMesh(positions: number[], normals: number[]): void {this.node.destroyAllChildren();let node = new Node();let render = node.addComponent(MeshRenderer);let mesh = utils.createMesh({positions: positions,primitiveMode: gfx.PrimitiveMode.TRIANGLE_LIST,normals: normals,});render.mesh = mesh;this.node.addChild(node);
}

4.寻路

 /*** 获取亮点之间的路径* @param start * @param end * 返回所有的路近点*/
public findPath(start: Vec3, end: Vec3):  Vec3[] {return positions;
}

总结

希望本次分享对大家有所帮助,demo中菜鸟对基础功能进行了分装,后续有时间还会逐渐完善补全,有兴趣的小伙伴可以去看看babylon.js 的源码以及使用,可以参照其进行功能的完善。

Cocos Creator3.x NavMesh导航网格寻路相关推荐

  1. Cocos Creator3.x NavMesh导航网格寻路(一)

    前言 在游戏开发过程中,寻路可能是大多数游戏都必不可少的功能.2d游戏中最常用的就是A* 寻路了.在3d游戏中,对于一些简单的,没有高度地面A* 寻路同时也是可以使用的,但是对于一些地面比较复杂的游戏 ...

  2. Cocos Creator3.x:NavMesh 导航网格寻路(二)

    前言 继Cocos Creator 3.x :NavMesh寻路后,菜鸟继续对寻路功能进行完善和测试,对除了web平台之外的其他平台进行支持与测试,目的是使咱们的寻路动能可以支持更多的场景. 在线体验 ...

  3. [unity3d]recast navigation navmesh 导航网格 寻路算法 源码分析

    recast navigation navmesh导航网格算法源码分析 Author:  林绍川 recast navigation navmesh是unity3d ue4内置的寻路算法 本文为了方便 ...

  4. 《UnityAPI.NavMesh导航网格》(Yanlz+Unity+SteamVR+云技术+5G+AI+VR云游戏+Unity+NavMesh+CalculatePath+立钻哥哥++OK++)

    <UnityAPI.NavMesh导航网格> 版本 作者 参与者 完成日期 备注 UnityAPI_NavMesh_V01_1.0 严立钻 2020.08.27 #<UnityAPI ...

  5. NAV导航网格寻路(4) -- 生成nav网格

    这篇是转的文章,原文 http://blianchen.blog.163.com/blog/static/131056299201037102315211/ 假设上图是一个游戏地图,红色的区域是不可行 ...

  6. COPY NAV导航网格寻路(4) -- 生成nav网格

    假设上图是一个游戏地图,红色的区域是不可行走的区域,浅灰色区域是可行走区域,要想在游戏中实现nav寻路,必须将可行走区域转化为nav网格并保存为一种固定形式的数据,如下图浅红色的三角形. nav网格必 ...

  7. 《UnityAPI.NavMeshAgent导航网格代理》(Yanlz+Unity+SteamVR+云技术+5G+AI+VR云游戏+Unity+NavMeshAgent+立钻哥哥++OK++)

    <UnityAPI.NavMeshAgent导航网格代理> 版本 作者 参与者 完成日期 备注 UnityAPI_NavMeshAgent_V01_1.0 严立钻 2020.09.10 # ...

  8. 在Unity中使用NavMesh导航

    In this tutorial we will learn about Navmesh in Unity, how to create it and use it on your game as p ...

  9. 了解导航网格 Navigation Mesh

    原文:https://www.jianshu.com/p/490a9128b248 这篇文章,首先会介绍什么是导航网格,它在 3D 游戏中起到了什么样的作用.然后会介绍目前导航寻路最常用的第三方开源库 ...

最新文章

  1. HDU 6051 - If the starlight never fade | 2017 Multi-University Training Contest 2
  2. 深入剖析防火墙策略的执行过程
  3. sizeof()与strlen()的区别与联系
  4. 第七章 ReentrantLock总结
  5. linux服务器调用端口超时,Linux服务器可以ping,但是telnet端口超时,网站wget超时,访问超时的解决办法...
  6. 【AI白身境】只会用Python?g++,CMake和Makefile了解一下​​​​​​​
  7. 读书精要《从一到无穷大》
  8. css3 box-shadow阴影(外阴影与外发光)讲解
  9. iview table增加一行减少一行_OA协会领导一行赴深圳市办公设备租赁行业协会参观交流...
  10. Linux使用命令 笔记
  11. 0507Python基础-set-深浅copy
  12. 怎么用计算机拟合函数wps,如何在excel 里利用曲线拟合的方式求公式|
  13. Java获取本地ip地址
  14. 七问个税改革:工薪阶层为何感觉税负重
  15. 坚定推动DDD落地的企业,70%代码效率翻倍了!
  16. Linux下串口编程总结
  17. border渐变 ios_iOS实现颜色渐变
  18. 骑士飞行棋 c语言代码,骑士飞行棋源代码.doc
  19. sublime text3安装python插件和flake8_让你用sublime写出最完美的python代码--windows环境-搜云库...
  20. java IO流之一 IO流介绍

热门文章

  1. 最短路径问题学习心得
  2. mysql date_format
  3. 【学习】日期函数:5、计算用户的平均次日留存率
  4. rosedb 上 Github Trending 啦!
  5. MySQL之数据库设计六个步骤
  6. 最近特别火的给Emoji表情加小辫子,双端通用方法来了
  7. C++的四种类型转换
  8. 基于区域生长和形态学处理的图像融合方法——Matlab图像处理
  9. 初学JavaScript输出语句
  10. js中请求URL获得json数据,将数据解析并建表插入