Cocos Creator | 导航网格自动寻路:多角色寻路、动态规避障碍物、上/下坡度等
01
效果演示
Cocos Creator 版本:3.4.1
该 demo 演示了增加/删除角色、增加/删除障碍物、多角色寻路、动态规避障碍物、上/下坡度、显示/关闭导航网格及实时路径
02
导航网格简介
RecastNavigation:
https://github.com/recastnavigation/recastnavigation
谷歌开源的一款非常强大的寻路系统,被广泛的应用于各大游戏引擎中
demo 中的素材是取自该系统
Babylon.js:
https://doc.babylonjs.com/extensions/crowdNavigation
微软开源的基于 web 的 3D 游戏引擎
recast.js 也是取自该引擎
个人理解:
根据一系列 mesh 中的顶点信息,实时计算可达路径
03
准备工作
1拷贝相关代码
将 Babylon.js 源码中 recast.js 相关的代码拷贝到自己的项目中
把 INavigationEngine.ts 和 recastJSPlugin.ts 看一遍,便可以基本了解他们的使用方法
2导入 recast.js
这里将 recast.js 以插件脚本的形式导入
关于插件脚本的官方文档:
https://docs.cocos.com/creator/manual/zh/scripting/external-scripts.html
04
实现方法
Babylon.js 中有详细的使用介绍以及参数说明:
https://doc.babylonjs.com/extensions/crowdNavigation/createNavMesh
1初始化 recast.js
之前已经将 recast.js 以插件脚本的形式导入了,这里可以直接使用
let recastInjection = await new Recast();
this.recastJSPlugin = new RecastJSPlugin(recastInjection);
2初始化 NavMesh
根据场景需求设定合适的导航网格参数,每个参数的意义在 d.ts 中都有详细的说明
let navmeshParameters: INavMeshParameters = {
cs: 0.2,
ch: 0.2,
walkableSlopeAngle: 35,
walkableHeight: 3,
walkableClimb: 2,
walkableRadius: 1,
maxEdgeLen: 12.0,
maxSimplificationError: 1.3,
minRegionArea: 8,
mergeRegionArea: 20,
maxVertsPerPoly: 6,
detailSampleDist: 6,
detailSampleMaxError: 1,
tileSize: 16,
};
this.recastJSPlugin.createNavMesh(meshRenderers, navmeshParameters);
this.recastJSCrowd = this.recastJSPlugin.createCrowd(10, 1) as RecastJSCrowd;
这里需要对 recastJSPlugin.ts 中的 createNavMesh 做一下适配,根据 cocos 的 mesh 创建导航网格
其中 meshRenderers 的类型为 MeshRenderer[],我们收集需要的模型来构建导航网格
为了收集方便,我们可以将模型都集中到一个节点下,然后通过下面的代码来获取该节点下所有的 MeshRenderer 组件
node.getComponentsInChildren(MeshRenderer);
根据 MeshRenderer 组件可以获取该模型中 mesh 的顶点位置及索引数据
不过这里获得的顶点位置是相对坐标,我们需要转换成世界坐标
for (pt = 0; pt < info.positions.length; pt += 3) {
Vec3.fromArray(position, info.positions, pt);
Vec3.transformMat4(transformed, position, worldMatrix);
positions.push(transformed.x, transformed.y, transformed.z);
}
最后将收集到的所有顶点位置和索引数据传递给 NavMesh,以此来构建导航网格
let { positions, offset, indices } = this.getMeshData(meshRenderers);
this.navMesh.build(positions, offset, indices, indices.length, rc);
3角色
· 创建角色
根据角色形象设定合适的角色参数,同样可以在 d.ts 中找到参数的详细说明
addAgent 返回该角色的唯一 ID,后续的一系列操作都要基于该 ID
addAgent(position: Vec3, agentParams?: IAgentParameters) {
position = this.recastJSPlugin.getClosestPoint(position);
if (!agentParams) {
agentParams = {
radius: 0.5,
height: 1,
maxAcceleration: 20,
maxSpeed: 6,
collisionQueryRange: 2.5,
pathOptimizationRange: 0,
separationWeight: 1,
};
}
let agentIndex = this.recastJSCrowd.addAgent(position, agentParams);
return agentIndex;
}
· 删除角色
根据角色 ID,删除该角色
this.recastJSCrowd.removeAgent(id);
4寻路
根据角色 ID,导航至目的地,如果目的地不可达,会自动导航至离目的地最近的位置
this.navMeshAgent.agentGoto(agentID, targetPosition);
也可以主动获取目的地最近的可达位置,然后导航至此
this.recastJSPlugin.getClosestPoint(position);
需要在 update 中驱动导航网格,才能实时获取到角色的最新状态
update(deltaTime: number) {
if (this.recastJSCrowd) {
this.recastJSCrowd.update(deltaTime);
}
}
根据角色 ID,获取角色在导航网格中的坐标,设置其位置
node.setPosition(this.recastJSCrowd.getAgentPosition(id));
根据角色 ID,获取角色当前的速度向量,设置其朝向
为了避免发生一些鬼畜行为,这里对速度向量做一个过滤
let vel = this.navMeshAgent.getAgentVelocity(id);
if (vel.length() > 0.2) {
node.forward = vel;
}
5障碍物
· 创建障碍物
recast.js 提供了两种障碍物类型的动态创建
圆柱体:
let obstacle = this.recastJSPlugin.addCylinderObstacle(position, radius, height);
立方体:
let obstacle = this.recastJSPlugin.addBoxObstacle(position, extent, angle);
· 删除障碍物
根据创建障碍时返回的信息可以直接删除
this.recastJSPlugin.removeObstacle(obstacle);
6调试信息
· 导航网格
创建导航网格显示所需的节点及材质
initDebugNavMesh() {
this.debugMaterial = new Material();
this.debugMaterial.initialize({
effectName: "unlit",
defines: {
// USE_ALBEDO_MAP: true,
},
states: {
primitive: gfx.PrimitiveMode.LINE_STRIP,
rasterizerState: {
cullMode: gfx.CullMode.NONE,
}
},
});
this.debugMaterial.setProperty("mainColor", Color.RED);
this.nodeDebugNavMesh = new Node("DebugNavMesh");
let meshRenderer = this.nodeDebugNavMesh.addComponent(MeshRenderer);
meshRenderer.setMaterial(this.debugMaterial, 0);
this.nodeDebugNavMesh.parent = director.getScene();
}
recast.js 中获取导航网格信息后,使用 utils.createMesh 创建 mesh,然后赋值给 meshRenderer
let mesh = utils.createMesh({ positions: positions, indices: indices, doubleSided: false, primitiveMode: gfx.PrimitiveMode.LINE_STRIP });
meshRenderer.mesh = mesh;
· 路径
recast.js 可以根据起始点和目标点计算出当前路径,但该路径不是一成不变的
let pathPoints = this.recastJSPlugin.computePath(start, end);
然后使用 Line 组件将该路径画出来
let node = new Node();
node.parent = agent;
let linePath = node.addComponent(Line);
linePath.worldSpace = true;
linePath.width.constant = 0.2;
linePath.color.color = Color.GREEN;
linePath.positions = pathPoints;
完整 demo:
子曰:“不患人之不己知,患不知人也。”
【解读】
孔子教育学生,在处世上要有人不知而不愠的精神,能够在寂寞中做成应该做的事业,完成应该具有的仁德修养。学,是为了自己的进步,而不要把精力用于怨天尤人上。处世是需要了解别人的,自己心态平和,才能真实地了解别人。不去苛求别人,要把精力用于提升自己的能力上。君子不担心没有人了解自己,不忧虑不能树立美好的名声,只忧虑自身的修养不够深厚,不能去充分了解别人。
更多教程
请扫码关注
Cocos Creator | 导航网格自动寻路:多角色寻路、动态规避障碍物、上/下坡度等相关推荐
- 麒麟子Cocos Creator 3D研究笔记三:角色换装(无动画)
零.效果展示 先来两张图 在线演示地址: https://showcase.ukylin.net/avatar/ 3D换装有两种情况,一种是身体各部件(如头发.上衣.裤子.手套.鞋子等身体各部分),另 ...
- 麒麟子Cocos Creator 3D研究笔记四:天空盒动态更换与IBL效果
麒麟子Cocos Creator 3D研究笔记之材质IBL与天空盒动态切换 在线演示地址: https://showcase.ukylin.net/skybox/ 天空盒对于3D渲染场景来说,有着不个 ...
- 【Cocos Creator】 使用 TTF 以及文本配置动态生成位图字体的解决方案
游戏开发,需要使用字体. 直接使用 TTF 字体,其优点是开发特别省事. 而缺点却是很要命: TTF 字体文件过大,包含了不必要的字,增大了包体,减缓了加载速度: 部分平台不支持 TTF 文件的加载: ...
- Cocos Creator 性能优化:DrawCall
Cocos Creator 性能优化:DrawCall(全面!) title: Cocos Creator 性能优化:DrawCall 前言 在游戏开发中,DrawCall 作为一个非常重要的性能指标 ...
- Cocos Creator - 动态合图(dynamicAtlasManager)
步骤 Cocos Creator - 动态合图(dynamicAtlasManager) 前言 启用.禁用动态合图 贴图限制 支持定制的渲染组件 调试 总结 Cocos Creator - 动态合图( ...
- 大神驾到 | 腾讯光子大牛的 Cocos Creator 网络通用框架(强势围观)
编者按 作者,宝爷.宝爷是光子工作室的开发工程师,谦称自己为一枚码农,是一个热爱游戏.热爱开发.热爱学习并坚持沉淀知识的开发者,曾写过<精通 Cocos2d-x 游戏开发>基础卷与进阶卷, ...
- Cocos Creator3.x NavMesh导航网格寻路(一)
前言 在游戏开发过程中,寻路可能是大多数游戏都必不可少的功能.2d游戏中最常用的就是A* 寻路了.在3d游戏中,对于一些简单的,没有高度地面A* 寻路同时也是可以使用的,但是对于一些地面比较复杂的游戏 ...
- Cocos Creator3.x NavMesh导航网格寻路
前言 在游戏开发过程中,寻路可能是大多数游戏都必不可少的功能.2d游戏中最常用的就是A* 寻路了.在3d游戏中,对于一些简单的,没有高度地面A* 寻路同时也是可以使用的,但是对于一些地面比较复杂的游戏 ...
- Cocos Creator3.x:NavMesh 导航网格寻路(二)
前言 继Cocos Creator 3.x :NavMesh寻路后,菜鸟继续对寻路功能进行完善和测试,对除了web平台之外的其他平台进行支持与测试,目的是使咱们的寻路动能可以支持更多的场景. 在线体验 ...
- [unity3d]recast navigation navmesh 导航网格 寻路算法 源码分析
recast navigation navmesh导航网格算法源码分析 Author: 林绍川 recast navigation navmesh是unity3d ue4内置的寻路算法 本文为了方便 ...
最新文章
- 微信小程序 点击卡片切换 动画效果
- PHP 获取数组最后一个值
- Entity Framework 出现 此 ObjectContext 实例已释放,不可再用于需要连接的操作 的错误...
- 实现框架页面iframe的背景透明方法
- Luogu P2920 时间管理【二分答案】
- 091_类数组对象转为数组
- 数据结构和算法解:第九章 算法设计技巧
- 科技谋定功能性农业-农业大健康:中科微研携手从玉农业
- 汇编--两种过程定义的方式,调用方式。
- 蓝桥杯第五届省赛JAVA真题----七对数字
- android 应用切换滑动,Android应用中利用ViewPager实现多页面滑动切换效果示例
- python中对象的概念是什么_python面向对象编程的基本概念
- 使Fiddler4抓包微信小程序
- 在Outlook 2013中发送给多个收件人时如何隐藏电子邮件地址
- 曹则贤:从一元二次方程到规范场论 | 中国科学院2022跨年科学演讲
- CTex下载地址和方法
- 网站克隆工具_科研|值得收藏的分子生物学必用工具(第二弹~)
- 百度地图瓦片下载工具(仅供学习)
- 8位可控加减法电路设计
- java excel checkbox_在Java窗体表格中插入复选框
热门文章
- 计算机多媒体话筒声音怎么调,音频调节器怎么调试麦克风 音频调节器调试麦克风方法介绍...
- kali linux 源码免杀,shellcode超级免杀
- 进行单元测试时一直报这个错,原因是缺少aspectjweaver包
- 中彩分析家 v7.18 build 1203 怎么用
- 利用树莓派为HP LaserJet 1020配置无线打印功能
- 用WPS2000制作勾股定理教学课件(转)
- TimesTen In-Memory Database
- 软件工程工具图(软件开发过程中可能用到的工具图)
- 浅谈大比例尺数字地形图的缩编方法
- idea设置炫酷主题