NGUI自适应屏幕分辨率

  unity官方承诺的新ui系统一直没有推出来,我们的UI使用的是原生的OnGUI系统,刚好UI需要改版,索性就想迁到NGUI上面来,于是看了一下NGUI源码,发现NGUI可以大大的降低DrawCall,减轻GPU负担,但是各个组件类上面,也有很多浪费cpu的运算可以改进,这一点对开发移动平台的游戏一定很重要。因此需要对他有针对性的做一些修改,以适应自己的需要。

  在迁移过程中,首先要解决的问题就是屏幕分辨率的问题,因为我们是开发移动平台的游戏,分辨率当时是设定在800*480像素,用OnGUI可以很容易解决分辨率的适配问题。看了NGUI的文档和源码,发现NGUI提供了3种分辨率解决方案。

  第一种是像素匹配,也就是UIRoot组件上面的设置Scaling为Pixelperfect。采用这种模式,如果在设计阶段一条垂直支线占用100个像素,那么在各个分辨率下面都只占用100个像素。这种样式如果页游或者端游上面设计固定像素大小的界面还是可以的,毕竟游戏窗口大,像素空间占比也不小,在不同的分辨率下面界面不会变形太多,但是如果放在移动平台上面,相同尺寸的屏幕,分辨率可以从几百变换到几千,像素密度差异非常大,比如在某个低端机上面,50个像素已经占据很大的屏幕空间了,但是到一个分辨率非常大的手机上面,50个像素只占据一点点屏幕空间了,这就造成一个问题,在低端机上面很清晰地界面到高端机上面会变小到甚至看不清楚了。

  第二种是固定尺寸,Scaling设置为FixedSize,这种模式下,界面占用的像素会等比缩放,但是他只提供了根据高度缩放。比如采用这种模式,你设置100像素高的界面,到了某个某个分比率下像素高翻一倍的屏幕上,界面会占用200像素高。很好,这不就是我们需要的吗?且慢,他提供的是根据高度来等比缩放的,但是现在的手机各种奇葩的宽高比都有,宽与高不是等比的,如果你设计了一个占满屏幕的背景,切换到另一个分辨率下,高度会刚好充满,但是宽呢?因为不是等比,所以会留下两边的黑边。这不是我们希望看到的。

  第三种方式是通过锚定,NGUI3.07以后的版本UIPanel和UiWidgt都是继承自UIRect,UiRect提供了四个锚定变量。比如设计一个背景框,把左右上下都锚定在根物体四个角上面,这样就实现了自适应分辨率的缩放。这确实满足了我们的需求,可是想想如果每个ui都要这样去设定,那也太麻烦了,而且采用Anchor的做法,会每帧都会浪费cpu去计算相对位置(还没有分析这一部分源码,不确定),而且每个UI都会有四个新增的anchor变量,也会浪费珍贵的终端内存。所以我打算把anchor去掉。

  那有没有别的方法呢?当然有,而且相当简单。NGUI为什么会对高度自适应呢?应为他对跟物体用2/manulHeight进行了缩放,这个缩放的意义是什么呢?为什么是用2来除呢?因为设计2dUI的时候,我们相机是采用正交投影模式,正交投影的视体是一个长方体,正交投影摄像机有个orthographicSize属性,我们把它设为1,他的意思是投影相机的视体半高为1,也就是这个视体的y轴是-1到1,高度一共为2,2的高度映射着整个屏幕高度,所以用2除以设置高度后,就可以在该高度进行界面设计,假定我们设计UI是800*480,我们就可以把manulHeigh设置为480,这样,root下的子物体,1就代表着1个像素,加入我们设计了一个240高度的界面,整个界面搞就占据了50%的屏幕高,切换一个不同高度的屏幕后,还是占据50%的屏幕高这样,就实现了针对高度的等比缩放了,那么宽度呢?同理啊,在Scaling里面添加一个新的样式 ,fixedSizeBoth,然后添加一个变量manulWidth, 对root的x轴所用 用  2*Screen.aspect/manulWidth缩放就可以了。 为什么要用2*Screen.aspect,自己去看看unity文档和3d方面的知识把。

你可能感兴趣的:(NGUI自适应屏幕分辨率)