Unity2d世界坐标和逻辑坐标1:1对应 世界坐标与逻辑坐标对齐
背景
Unity 最初是作为 3D 游戏引擎而设计的,在 4.3 版本后才推出 UGUI 和 Sprite 用于 2D 游戏设计。在 UGUI 中使用的是屏幕坐标系(以像素为单位),而在 Unity 中依然使用 3D 坐标系中的 Unit 浮点单位。在导入 Texture2D 时,可以进行像素到单位(Unit)的转换设置。世界坐标系的坐标原点是屏幕中心点,这导致在实际开发中需要进行大量的世界坐标到屏幕坐标的转换操作。这个问题一直困扰着我,有时甚至让我抓狂,这也是我写这篇文章的初衷。
另外,Unity 系统使用中心点作为默认坐标系的原点,这在逻辑坐标(以地图为参照物)中物体移动时,无形中增加了坐标转换的难度。对我来说,最理想的方式是采用我们习惯的 Windows 坐标体系,至少要完成世界坐标、屏幕坐标及逻辑坐标(游戏地图)的原点对齐,以及实现世界坐标单位和屏幕坐标单位像素 1:1 对应。文字描述可能比较晦涩,下面我们通过几张图片来说明问题。
传统 Windows 的坐标系,其左上角为坐标原点,x 轴正方向向右,y 轴正方向向下。
Unity 中的坐标系,即世界坐标,原点是屏幕中心点,x 轴正方向向右,y 轴正方向向上。
默认情况下,世界坐标和屏幕坐标以屏幕中心为坐标系原点。导入的纹理图片默认也以图片中心点为原点,而非我们习惯的左上角或者左下角逻辑原点。例如,在左下角区域,以中心点作为坐标原点,该区域的坐标值为负值。这就与我们熟知的逻辑坐标存在一个差值,在进行逻辑坐标与世界坐标或者屏幕坐标转换时,就需要考虑这个差值。
实现
我们知道,屏幕显示的大小由摄像机的尺寸和分辨率决定。其中,摄像机的尺寸由属性面板中的 Size 属性确定,实际上该值是可视区域高度的一半,单位为 Unit。很多屏幕自适应程序的教程也是基于这个原理设计的,相关文章和帖子已经很多,这里就不详细阐述了。
我们要实现的最终效果,其实只需对 Unity 的世界坐标进行平移,具体操作是平移相机,如下图所示。
实际上,要实现世界坐标和逻辑坐标的一一对应,只需通过以下两个步骤:
- 统一世界坐标、屏幕坐标、逻辑坐标的单位;
- 设置世界坐标和逻辑坐标的原点相同(即(0, 0)点相同)。
统一坐标单位
首先,我们设置纹理(即图片)的 Size 单位。默认值是每 100 像素为一个单位,即在 Unity 3D 中 100 个像素对应一个 Unity 3D 的 Unit 单位。我们将这个值修改为每一像素对应一单位,具体设置如下图所示。
设置完成后,导入工程中的图片(纹理)就以像素为单位。简单来说,如果一张图片的尺寸是 300×400 像素,那么它的宽和高也就是 300×400 单位(Unit)。
接下来,我们设置合理的摄像机尺寸。参考屏幕自适应技术,我们选择一个固定的像素尺寸,这里选择 800×600。由于前面已将所有导入工程中的图片单位设置为一像素对应一单位(Unity),所以我们需要将摄像机的尺寸 Size 设置为可视区域分辨率高度的一半,即 300 单位。至此,我们完成了世界坐标系和逻辑坐标系的单位统一。
统一坐标原点
我们知道,默认的世界坐标系和屏幕坐标系以屏幕的中心为坐标系原点,而逻辑坐标原点采用图片的中心点作为原点,这不符合 2D 程序开发的习惯,因此需要统一坐标原点。Unity 3D 世界坐标系中,x 轴和 y 轴的方向分别是向右和向上,我们可以假设屏幕的左下角为原点(而传统的 Windows GUI 中,x 轴和 y 轴的方向是向右和向下,假设屏幕的左上角为原点)。
首先,我们将导入工程中的所有 2D 纹理的坐标点(中心点)设置为左下角(BottomLeft)点。然后,对相机进行平移操作,将相机向左平移四百单位,向上平移三百单位,这样就完成了世界坐标和逻辑坐标的原点统一。通过下面两张图可以更清楚地看到效果。
- 第一步,将 2D 纹理的中心点设置在左下角点看到的现象。
- 第二步,平移相机实现世界坐标和逻辑坐标(屏幕坐标)的重合。
相机的设置
(此处可补充相机设置的具体内容,若原文无更多信息,可保留此小标题占位)
总结
本篇文章是对 Unity 3D 坐标系系统的综合应用,同时也是一块试金石,考验你是否真正掌握了 Unity 3D 坐标系系统。不知道你掌握得如何,反正我是学会了。