Cocos Creator3.x 你们要的导航网格寻路(Nav Mesh )2.0 版本来了
前言
咱们的Nav Mesh 导航网格寻路插件Cocos Creator3.x NavMesh导航网格寻路,Cocos Creator3.x NavMesh导航网格寻路(二)已经上线一年半了。累计出售已经超过了100份:
在这一年半的时间中,宗宝在使用过程中对插件逐步进行完善,尽可能的去提高使用的方便性;在这期间也有不少小伙伴咨询插在使用过程中遇见的问题。
下边宗宝将带来NavMesh导航寻路的全新版本,以及将小伙伴在使用期间遇见的问题进行统统一回复
Nav Mesh(导航寻路) 2.0
1.组件化(NavMeshComponent)
经过考虑,组件化是必然的;也是体验相对比较好的方式;
1).创建方式
- 1.层级管理器点击坐标右键
- 2.选择最下边的Nav Mesh选项
此时层级管理器中会自动创建 “Nav Mesh” 节点,并且此节点将自动添加NavMeshComponent组件;注意:当前场景只运行添加一个挂有NavMeshComponent组件的节点
2).组件
那么NavMeshComponent在属性设置上总共分为五个模块:
- 1.参与网格构建节点(节点绑定)
- 2.属性配置(构建属性配置)
- 3.调试(编辑器调试模式)
- 4.导入构建数据(导入外部已有数据进行快速构建)
-
5.构建数据导出(导出构建的网格数据到本地)
接下里宗宝就每个模块按个和大家介绍一下
1.组件:参与网格构建节点
导航网格构建的前提是建立在网格数据的基础上;此处可以将进行绑定参与构建的节点;child属性决定了是只取当前节点的网格数据,还是说除了当前绑定节点以外还会取所有的子节点的网格数据;在使用过程中可以根据场景节点结构自己决定;
2.组件:属性配置
3.组件:调试
当调整完设置配置后,肯定是希望第一时间去查看对应的构建之后的网格数据
调试模块:宗宝添加了两种配置,分别是调试网格的类型面和线;以及调试的颜色配置
- Build 按钮:可以根据配置的属性参数进行网格数据构建,构建后自动的显示调试效果
-
Clear 按钮: 清除现在的场景编辑器中的调试效果
黑色,线条
蓝色,面
4.组件:导入构建数据
本地NavMesh数据导入调试
5.组件:构建数据导出
构建导航网格数据一键导出;这是常用的优化手段之一;运行时构建是一个比较耗时的操作,如果能提前将构建好的数据存储在本地,运行时直接加载生成,可以大大减少耗时;
- Export Data 按钮:可以快速构建,并将构建后的数据以二进制的形式存储在项目的asset目录下,默认文件名称为:nav-mesh.bin
2.接口
组件内部对常用的接口进行了封装,以便外部调用
/**
* 构建
* 基于绑定的节点,进行导航网格的构建
*/
public build(): void {
...
}
/**
* 渲染debug调试网格
*/
public bakeDebugBuild(): void {
....
}
/**
* 基于加载的本地数据生成导航网格
*/
public buildFromNavMeshData(data: Uint8Array): void {
....
}
/**
* 获取起点到终点的路径
* @param start
* @param end
* @returns
*/
public getPath(start: Vec3, end: Vec3): Vec3[] {
...
}
/**
* 获取传入坐标在Nav Mesh 网格中距离最近的坐标点
* @param pos
* @returns
*/
public getClosestPoint(pos: Vec3): Vec3 {
...
}
/**
* 添加圆柱形障碍物
* @param position 位置
* @param radius 半径
* @param height 高
* @returns
*/
public addCylinderObstacle(position: Vec3, radius: number, height: number): IObstacle {
...
}
/**
* 添加立方体障碍物
* @param position 位置
* @param size 尺寸
* @param angle 盒子方向在Y轴上的弧度角
* @returns
*/
public addBoxObstacle(position: Vec3, extent: Vec3, angle: number): IObstacle {
...
}
/**
* 创建人群
* @param maxAgents 人群中代理的数量
* @param maxAgentRadius 人群中代理的最大半径
* @returns 返回人群id
*/
public createCrowd(maxAgents: number, maxAgentRadius: number): number {
...
}
/**
* 添加代理
* @param crowdId 将要添加的目标人
* @param node
* @param conifg
*/
public addAgent(crowdId: number, node: Node, conifg: AgentConfig): number {
...
}
/**
* 设置代理的激活状态
* 如果需要自己控制代理的位置,state设置为false,非激活状态
* 非激活状态下不会同步位置等坐标
*/
public activeAgent(crowdId: number, agentId: number, state: boolean): void {
...
}
/**
* 代理移动到指定位置
* @param crowdId
* @param agentId
* @param target
*/
public moveAgent(crowdId: number, agentId: number, target: Vec3): void {
...
}
/**
* 将代理传送到指定位置
* @param crowdId
* @param agentId
* @param target
*/
public teleportAgent(crowdId: number, agentId: number, target: Vec3): void {
...
}
3.案例
为了方便大家理解,以及实际项目中的使用,宗宝基于新版本插件实现了两个简单demo;
大家可以通过上图中的步骤将示例工程导入到当前的项目中;
案例一
8主要以组件编辑器中的基本使用为例;
案例二
主要以代理寻路以及移动为例
常见问题解答
1.是否支持动态添加障碍物?
之前版本不支持,但是新的版本已经进行了支持;
2.动态添加障碍物不生效是为啥?
这也是咨询宗宝最多的问题,在添加动态障碍物时无法生效;这个问题分三个部分:
- 1.动态添加的障碍物不会对原构建的导航网格产生影响,只会对寻路的结果产生影响
-
2.动态添加障碍物生效的前提是:网格在构建是设置了合适的tileSize;
对比一下不设置tileSize和设置tileSize的效果
图一是不设置tileSize,图二是设置了tileSize;区别在于图一中是以三角形为单位,而图二中是以方格为单位;
tileSize的作用就是将导航网格方格化,当我们添加障碍物时会对受到影响的方格进行标记,从而在寻路的时候减少不必要的计算
-
3.障碍物的长,宽不能大于方格的尺寸
简单来说,就是你创建了一个立方块的障碍物,那么这个障碍物必须可以被网格能包住,如果障碍物的形状不固定,横跨多个方格,建议用多个标准障碍物进行拼接
3.内存不足
内存不足的主要原因是由于基于原场景模型进行导航网格构建时,原场景中的模型复杂度比较高,三角面数多导致的,
寻路本身就是一个近似的求解过程,所以可以用基础模型:Plane,Cube来近似的代替原模型进行网格数据的构建,这不仅可以避免内存不足的问题,还可以减少构建时的耗时,以及降低网格的复杂程度,从而进一步影响到寻路的效果;
写在最后
插件获取方式
Cocos Dashboard 商城中搜索"NavMesh导航网格寻路",作者账户:carlosyzy 进行下单
插件升级
宗宝经过考虑
- 1.原商城的插件保持不变;
商城中的原有插件为最原始的使用方式,大家在其基础上可以自行扩展和调整,扩展性比较强 - 2.新插件获取
新插件将不会再次上线Store,如有需求的可以添加宗宝微信联系方式"Carlos13207"