转载自:http://blog.csdn.net/yxriyin/article/details/46800241
对于网上各种适配方法,说明的有很多,但我认为大部分都是自己写一个demo啥的能行然后就说这种方案可以。但实际上这些方法到底怎么样,恐怕并不尽如人意。
ngui的UIRoot自带缩放功能,假设你的游戏按照普遍的1280*720设计,那么所有以此比例的分辨率都将完美适配。
那么如果比例不同呢,uiroot并没有做任何处理,那么就是当宽度太宽,那么你的游戏将会被截边,如果高度太高,那么你的ui将会不贴边。当然你会发现ngui还提供了一个叫做anchor的类,这个类的作用就是让你的位置能够相对保持不变。那么看似能够解决这个问题,然后很多人也都是写了下anchor的用法然后就说完美适配啦。。。。太年轻。
ui的设计并没有如此简单,首先贴边的你可能认为很好设计,那么居中的呢?面板大小呢?假设面板大小也相对不变,那么就是面板时大时小,那么你怎么保证面板里面的东西也对应起来呢,那么只能是所有的控件全部都用anchor设计,我只能说如果你一开始就能这么做,那么恭喜你,虽然每一次工作量多了一些,但长期弄的话,这将是实现出最完美的ui适配。
但遗憾的是,即便你拥有如此先见之明,一些不好的ui设计依然会导致问题,重叠问题。没错,如果你的ui设计没有足够的容错性,那么你可能发现在某些比例下UI之间会产生相互重叠的情况,然后你可能要一个个去矫正规避。所以我认为这个性价比真的不高。不过也有这么做的游戏,例如《不良人》。大家可以去看一下,对于不同的分辨率,它都能比较好的适配,很大程度上是ui设计比较合理,一个全屏大底板,控件间距尽量小等。
如果你一开始没有做相关内容,那么你就会发现各种适配问题,那么有什么快速方法解决呢?
那就是黑边。
按照比例缩放,如果碰到边界就停止,也就是多余部分应该会以黑边显示。有些人可能会调整camre的aspect,不推荐,因为会拉伸,你会发现你的ui被拉长或压扁。眼尖的人马上就能看出来,然后会觉得很不舒服,所以黑边还是正确的做法。
那么怎么快速的产生黑边呢,我尝试了各种可以黑边的方法,其中最快速最好用的就是camera.rect,这个是最完美的,其他或多或少有bug或者需要特殊处理。
代码如下:
public static float getTimes()
{
float screenHeight = Screen.height;
float screenWidth = Screen.width;
float tarW = screenHeight * 1280f / screenWidth;
return tarW / 720f;
}
这个是获得理论上的缩放比例。我是按照1280*720来设计游戏的。
public static void checkMainCamera()
{
float times = CameraUtil.getTimes();
if(times < 1f)
{
float x = (1-times) / 2f;
Camera.main.rect = new Rect(x, 0f, times, 1f);
}
else if(times > 1f)
{
float x = (1 - 1 / times) / 2f;
Camera.main.rect = new Rect(0f, x, 1f, 1 / times);
}
}
这个就是调整函数,当缩放比例<1,说明宽度太长,>1说明高度太高。
以上是调整3d摄像机的,那么ui摄像机的调整建议放在UIRoot中,这样就不用找各种地方了。
protected virtual void Awake () {
mTrans = transform;
if (Application.isPlaying)
{
Camera c = GetComponentInChildren<Camera> ();
c.backgroundColor = Color.black;
float times = CameraUtil.getTimes ();
if(times < 1)
{
float x = (1 - times) / 2f;
c.rect = new Rect(x, 0f, times, 1f);
}
else if(times > 1)
{
float x = (1 - 1 / times) / 2f;
c.rect = new Rect(0f, x, 1f, 1 / times);
}
}
}
修改UIroot的awake函数。好了,perfect。