Unity 提供了三个 UI 系统帮助我们创建游戏界面 (UI):
第一,UI 工具包
第二,Unity UI 软件包 (UGUI)
第三,IMGUI
UI 工具包是 Unity 中最新的 UI 系统。它旨在优化跨平台的性能,并基于标准 Web 技术。您可以使用 UI 工具包为 Unity 编辑器创建扩展,并为游戏和应用程序创建运行时 UI。但它仍然缺少 Unity UI (UGUI) 和 IMGUI 中的一些功能。
Unity 用户界面(也称为 UGUI)是一个较旧的、基于游戏对象的 UI 系统,您可以使用它为游戏和应用程序开发运行时 UI。在 Unity UI 中,即可使用组件和 Game 视图来排列和定位用户界面并设置其样式。它支持高级渲染和文本功能。
IMGUI是立即模式图形用户界面 (IMGUI) 是一个代码驱动的 UI 工具包,它使用 OnGUI 函数以及实现它的脚本来绘制和管理用户界面。您可以使用 IMGUI 来创建脚本组件的自定义 Inspector,Unity 编辑器的扩展以及游戏内调试显示。不推荐用于构建运行时 UI。
目前来说,使用UGUI创建游戏界面是我们最佳选择。
在进行学习之前,我们有比较介绍一些UI创造中的一些问题。不管使用那种API,不管是做PC端的UI设计,还是手机端的UI设计,这些问题都是一样要解决的。那么就是屏幕自适应的问题。我们知道,不管是PC屏幕,还是手机屏幕,他们都有不同的尺寸。如何让我们制作的UI能够在不同尺寸的屏幕上展示出“统一”的效果呢?例如,我们做了一个按钮,放在屏幕的某一个位置(例如屏幕中间位置),那么当我们的屏幕发生变化的时候,这个按钮在新的屏幕上如何正确显示它的位置和尺寸呢?很显然,百分比是一个不错的解决方案。接下来,我们就来认识UI中的第一个概念,Canvas画布。画布是一种带有画布组件的游戏对象,所有 UI 元素都必须是此类画布的子项。创建新的 UI 元素时,如果场景中还没有画布,则会自动创建画布。UI 元素将创建为此画布的子项。接下来,我们就来是试一试。我们点击菜单栏“GameObject”->“UI”->“Text”创建一个文本。
其实在3D场景中编辑2D的UI界面不是很方便,我们可以点击上图中红色标注的“2D”按钮,切换到2D场景下进行编辑,如下所示:
上图中左下角的“New Text”就是我们刚刚添加的“文本”UI元素,而最外面的大矩形就是Canvas画布。那么,这个Canvas画布很明显,就等同于我们的屏幕。上文中提到,用户的屏幕尺寸是不确定的,有大有小,因此Canvas画布的一个重要功能就是自适应用户的屏幕。另外一个问题就是,我们做UI界面编辑的时候,基本上都是在“2D”场景中进行,因为UI界面始终会显示在用户的屏幕上面,它只有XY坐标属性,并没有Z坐标属性。我们可以去Hierarchy层次视图来查看Unity帮我们都创建了那些游戏对象,
其中Text控件是我们创建的,Canvas画布是自动创建的,且它是TexT控件的父对象。同时,还有一个EventSystem的游戏对象,它主要用于UI控件事件交互使用的,例如点击事件等。接下来,我们先介绍Canvas画布,先查看它的Inspector检视视图
对于Canvas画布,我们首先要了解它的“Render Mode”和“UI Scale Mode”两个项目的含义。首先是渲染模式“Render Mode”,它有三个值可以选择:
第一,Screen Space – Overlay:此渲染模式将 UI 元素放置于在场景之上渲染的屏幕上。如果调整屏幕大小或更改分辨率,则画布将自动更改大小来适应此情况。这是默认模式,也就是UI元素会遮挡游戏场景中的任何游戏物体。
第二,Screen Space – Camera:此渲染模式同上,但在此模式下,画布需要放置在指定摄像机前面的给定距离处。UI 元素由此摄像机渲染,这意味着摄像机设置会影响 UI 的外观。
第三,World Space:在此渲染模式下,画布的行为与场景中的所有其他对象相同。该模式就是将UI元素放置到3D场景中的效果,UI元素就相当于3D场景中的游戏对象。
在我们日常游戏开发中,使用第二种会多一些,其他两种根据我们的需求去使用。
此模式下,需要我们选择一个相机渲染UI,我们只有“Main Camera”相机,因此就将主相机拖拽到Canvas组件下的Render Camera选项处。
接下来是缩放模式“UI Scale Mode”,此项并不是Canvas如何缩放(因为Canvas本身就会根据屏幕的实际尺寸进行缩放),而是其下UI元素的缩放模式,它也有三个值可以选择:
第一,Constant Pixel Size恒定像素:无论屏幕大小如何,UI 元素都保持相同的像素大小。这是默认值。我们知道屏幕的尺寸单位就是像素,因此显示到屏幕上的内容,最终都会以像素显示出来。因为UI元素是直接显示在屏幕的二维平面上的,因此它的尺寸单位就是像素。但屏幕发生变化的时候,Canvas画布会自动进行放大或缩小,Canvas画布上的UI元素势必会受到这种自适应带来的影响。这里的Constant Pixel Size的选项就是保持UI元素的像素尺寸不变。那么像素尺寸不变,UI元素在屏幕上的大小就不变嘛?不一定的,我们知道屏幕的像素分辨率是可以调整的,例如1920x1080,1280x720等等。也就是说,同一屏幕的像素也是可以不一样的,当屏幕像素分辨率发生变化的时候,UI元素的大小也会改变。例如,同一屏幕,一个100*100像素的UI元素的在1920x1080(大分辨率)下的尺寸肯定要小于1280x720(小分辨率)下的。此模式下屏幕分辨率增大的话,UI元素会变小。但是,我们也不经常频繁的修改屏幕的分辨率,因此可以暂且理解Constant Pixel Size下的UI大小不变。
第二,Scale With Screen Size屏幕尺寸比例:屏幕越大,UI 元素越大。也就是说,UI元素会跟随Canvas画布一起放大或缩小。这种模式给用户的体验会好一些,UI元素跟跟随分辨率增大而增大,其实很多的软件界面(或者H5网页)都是遵从这个原则来设计开发的。
第三,Constant Physical Size恒定尺寸:无论屏幕大小和分辨率如何,UI 元素都保持相同的物理大小。这个就非常简单了,不管是屏幕改变,还是分辨率改变,UI元素都保持相同大小。这种模式在分辨率变化不大的情况下,给用户的体验也是不错的。
在我们日常游戏开发中,我们一般会选择第二种方案Scale With Screen Size,如下所示。
我们可以看到四个不同的参数设置:
Reference Resolution: 参考分辨率,就是我们设计稿的尺寸,也就是我们Canvas的尺寸。例如:横屏设置为1920*1080;竖屏设置为:1080*1920即可。在Editor上设计UI时就是根据这个默认尺寸进行布局。如果当前屏幕分辨率大于参考分辨率,则画布会放大以便适应屏幕,UI元素也会跟随统一放大;如果当前屏幕分辨率小于参考分辨率,则画布会相应缩小以适应屏幕,UI元素也会跟随统一缩小。等比例缩放不存在任何问题,问题就是不等比例的时候如何缩放。这就好比将一个正方形缩放成一个长方形,UI元素一定会被挤压扭曲。
Screen Match Mode: 屏幕匹配模式,默认使用Match Width Or Height即可,它表示使用下面的Match值来决定如何对Canvas画布进行缩放。
Match: 当Match=0时,表示适配宽度。就是将Canvas宽度设置为屏幕宽度,并保持默认尺寸比例不变(例如上图中的800:600的比例)。如果此时高度超过屏幕高度,超出部分将会被裁切掉。这是Unity的默认值,也就是宽度适配。当Match=1时,适配高度。将高度设置为屏幕高度,并保持默认尺寸比例不变。如果此时宽度超过屏幕宽度,超出部分将会被裁切掉。Reference Pixels Per Unit: 每1个Unity单位的像素数量,默认100即可。
总结:上面的参数设置其实就是制定Canvas的缩放规则,然后再统一的对UI元素进行缩放。影响UI元素展示效果的有两个因素,一个是尺寸,另一个是位置(锚点)。接下来,我们就来看看UI元素的位置是如何设置的。
由于我们上面的操作,无意间将Canvas的尺寸改小了,因此Text 这个UI元素被遗弃在了Canvas的外面了。这样的话,我们运行工程后,是看不到Text的,我们必须将它移动到里面来。我们先点击选中Text UI元素说起,然后查看它的Inspector检视视图,如下所示
我们首先介绍的是“Rect Transform”组件,它就代表了UI元素的位置信息。在这个组件下,我们看到了PosX和PosY的属性,我们将这两个属性值改成0试一试。
修改之后,我们发现Text被放置到了Canvas的中间位置。为什么会是这个样子?这里面最重要的是对“Anchors”的理解,也就是我们上面提到的“锚点”。什么是“描点”呢?
我们先将Text从中间移动到旁边。然后点击画布中间的那个“四瓣雪花”就是我们的锚点。我们发现,这个锚点的位置位于画布的中间,因为它距离画布上下左右的距离都是50%。注意,锚点的位置是根据百分比来确定的。这样的好处就是,当我们的Canvas缩放之后,锚点在画布中的位置不会改变。当我们点击选中“锚点”的时候,是可以移动它的位置。它的位置由四个数值来决定,分别是水平方向和垂直方向的百分比,并且每个方向上的两个数值的和应该是100%(也就是1)。我们点击检视面板上的“Anchors”展开下面隐藏的区域。
上图中展示了锚点的四个数值,因为是中间位置,所以都是0.5(也就是50%)。但是,我们通常不会通过手动修改上面数值的方式来改变锚点的位置。Unity给我们提供了一个快捷方式。我们回到TextUI元素的Inspector检视视图中,
左边的“middle/center”图形按钮是用来快速设置“锚点”位置的,点击如下
Unity会提供给我们几种常见的位置,比如中间,左上角,右上角等等。我们只需要点击想要的“位置”,就可以自动设置锚点位置了。我们当前是中间的位置,我们修改为左上角。
此时,我们在回到Scene场景视图中查看。
我们发现锚点移动到了Canvas的左上角了。那么,这个锚点对于Text有什么作用呢?
我们将Text的PosX和PosY的数值改成0,再查看其效果。
很明显了,UI元素的位置信息(PosX/PosY)是基于锚点的,而锚点又是基于Canvas的。我们可以简单的理解,Canvas代表屏幕,UI元素的锚点根据百分比来确定位置,然后UI元素的真正位置又是根据自身的锚点来确定的。千万不要认为,UI元素的位置是基于屏幕的。
但是,在上面的截图中,我们发现了一个小问题。就是Text 的中心位置(Pivot)位于锚点位置,所以,Text一部分内容放置在了Canvas的外面。这部分内容无法显示的。如何将Text全部移动到Canvas里面呢?两种方式,第一是修改PosX和PosY的数值,第二就是修改Text的“Pivot”轴心。记住,UI元素的位置是基于锚点的,更准确的说,是UI元素的“Pivot”轴心基于锚点的。这就好比我们将一个模型放置到一个坐标点上的时候,实际是将这个模型的“Pivot”轴心放置到了这个坐标点上。
从Text的Inspector检视面板中看出,它的“Pivot”轴心位于矩形的中心位置。这就是为什么是Text的中心位置被放置到了Canvas的左上角了。如果我们将Text的轴心修改为它的左上角,那么当我们设置Text的PosX和PosY的值为0的时候,Text的左上角就与Canvas的左上角对齐了。
我们回到Scene场景视图中查看
接下来就是TextUI元素的尺寸属性 Width 和 Height,他们的单位都是像素。
默认情况下,我们的Text的尺寸是160x30的像素。同理,我们的PosX和PosY的值也是像素值。如果我们设置PosX = 10,PosY = -10
我们发现Text与Canvas左上角的间接就是10像素。请注意,这个10像素的数值是固定的。也就是说,当屏幕(Canvas)改变的时候,Text始终会在屏幕左上角10像素的距离处。我们可以Play运行工程,来看一下真实的效果
最后就是UI元素的Rotation旋转和Scale缩放,大家可以根据自身情况来使用。
本课程涉及的内容已经共享到百度网盘:https://pan.baidu.com/s/1e1jClK3MnN66GlxBmqoJWA?pwd=b2id