关闭

unity3d ngui 适配性价比最高的方案

标签: unity3dngui 适配
1453人阅读 评论(5) 收藏 举报
分类:

      对于网上各种适配方法,说明的有很多,但我认为大部分都是自己写一个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。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:231352次
    • 积分:3341
    • 等级:
    • 排名:第10452名
    • 原创:88篇
    • 转载:19篇
    • 译文:0篇
    • 评论:91条
    博客专栏
    最新评论