Unity NGUI之UIRoot画布自适应

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的时候就能保证在此分辨率下是基于高度缩放了。下边是个人根据网上的方案修改的一个脚本:

[csharp]  view plain  copy
  1. public class AutoScale : MonoBehaviour  
  2. {  
  3.   
  4.     static int SCREEN_WIDTH = 960;  
  5.     static int SCREEN_HEIGHT = 640;  
  6.     int mScreenWidth;  
  7.     int mScreenHeight;  
  8.   
  9.     UIRoot root;  
  10.     // Use this for initialization  
  11.     void Awake()  
  12.     {  
  13.         mScreenWidth = SCREEN_WIDTH;  
  14.         mScreenHeight = SCREEN_HEIGHT;  
  15.         root = GetComponent<UIRoot>();  
  16. ScaleScreen ();  
  17. #if UNITY_EDITOR  
  18. UICamera.onScreenResize += ScaleScreen;  
  19. #endif  
  20.     }  
  21.   
  22.     void ScaleScreen()  
  23.     {  
  24.         if ((float)Screen.width / (float)Screen.height < (float)SCREEN_WIDTH/(float)SCREEN_HEIGHT)  
  25.         {  
  26.             root.manualHeight = SCREEN_WIDTH * Screen.height / Screen.width;  
  27.         }  
  28.         else  
  29.         {  
  30.             root.manualHeight = (int)SCREEN_HEIGHT;  
  31.         }  
  32.     }  



将这个脚本挂在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并且调整好各个组件的相对位置,你的游戏就可以在任意分辨率下完美运行了!



转载 : http://blog.csdn.net/qinglongyanyuezhu/article/details/40747569

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值