更新记录

1.0.0(2026-07-19)

首发:自研高性能原生室内寻路核心:栅格 A*(对象型 NavGrid,4/8 向、运行时增删障碍、扁平 [x,y] 路径) + 路点图 Dijkstra(跨楼层,边带


平台兼容性

uni-app x(5.14)

Chrome Safari Android iOS 鸿蒙 微信小程序
5.0 12 × ×

nex-navmesh · 室内寻路(栅格 A* + 路点图)

自研高性能原生室内寻路核心,提供 uni-app 可调的 JS API。无额外系统依赖。

两种寻路

  • 栅格寻路(对象型 NavGrid):固定宽高的二维栅格,每格可走/障碍;A* 最短路,支持 4 向(正交)与 8 向(含对角,禁止穿墙角)。返回扁平 [x,y]×N 路点数组,障碍可运行时增删。
  • 路点图寻路(自由函数 findPathGraph):任意带权有向图,Dijkstra 最短路;边带 weight 与可选 kindelevator/stairs 等楼层转换标记),天然支持跨楼层导航(电梯/楼梯按权重择优)。

适用:商场/医院/展馆室内导航、停车场寻车位、游戏地图寻路、机器人/AGV 路径规划、栅格地图最短路。

支持 App 端(Android / iOS)H5 端NavGrid 全方法 + findPathGraph 全量可用; H5 端建议应用启动时 await ensureReady() 一次);小程序不支持。 uni-app x(uvue)与经典 uni-app(vue3)都可引入。

API(8 个)

栅格寻路(对象型 NavGrid)

成员 签名 说明
构造 new NavGrid(width: number, height: number, blockedJson: string) 建栅格;blockedJson = [[x,y],...] 障碍格(空串或 [] 表示无障碍)
方法 width(): number / height(): number 栅格宽 / 高(格)
方法 isBlocked(x, y): boolean 某格是否障碍
方法 setBlocked(x, y, blocked: boolean): void 运行时设置某格障碍/可走
方法 findPath(sx, sy, ex, ey, diagonal: boolean): number[] A* 最短路,返回扁平 [x,y]×N(含起止);无路(含起/止被障碍)返回 []
方法 gridPathLength(sx, sy, ex, ey, diagonal: boolean): number 最短路代价(格数:正交步 1.0、对角步 ≈1.4);无路返回 -1

路点图寻路(自由函数)

函数 签名 说明
findPathGraph findPathGraph(nodesJson, edgesJson, startId, endId): string 带权有向图 Dijkstra,返回 JSON 路径(见下)

约定(重要)

  • 坐标系:原点 (0,0) 在左上角,x 向右、y 向下(瓦片/canvas 坐标系)。
  • 越界即抛错:坐标 x ≥ widthy ≥ heightOutOfBounds;绝不闪退。
  • 无路返回空findPath 无路返回 []gridPathLength 返回 -1(不是抛错)。
  • 对角禁止穿墙角:8 向模式下,对角步要求两侧正交邻格都可走(不会从两堵墙的拐角缝里穿过)。
  • 图边有向findPathGraph 的边是 from→to 单向,需双向请加反向边;平行边自动取较小权那条。
  • 代价用缩放整数(内部):栅格正交=10/对角=14,图边 weight ×1000 取整——避免浮点比较的不确定性,结果确定可测。

最小用法(栅格绕障)

import { NavGrid, findPathGraph } from '@/uni_modules/nex-navmesh';

// 5×5 栅格,列 x=2 的 y=0..3 设为障碍(仅留缺口 (2,4))
const g = new NavGrid(5, 5, '[[2,0],[2,1],[2,2],[2,3]]');

const path = g.findPath(0, 0, 4, 0, false);   // 正交 A*,绕到缺口
for (let i = 0; i < path.length; i += 2) {
  const x = path[i], y = path[i + 1];
  // 用 (x, y) 画路点 / 连线
}
if (path.length === 0) { /* 无路 */ }

g.setBlocked(2, 4, true);                       // 运行时把缺口也堵上
const len = g.gridPathLength(0, 0, 4, 0, true); // 对角模式代价;-1 = 无路

跨楼层路点图

const nodes = JSON.stringify([
  { id: '1F-门口' }, { id: '1F-电梯口' },
  { id: '2F-电梯口' }, { id: '2F-A区' },
]);
const edges = JSON.stringify([
  { from: '1F-门口', to: '1F-电梯口', weight: 8 },
  { from: '1F-电梯口', to: '2F-电梯口', weight: 3, kind: 'elevator' }, // 乘电梯跨楼层
  { from: '2F-电梯口', to: '2F-A区', weight: 6 },
]);

const out = findPathGraph(nodes, edges, '1F-门口', '2F-A区');
const r = JSON.parse(out);
// r = { found: true, path: ['1F-门口','1F-电梯口','2F-电梯口','2F-A区'],
//       cost: 17, edges: [ {from,to,weight,kind}, ... ] }
// r.edges[i].kind === 'elevator' 即可提示「此处乘电梯」

findPathGraph 返回的 JSON 结构:

字段 类型 说明
found boolean 是否找到路径
path string[] 节点 id 序列(含起止;无路时为 []
cost number 路径总代价(各段 weight 之和;无路时 0)
edges {from,to,weight,kind}[] 路径分段;kind 为该段标记(如 elevator),无则 null

错误处理

构造与坐标方法在参数非法时 throwInvalidParam(宽高为 0 / 栅格过大 / 图规模超上限 / 权重为负或非有限 / 起止 id 不在节点集)、OutOfBounds(坐标越界)、Parse(JSON 非法)。所有非法输入都被挡在边界,绝不闪退,调用方按需 try/catch。

边界

纯几何/拓扑寻路:不含动态避障、实时重规划、转弯半径/平滑、A* 之外的路径平顺化。栅格上限约 400 万格(≈2000×2000)防 OOM。

完整 API、错误码、栅格/图两类配方见仓库 docs/navmesh-plugin-contract.md

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据。所有计算/处理均在本地完成,无任何网络请求、不发送数据到任何服务器。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。