UI中的坐标系统

※ UE版本: 5.1.1, 系统: Windows 10
※ 最后更新日期: 2023-12-14

坐标系统简介

坐标系与DPI缩放

常见的UI系统都习惯以左上角作为坐标系的原点,往右为x轴正方向,往下为y轴正方向,SlateUI也不例外。

屏幕坐标系示意图

为了使UI界面能够自动适应各种不同分辨率的显示设备,SlateUI使用DPI缩放来控制UI元素的整体尺寸。

所谓DPI缩放(DPI Scale),其实只是一个浮点值,这个值的大小为视口坐标空间中单位长度与显示器实际像素长度的比值。
举个例子:

  1. 若显示器分辨率为1920px × 1080px,游戏视口实际大小为1280px × 720px,则此时DPI缩放的值为0.67。
  2. 若显示器分辨率为3840px × 2160px,游戏视口实际大小为1920px × 1080px,则此时DPI缩放的值为1.0。
  3. 若显示器分辨率为3840px × 2160px,游戏视口实际大小也为3840px × 2160px,则此时DPI缩放的值为2.0。

从上面的例子可以看出,SlateUI希望游戏视口内的坐标空间范围尽量接近1920×1080,好让开发者能够忽略不同用户显示设备的差异,用统一的标准设计和实现UI功能。

SlateUI中的坐标空间

SlateUI中有三种坐标空间:绝对空间(也叫屏幕空间)视口空间本地空间。这几个坐标空间仅在下面两个属性上存在差异:

  1. 原点位置
  2. 是否经过DPI缩放

下面对每个类型的坐标空间进行解释。

绝对空间,以显示器的左上角为坐标原点,并且绝对空间的像素大小未经过缩放,坐标中的像素大小就是物理像素的大小。

绝对空间坐标示意图

“获取平台上鼠标位置(GetMousePositionOnPlatform)”节点获取到的就是这个坐标。

视口空间,以游戏视口左上角为原点,坐标空间中的像素大小经过缩放,需要乘上DPI Scale才能得到物理像素下的大小。

视口空间坐标示意图

本地空间,以父控件左上角为原点,坐标空间中的像素大小也经过缩放,需要乘上DPI Scale
本地空间坐标示意图

蓝图中常见的坐标节点

蓝图中有很多与坐标相关的节点,刚接触UMG坐标的朋友容易对这些节点返回的坐标类型感到迷惑,这里特别列举一些常用的节点。

获取鼠标坐标

从鼠标事件中获取

本地到视口

本地到视口这个节点有些特殊,它传出的Viewport Position是正常的视口空间坐标,但Pixel Position是以视口左上角为原点的绝对坐标,也就是使用Viewport Position直接乘DPI Scale得到的坐标。这个Pixel Position很奇怪,大多数场景下都不能直接使用。

另外,如本地到视口节点这样需要传入一个几何体Geometry的节点,另一个传入的本地坐标参数Local Coordinate是以此几何体做参考系的本地空间。也就是说,这里传入的(0, 0)其实指的是几何体Geometry的左上角!

几何体FGeometry

TODO: 绘制空间几何体

TODO: Tick空间几何体

TODO: 缓存空间几何体

双屏和双游戏窗口

TODO

绝对空间:
绝对空间仅与显示器有关。双屏时仍然以主屏左上角为原点,若副屏在主屏左侧,则副屏的坐标会从左侧与主屏坐标拼接,如图所示。

双屏绝对空间

视口空间:
TODO

参考文章

  1. DPI 缩放 https://docs.unrealengine.com/5.1/zh-CN/dpi-scaling-in-unreal-engine/
  2. Calculating widget coordinate in UnrealEngine