UI、屏幕、世界坐标来回转换:Unity 常见矩阵应用

如果说矩阵在 Shader 里属于“你迟早要懂”,那在客户端业务里,最常见的高频落点其实是坐标转换。

这也是我自己觉得最值得早点学的一块。因为很多客户端问题表面上像 UI 逻辑,实际上最后都会追到“这个点现在到底在哪个空间”上。

尤其是这些需求:

  • 3D 角色头顶挂血条
  • 点击屏幕落到地面
  • 世界物件映射到 UI 红点
  • 小地图图标和场景位置同步

这些本质上都在做一件事:跨坐标空间翻译。

一、先分清几个常见空间

在 Unity 里,最容易混的通常有这几种:

  • 世界空间
  • 屏幕空间
  • 视口空间
  • UI 本地空间

如果不先分清语义,后面 API 调得再多也只是碰运气。

1. 世界空间

场景里物体真实存在的位置。

2. 屏幕空间

通常是像素坐标,左下或左上为原点要看具体上下文。

3. 视口空间

归一化后的屏幕比例坐标,一般在 [0,1] 范围。

4. UI 本地空间

相对于某个 RectTransform 的局部二维坐标。

二、为什么“世界点挂 UI”本质上不是一个步骤

很多人第一次做头顶血条,会以为只需要把 3D 位置塞给 UI。

实际上至少经历两段:

  1. 世界空间 -> 屏幕空间
  2. 屏幕空间 -> 某个 Canvas 或 RectTransform 的局部空间

这两段背后其实都和相机投影、矩阵变换有关。

三、WorldToScreenPoint 是最常见入口

例如:

1
Vector3 screenPos = camera.WorldToScreenPoint(worldPos);

它做的不是简单减法,而是把世界点走过相机的观察和投影过程,最终得到屏幕位置。

所以如果结果不对,问题不一定在 UI,也可能在:

  • 相机选错了
  • 点在相机后方
  • 使用了错误的渲染相机

四、为什么拿到屏幕坐标后还不能直接给 UI

因为 UI 不是天然就和屏幕像素一一对应。

特别是 Canvas 处于不同模式时:

  • Screen Space Overlay
  • Screen Space Camera
  • World Space

处理方式都可能不同。

很多时候你还要进一步做:

1
RectTransformUtility.ScreenPointToLocalPointInRectangle(...)

把屏幕点换成某个 UI 根节点的局部点。

一个常见写法大概会像这样:

1
2
3
4
5
6
7
8
9
Vector3 screenPos = camera.WorldToScreenPoint(target.position + offset);

RectTransformUtility.ScreenPointToLocalPointInRectangle(
uiRoot,
screenPos,
canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : camera,
out Vector2 localPoint);

marker.anchoredPosition = localPoint;

这段代码看起来只是几行转换,但它其实已经把“世界 -> 屏幕 -> UI 本地”这条链走完了。

五、点击屏幕打到世界,也是反向变换

另一个高频需求是:

玩家点屏幕某个位置,我想知道场景里对应哪里。

这通常不是“直接得到 3D 点”,而是:

先从屏幕点发射一条射线,再和场景中的平面、碰撞体相交。

比如:

1
Ray ray = camera.ScreenPointToRay(screenPos);

这背后其实就是把二维屏幕输入重新解释回三维世界方向。

六、小地图、本地雷达、战斗提示都在做类似的空间投影

很多业务系统表面看起来不一样,但底层都类似:

  • 小地图把世界平面位置压到一张 2D 贴图坐标里
  • 战斗指示器把世界范围映射到屏幕角标
  • 任务箭头把 3D 方向转成 UI 旋转

本质都是:

找对中间空间,然后做稳定的坐标变换。

七、为什么 UI 跟随经常“抖”或“飘”

常见原因通常有这些:

  1. 更新时机不对,角色已经动了,UI 还没跟上
  2. 使用了错误的相机
  3. 没处理物体在相机后方的情况
  4. 直接拿屏幕坐标硬塞局部坐标
  5. Canvas 缩放规则没有考虑进去

所以这种问题不要只盯数值,先把空间链路画出来更有效。

八、一个很实用的排查顺序

如果世界点映射 UI 有问题,我一般会按这个顺序查:

  1. 世界点本身是不是对的
  2. WorldToScreenPoint 输出是不是合理
  3. 目标 Canvas 模式是什么
  4. UI 根节点的本地坐标系是不是理解对了
  5. 最后是不是又叠加了额外偏移

这比一上来疯狂调 offset 高效很多。

九、矩阵知识在这里真正帮到你的地方

你不一定需要手推 VP 矩阵,但你要知道:

  • 世界到屏幕不是魔法,是投影变换
  • 屏幕到 UI 不是直接赋值,是另一个空间映射
  • 相机决定了中间变换规则

只要这个认知有了,很多坐标转换问题都会从“玄学”变成“可拆解流程”。

十、总结

UI、屏幕、世界坐标的来回转换,是 Unity 客户端里最实用的一类矩阵应用。

它看起来不像 Shader 那么“图形学”,但本质上用的是同一套空间变换思想。

下一篇我会继续讲更偏工程排查的一面:InverseTransformPointMultiplyPoint、Gizmos 这些工具怎么组合起来定位矩阵问题。