Skip to content

坐标系

背景

navmesh 升级后,导航数据改由新版 Recast Navigation 工具链生成。这里需要区分两个概念:

  • NavMesh 源模型、生成工具和底层 Detour 使用的坐标约定。
  • KBE Entity 通过客户端协议同步的位置和方向。

NavMesh 升级不会改变 Entity 协议中的位置顺序。KBE 仍然使用 Y 轴表示高度、XZ 作为水平面,位置按照 (x, y, z) 传入 Detour,路径点也按照 (x, y, z) 返回。

客户端是否需要转换位置,取决于客户端引擎自身的坐标定义。默认前向为 +Z-Z 主要影响模型朝向,不能据此直接交换位置的 Y/Z 轴。

基本约定

  • KBE 世界坐标使用 Y-up,水平面为 XZ。
  • Entity 位置字段顺序为 (x, y, z),NavMesh 升级不会自动改变该顺序。
  • 位置和朝向必须分开处理。位置轴一致时直接使用;模型默认前向不一致时只调整朝向。

旋转字段中:

  • x = roll
  • y = pitch
  • z = yaw

当前大部分客户端场景中,主要关注的是 yaw 的转换。

接入原则

  • 先确认客户端引擎的向上轴、水平轴、默认前向和长度单位。
  • 出生、普通位置更新、平滑移动、传送、服务端纠正和客户端回传必须使用相同规则。
  • 客户端回传服务端时执行下发映射的反向操作。
  • 模型朝向存在固定偏差时,优先调整模型或其渲染子节点;确需在代码中补偿时,保持下发和回传对称。

各客户端坐标转换

以下公式以 KBE Entity 坐标为输入,转换到当前配套 Demo 使用的客户端坐标。

Unity

Unity 侧需要对 x 轴做翻转。

位置:

text
x' = -x
y' = y
z' = z

朝向:

text
yaw' = -yaw

说明:

  • 由于协议中的 z 表示 yaw,也可以写成:yaw = -z

Cocos Creator

Cocos Creator 3.x 与 KBE 都使用 Y 轴表示高度,位置直接使用,不翻转 X,也不交换 Y/Z。

位置:

text
x' = x
y' = y
z' = z

朝向:

text
yaw' = yaw + 180

当前 Demo 中可以直接写:

ts
const targetPos = new Vec3(
    this.position.x,
    this.position.y,
    this.position.z
);
this.renderObj.setPosition(targetPos);

这里的 yaw + 180 用于适配 Demo 模型的默认前向,不属于位置转换。如果模型资源本身已经朝向正确,不应重复增加偏移。

Godot

Godot 4 与 KBE 都使用 Y 轴表示高度,位置同样直接使用。

位置:

text
x' = x
y' = y
z' = z

朝向:

text
yaw' = yaw + 180

当前 C# Demo 中的位置更新写法为:

csharp
((Node3D)this.renderObj).GlobalPosition = new Vector3(
    position.x,
    position.y + 1.0f,
    position.z
);

部分角色控制器会在 Y 轴增加角色高度偏移。该偏移需要在客户端回传时从 Y 轴减掉,它不是坐标轴转换。

Unreal Engine

UE 除了轴映射外,还需要注意长度单位差异。KBE 常用米制逻辑单位,而 UE 默认使用厘米,因此位置需要乘以 100

位置:

text
x' = x * 100
y' = z * 100
z' = y * 100

朝向:

text
yaw' = yaw + 90

对照汇总

客户端位置转换朝向转换
Unity(-x, y, z)yaw = -yaw
Cocos Creator(x, y, z)当前 Demo 模型:yaw = yaw + 180
Godot(x, y, z)当前 Demo 模型:yaw = yaw + 180
Unreal Engine(x * 100, z * 100, y * 100)yaw = yaw + 90

注意事项

  • 如果客户端还存在“客户端坐标回传服务端”的逻辑,必须实现反向转换,不能只做单向适配。
  • yaw + 180yaw + 90 后,建议统一做角度归一化,例如限制到 [-180, 180)[0, 360)
  • 不要把 +Z / -Z 默认前向差异直接理解成位置必须交换 Y/Z。
  • Cocos Creator 或 Godot 若使用 (-x, z, y),会把 Y 高度错误地换到 Z 轴,导致角色高度和水平位置异常。
  • NavMesh 二进制格式已经升级,旧 .navmesh 不能通过改名复用,必须用当前工具从场景源模型重新生成。