赞
踩
NGUI是unity3D开发中常用的UI制作插件,它提供了丰富的UI组件,为开发者提供了极大的方便。作为一个手游开发者,面对纷繁复杂的机型,UI的自适应是一个很大的问题,还好NGUI为广大开发者提供了非常方便的自适应解决方案。
在NGUI的整个UI框架中,UIRoot是必不可少的,UI视口的大小是由 NGUI的UIRoot脚本决定的。NGUI的其他控件,如 UIPanel UITexture UISprite UIlabel 等组件,都是继承自UIRect组件,这些组建在Inspector面板中都能够看到Anchor选项,可以选择对应的自适应模式:
None即不进行自适应,不管屏幕分辨率怎么改变,位置保持不变;
Unified 标准自适应,选择后可以选择一个Target,及相对于target的上下左右偏移量,当分辨率改变或者target的尺寸发生变化的时候,UIRect会根据相对于Target的偏移量进行相应的移动缩放等变化。
Advance,上下左右四个边可以分别指定一个Target,当然也可以不指定。
在NGUI3.7.x之前的版本中,UIRoot的 ScalingStyle 由三种不同的选项:
PixelPerfect,
FixedSize,
FixedSizeOnMobiles
PixelPerfect 就是UI显示以图片的真实像素为准,在Minimum Hight 和Maximum Hight 范围内,不进行缩放,图片是多大就是多大,当超过这个范围后,就以此最小值,或最大值的显示范围为准。
FixedSize 也即UI根据设备当前的分辨率自动进行缩放。
FixedSizeOnMobiles 是以上两种的结合,当程序运行在android iOS wp 等移动设备上时,使用FixedSize 模式,其他情况下使用PixelPerfect模式。
因在移动设备中PixelPerfect模式不常用,这里重点说明下FixedSize 模式下的自适应方案。
在FixedSize模式下,UIRoot有个Manual Height 参数,这个就是参考屏幕的高度,在横屏模式下,如果游戏的UI设计是以960*640分辨率为基准的,那么这个值就填640,那么不管在任何分辨率下,都会保证高度不变,宽度根据实际分辨率的比例扩大显示范围,如在1136 * 640分辨率下,显示范围就是1136 * 640 ,在854 * 480 分辨率下,根据显示高度为640,那么宽度就是(640 /480)*854 = 1138.66666,显示范围就是1138*640。为了使在不同分辨率下都能显示背景图,往往会吧背景图做的大一些,以下是不同分辨率下的效果图,图中左中右三个小图片分别根据anchor设置居左对齐,无 ,右对齐:
背景图:
960*640分辨率下:
1136*640下:
854* 480下:
以上三种分辨率中,宽高比:
960*640 :1.5,
1136*640 :1.775,
854*480:1.779,
因为我们的UI都是以960*640为基准设计的,当在1136*640和854*480这些宽高比大于960*640的时候,视口范围会自动向两边扩展,按钮等组建也会随之向两边扩展,那么问题来了!1024*768分辨率宽高比:1.33333,小于1.5,视口依旧是高度不变,宽度缩小,就出现了下面的情况:
因为宽度缩小,按钮依旧是左/ 右对齐,就会导致按钮相互重叠!
出现这种问题怎么办?如果我们以1024*768分辨率做为参考分辨率,那么所有其他的宽高比大于1.333的分辨率下都是宽度向两边扩展,貌似不会出现重叠的问题,但是如果分辨率宽高比比这个更小呢(虽然现在貌似除了黑莓的一款方屏手机外木有其他的奇葩机型了)?并且现在市面上流行的几种分辨率宽高比基本上都在1.7以上,如果以4:3为比例设计UI的话,放在1.7以上的手机上可能会显得比较松散,效果也不够好。最好的解决办法,就是在宽高比小于基准分辨率的宽高比的情况下,使用基于宽度的缩放模式,反之使用基于高度的缩放模式。
在NGUI3.7.0以前,NGUI并没有提供基于宽度缩放的模式,我们就要自己实现了,这个网上也有较多的解决方案,原理都是一样的,基于宽度缩放,几保证宽度960不变,那么在1024*768屏幕下,高度应该为960*3/4 = 720,也就是当我们把UIRoot的ManualHeight设置为720的时候就能保证在此分辨率下是基于高度缩放了。下边是个人根据网上的方案修改的一个脚本:
- public class AutoScale : MonoBehaviour
- {
-
- static int SCREEN_WIDTH = 960;
- static int SCREEN_HEIGHT = 640;
- int mScreenWidth;
- int mScreenHeight;
-
- UIRoot root;
- // Use this for initialization
- void Awake()
- {
- mScreenWidth = SCREEN_WIDTH;
- mScreenHeight = SCREEN_HEIGHT;
- root = GetComponent<UIRoot>();
- ScaleScreen ();
- #if UNITY_EDITOR
- UICamera.onScreenResize += ScaleScreen;
- #endif
- }
-
- void ScaleScreen()
- {
- if ((float)Screen.width / (float)Screen.height < (float)SCREEN_WIDTH/(float)SCREEN_HEIGHT)
- {
- root.manualHeight = SCREEN_WIDTH * Screen.height / Screen.width;
- }
- else
- {
- root.manualHeight = (int)SCREEN_HEIGHT;
- }
- }
将这个脚本挂在UIRoot所在的物体下,在游戏开始运行时回自动调整UIRoot到合适的值,在编辑器模式下,如果手动调整分辨率会调用UICamera.onScreenResize委托,此时UIRoot也会重置,便于调试。
在NGUI3.7.0版本中,NGUI的开发人员终于意识到了这种自适应方式的优势,于是在UIRoot中新增了基于宽度缩放的模式,在新版本中,ScaleStyle枚举变成了以下三个:
Flexible,
Constrained,
ConstrainedOnMobiles,
实质上跟以前的版本一个意思,只是在Constrained模式下多了两个选项:
ContentWidth 基于宽度缩放,ConentHeight,基于高度缩放,Fit后边的勾表示选择的模式,若只打一个勾就是基于宽度或高度缩放,若两个勾都打上,则会根据所填的960 640为基准,如果宽高比大于1.5就基于高度缩放,反之基于宽度缩放,非常之方便。
最后,关于背景图的大小,宽高比最大的分辨率应该是854*480:1.779,最小的应该是1024*768:1.33333在基于960*640为基准分辨率的模式下,那么为保证在这两者范围内的所有分辨率都能够完美显示背景,背景的大小,至少应是1.779*640 = 1138.56,960/1.333 = 720。这样,设置好UIRoot并且调整好各个组件的相对位置,你的游戏就可以在任意分辨率下完美运行了!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。