Cocos Creator3.x NavMesh导航网格寻路

前言

在游戏开发过程中,寻路可能是大多数游戏都必不可少的功能。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 的源码以及使用,可以参照其进行功能的完善。

<think>好的,用户想了解2D环境下的寻路算法及实现方法。首先,我需要整理常见的寻路算法,尤其是针对2D环境的。根据提供的引用内容,用户提到了A*算法、Theta*、ANYA等,还有相关的插件比如PolyNav和Navmesh2d。需要确保覆盖这些内容,同时结合具体实现方法。 首先,得从基础算法开始。比如A*算法,用户可能已经知道它是结合了起点距离和启发式函数,但需要详细解释它的原理和实现步骤。然后,可以提到其他改进算法如Theta*和ANYA,说明它们的优势和适用场景。此外,用户提到的插件使用也很重要,需要简要说明如何利用这些工具快速实现寻路功能。 接下来,要检查引用内容是否准确。引用[2]提到A*是结合了前两者的优点,这点要在回答中强调。引用[3]对比了ANYA和Theta*,需要指出它们的区别和适用情况。引用[4]和[5]提到的Unity和Cocos Creator实现方法,应该给出具体步骤或示例代码,帮助用户理解实际应用。 还要注意用户可能的实际需求,比如游戏开发中的寻路实现,所以需要提供插件和代码示例。例如,用Navmesh2d创建导航网格,或者用A*的TypeScript代码示例。同时,考虑用户可能需要进一步优化算法,所以相关的问题部分可以引导他们思考性能和应用场景。 另外,用户可能对算法的选择有疑问,比如何时使用A*,何时选择Theta*或ANYA。需要根据引用内容解释不同算法的适用环境,比如2D网格、动态障碍物处理等。同时,提到插件的使用可以简化开发流程,适合不熟悉算法细节的开发者。 最后,确保回答结构清晰,分点列出算法、实现方法和工具,并在最后生成相关问题,帮助用户深入探索。还要正确引用提供的参考资料,比如引用[3]和[4]中的插件信息,以及算法比较的内容。同时,注意使用正确的LaTeX格式,虽然用户的问题中没有数学公式,但回答中如果有需要的地方要符合格式要求。</think>### 2D环境下的寻路算法及实现方法 #### 一、常见2D寻路算法 1. **A*算法** - **核心原理**:结合$g(n)$(起点到当前节点的实际距离)和$h(n)$(当前节点到终点的启发式估计距离),通过代价函数$f(n) = g(n) + h(n)$选择最优路径[^2]。 - **适用场景**:网格地图、均匀代价环境,如策略游戏或机器人路径规划。 - **代码示例**(TypeScript): ```typescript class AStarNode { x: number; y: number; f: number; // 其他属性... } function findPath(start: Node, end: Node): Node[] { // 开放列表、关闭列表处理逻辑... } ``` 2. **Theta*** - **特点**:在A*基础上优化路径平滑度,允许节点间直线检测,减少冗余转折点[^3]。 - **优势**:适用于需要自然移动轨迹的场景,如RTS游戏单位移动。 3. **ANYA算法** - **创新点**:通过“任意角度”路径规划跳过网格限制,适合高自由度环境。 - **局限性**:主要适用于2D二值(无障碍/有障碍)网格地图,复杂地形需结合其他方法。 4. **Dijkstra算法** - **基础作用**:保证最短路径,但效率低于A*,常用于无启发式信息的场景。 #### 二、实现方法 1. **基于算法的手动实现** - **A*实现步骤**: 1. 定义网格数据结构; 2. 初始化开放列表和关闭列表; 3. 迭代计算$f(n)$并更新路径; 4. 回溯生成最终路径。 2. **使用现成工具/插件** - **Unity插件**: - **PolyNav**:支持动态障碍物和复杂多边形导航网格[^4]。 - **Navmesh2D**:通过烘焙2D导航网格实现高效寻路(步骤:创建导航网格 → 添加寻路组件 → 脚本调用)。 - **Cocos Creator**:结合A*算法拆解步骤的TS实现(参考引用[5]的Demo)。 3. **性能优化技巧** - **分层寻路**:将地图分为大区域预计算,再局部细化。 - **跳跃点搜索**(JPS):跳过对称路径,减少计算量。 - **动态障碍物处理**:局部重新规划而非全局更新。 #### 三、算法选择建议 | 算法 | 适用场景 | 复杂度 | 路径质量 | |----------|----------------------------|---------|---------------| | A* | 均匀代价网格 | $O(b^d)$| 最优 | | Theta* | 需要平滑路径 | 较高 | 接近最优 | | ANYA | 二值网格、任意角度移动 | 低 | 依赖地图划分 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿越的杨宗宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值