2.5 创建第一个UI
2.5.1 创建一个2D UI
制作UI时,首先我们要创建UI的“根”。在Unity顶部NGUI菜单中选择Create,然后选择2D UI,如图2.25 所示。
▲图2.25
创建完成后,我们能看到图2.26所示的景象,在Scene窗口中,NGUI自动生成了一个名为UI Root 的物体,其中带有一个Camera 作为子物体。
▲图2.26
这个新生成的Camera,是NGUI生成的专门用来渲染UI的相机,当我们生成NGUI的UI Root时,就自动将生成的UI的layer设为了第8层。在这个相机中,只能看见第8 层的物体,也就是只能看见UI。因为是2D UI,所以我们从图中可以看到相机是正交相机。
图2.26中红色的矩形是相机的视窗大小比例,它会根据Game 视图中的屏幕长宽比设置自动调整。
2.5.2 创建一个3D UI
创建3D UI的过程和创建2D UI的过程类似,创建出来的3D UI如图2.27所示,NGUI依然自动生成了一个名为UI Root的物体,并带有一个Camera 子物体,这个原理和2D UI类似,其中最大的区别就是相机的模式。3D UI的相机在Scene视窗中是一个正交摄像机,将会支持UI的三维透视效果。
2.5.3 了解UIRoot、UIPanel和UICamera组件
在我们创建的UI中,可以发现UI Root物体和Camera 物体上面都带有NGUI特有的脚本组件,其中 UI Root 物体上带有 UIRoot 和 UIPanel 两个组件,而子物体 Camera 带有一个UICamera组件,这几个组件都是NGUI体系中比较核心的组件,下面我们来简单了解一下。
▲图2.27
1.UIRoot组件
UIRoot组件总是出现在NGUI的UI“树”的最顶层,也就是那个“根”物体中。它的作用是缩放UI。我们在让美术人员作图时知道,UI一般都是以像素作为单位,比如1920*1080等,而Unity中则是以米为单位,如果一个100*100像素的UI元件放入到一块1000*1000分辨率的屏幕中,按理说这个UI元件应该是屏幕大小的1%,但是因为Unity中的单位是米,所以它会从100*100像素的大小变为100*100米,会导致一个小UI元件变得非常之巨大。这个时候UIRoot会通过屏幕来缩放UI控件,让UI控件从视觉上是正常的。
在UIRoot组件中,它提供了3种缩放的方式,也就是UIRoot组件下的Type值。这3种方式分别为PixelPerfect、FixedSize、FixedSizeOnMobiles。
PixelPerfect是指永远保持像素大小不变,比如一张100*100像素的图片,在500*500分辨率的屏幕上,它是100*100像素,在1000*1000分辨率的屏幕上,它依然还是100*100像素,因为它的源文件就是这个大小,而PixelPerfect让它一直保持这个大小。这样就可以让UI的图片永远是最清晰的,但是会导致分辨率高的屏幕下UI显得特别小;分辨率低的屏幕下 UI显得特别大。
FixedSize是和上一种缩放方案完全相反的方案。在FixedSize下,NGUI将不再保护图片的原尺寸,只会关心 NGUI 自己所需要的缩放参数,这种模式下必须设置 UIRoot 的ManualHeight值,然后NGUI会将所有的控件按照和这个值的高度比例进行缩放。例如,设置ManualHeight为1000,然后一张100*100的图片在高度为1000的屏幕分辨率下占1/10的高度,那么当UI放到一个分辨率为500*500的屏幕上时,它依然占1/10的高度,只不过图片尺寸被自动放缩为50*50,这样就保证了UI和屏幕分辨率的比例是一定的。
FixedSizeOnMobiles是两种方案的结合体,它会让UI在PC、Mac、Linux系统下自动采用PixelPerfect,而在移动设备上自动采用FixedSize。
如果没有选择 FixedSize ,那么必须设置另外两种缩放模式下的 MinimumHeight 和MaximumHeight 两个值,代表最大高度和最小高度。例如选择 PixelPerfect 模式,将MinimumHeight设置为720,将MaximumHeight设置为900,那么在一个分辨率为800*600的屏幕上,因为屏幕分辨率的高度小于UIRoot里的最小高度,UIRoot就会按照FixedSize模式下ManualHeight为720的情况进行处理;同理,如果将UI放到一个分辨率为1920*1080的屏幕上,因为该屏幕分辨率的高度1080大于设置的900,于是UIRoot就会按照FixedSize模式下ManualHeight为900的情况进行处理。
值得注意的是,在3.7.0以后的NGUI上,UIRoot的缩放模式改为了。
●Flexible,等同于上文讲到的PixelPerfect。
●Constrained,等同于上文讲到的FixedSize。
●ConstrainedOnMobiles,等同于上文讲到的FixedSizeOnMobiles。
功能上几乎完全一样。
2.UIPanel组件
如图2.28所示,UIPanel有很多属性。其中,Alpha属性顾名思义是透明度,默认为1不透明。它将控制它旗下所有Widget(所有的UI控件都将带有Widget,因为它们都继承自Widget)的透明度,也就是它会让它的子物体里的所有UI控件都一起发生透明度变化,可以用来做整个UI的淡入淡出以及隐藏等。
Depth深度属性,这是一个极其重要的属性。在NGUI中,每一个Panel都有Depth,每一个Widget控件也有Depth,Depth将决定渲染的顺序,直接影响了UI之间的前后重叠关系。Depth 越高的控件将会显示在视野的上层,Depth 越高的 Panel 也会显示在视野的上层。但是Panel的Depth权重远远高于Widget,也就是说,在大部分情况下,属于低Depth的Panel的控件,不管这个控件本身的Depth为多少,它都将显示在高Depth的Panel的控件后面。当你有多个 Panel 的时候,例如你制作了很多面板界面,每一个界面都有一个Panel,那么此时尽量保证这些Panel不要共用同一个Depth,因为这将导致NGUI在渲染时无法以1个DrawCall完成,会以增加DrawCall的方式来保证渲染顺序不混乱,这样就增大了性能的开销。不过NGUI在碰到Panel有共用Depth的情况时会做出提醒,如图2.29红框部分所示。
▲图2.28
▲图2.29
Clipping是剪辑视窗的功能,它将可以让一个面板只显示某一块区域,关于这部分知识后文我们再讲解。
在高级选项中,我们讲解一些初学者需要了解的。Render Q可以理解为渲染顺序,默认为自动设置。这个选项在和粒子系统结合使用时会有影响,我们后文会说明。如果该Panel下的UI需要被灯光影响到(NGUI的UI是默认不接收灯光照射效果的),需要勾选Normals。如果该Panel下面所有的UI控件都不会被移动,那么可以勾选Static来将它们设置为静态的,这样会导致该Panel下所有的控件都将忽略位置、旋转、缩放的操作,永远保持不动。虽然这样可以提高一些性能,但是慎重使用。
单击Show Draw Calls按钮,可以看到该Panel下所有的DrawCall消耗情况,如图2.30所示。
▲图2.30
3.UICamera组件
图2.31所示为UICamera组件的截图,UICamera这个组件的核心作用是:让带有这个组件的摄像机渲染出的物体能够接收NGUI的事件。如果我们自己创建了一个物体,并且希望对这个物体使用一些 NGUI 中的事件,例如 OnPress()、OnDrag()等,就需要为渲染这个物体的摄像机添加UICamera组件。
▲图2.31
在UICamera中,大部分设置我们都不需要去操心,它让我们的事件支持多点触摸、鼠标键盘触摸屏等事件的接收。但是要注意的是EventMask 这个选项,这个 EventMask 和相机中的 CullingMask 非常相似,相机的 CullingMask 是为了选择渲染那些层的物体,这里的EventMask是为了选择接收那些层的物体的事件。UICamera会默认只接收我们创建UI时被自动设置的那个layer,但是,如果我们在制作UI过程中,在创建UI后因为某些原因修改了UI的层,一定要将UICamera的EventMask修改过来,否则将会发现,我们单击UI没有反应,因为它接收不到这个layer的物体的事件。
关于这 3 个最基础的控件讲了这么多,其中有很多都是较少用到,主要目的是加快对NGUI概念的形成。具体在需要的时候应该进行什么样的操作,我们后面的一些实战内容中会讲到。