Ngui分辨率适配

必备知识点

1.分辨率适配必然是Orthographic Camera

2.Camera下对应的“Size”(图1)属性大小的理解:当前摄像机高度 = Size * 2 * UnityUnit(Unity编辑器单位长)

3.NGUI象素比例与UnityUnit之间的比值关系为 1:1(这里需要注意所有父节点的缩放都要重置为1)

4.Game视图下分辨率(图2)的意义:

意义1:

  Game视图渲染时的光栅格个数(光栅格数越少,画面越模糊)

意义2:

  由于上面Size已经决定了摄像机高度,那么还需要根据这个“长宽比值”来决定摄像机的宽度

Eg:

  比如Size属性为384,分辨率设置为 2000 X 1000 那么最终 摄像机照射范围就是 “长 -----> 1536UntiyUnit, 宽 -----> 768UnityUnit”

                                          图1

                        图2(当分辨率比值不变,修改其数值大小时,照射范围一致,只是影响清晰度)


 

 

分辨率适配的原理:

1.我们最开始摆放UI的时候都需要有一个最初的分辨率和Camera Size(之后称之为 预设分辨率 & 预设Size)

2.我们假设预设分辨率比为3:2(1152 : 768),而目标分辨率比是未知的,存在以下2种情况 “长宽比小于 预设长宽比”,“长宽比大于 预设长宽比”

 - 情况1 

          【】 由于屏幕高度没有发生变化,所以Camera Size不需要改变

          【】 其他UI元素根据其anchor值决定是否 “移动” 或 ”缩放”

- 情况2

     【】 由于屏幕高度发生变化,所以要重新计算Camera Size 

     【】 其他UI元素根据其anchor值决定是否 “移动” 或 “缩放”

以下是分辨率控制器代码(Manager部分)

/***************************************
Editor: Tason
Version: v1.0
Last Edit Date: 2018-04-13 
Tel: 328791554@qq.com
Function Doc: 
分辨率适配 
主要理解一下裁剪方式
***************************************/

using UnityEngine;
using System.Collections;


public class ResolutionController : MonoBehaviour
{
    //设置(时)分辨率
    public int m_originalWidth = 1152;
    public int m_originalHeigh = 768;

    //设置(时)摄像机Size 
    public static float s_cameraSize;
    [HideInInspector]
    public float m_cameraSize;

    //管理的摄像机们
    public Camera[] m_cameras;

    //偏移值
    public static float s_scaleRatio = 1;
    public static float s_topCenter = 1;
    public static float s_bottomCenter = 1;
    public static float s_leftCenter = 1;
    public static float s_rightCenter = 1;

    //横屏和竖屏判断 主要涉及裁剪方式
    public static bool s_isHorizontalScreen = true;

    //原始长宽比
    public static float s_originalHVRatio;

    // ----- Awake -----
    private void Awake()
    {
        //初始化
        m_cameraSize = m_originalHeigh / 2;
        s_cameraSize = m_cameraSize;

        //设置长宽比
        s_originalHVRatio = (float)m_originalWidth / m_originalHeigh;

        //当前长宽比
        float currentHVRatio = (float)Screen.width / Screen.height;

        float t1 = Screen.height * m_originalWidth;
        float t2 = Screen.width * m_originalHeigh;
        float temp;
        /* 情况2
         * ------------------
         * |                |
         * |----------------|
         * |                |
         * |----------------|
         * |                |
         * ------------------
         */
        if (currentHVRatio > s_originalHVRatio)
        {
            s_isHorizontalScreen = true;

            //得到纵向高的比值
            s_scaleRatio = s_originalHVRatio / currentHVRatio;
            //得到缩放后的Size大小
            temp = m_cameraSize * s_scaleRatio;

            s_topCenter = temp - m_cameraSize;
            s_bottomCenter = -s_topCenter;
            s_leftCenter = 0; s_rightCenter = 0;
        }
        /* 情况1
        * ------------------
        * |   |       |    |
        * |   |       |    |
        * |   |       |    |
        * |   |       |    |
        * |   |       |    |
        * ------------------
        */
        else
        {
            s_isHorizontalScreen = false;
            //这个可划分为 “目标长 / 预设长 = 缩放比例”该比例<1
            s_scaleRatio = currentHVRatio / s_originalHVRatio;
            temp = m_cameraSize;

            s_topCenter = 0; s_bottomCenter = 0;
            s_leftCenter = (1 - s_scaleRatio) * m_cameraSize * s_originalHVRatio;
            s_rightCenter = -s_leftCenter;
        }

        //设置摄像机的size
        foreach (var a in m_cameras)
        {
            if (a != null) a.orthographicSize = temp;
        }
    }
}
View Code

  代码中需要理解一下的地方就是 “第91行”“s_scaleRatio = currentHVRatio / s_originalHVRatio;” 

       “当前长 / 当前宽" 除以 “预设长 / 预设宽” 由于 情况1中 当前宽 = 预设宽 所以 上列算式可以划分为 "当前长" 除以 “预设长” 

以下是分辨率受控体代码(受控体部分)

/***************************************
Editor: Tason
Version: v1.0
Last Edit Date: 2018-XX-XX 
Tel: 328791554@qq.com
Function Doc: 
分辨率子对象 配合 ResoulutionController 控制手机适配
***************************************/

using UnityEngine;
using System.Collections;


public class ResolutionObject : MonoBehaviour
{
    //情况1 (长宽比减小)是否缩放
    public bool m_state1ScaleSwitch = true;
    //情况2 (长宽比增加)是否缩放
    public bool m_state2ScaleSwitch = true;

    //对齐锚点选择
    public bool m_top;
    public bool m_bottom;
    public bool m_left;
    public bool m_right;

    // ----- Start -----
    private void Start()
    {
        Vector3 v;
        if (!ResolutionController.s_isHorizontalScreen && m_state1ScaleSwitch)
            transform.localScale *= ResolutionController.s_scaleRatio;
        if (ResolutionController.s_isHorizontalScreen && m_state2ScaleSwitch)
            transform.localScale *= ResolutionController.s_scaleRatio;

        if (m_top)
        {
            v = transform.position;
            v.y = ResolutionController.s_cameraSize * (1 - ResolutionController.s_scaleRatio) + transform.position.y * ResolutionController.s_scaleRatio + ResolutionController.s_topCenter;
            transform.position = v;
        }

        if (m_bottom)
        {
            v = transform.position;
            v.y = ResolutionController.s_cameraSize * (ResolutionController.s_scaleRatio - 1) + transform.position.y * ResolutionController.s_scaleRatio + ResolutionController.s_bottomCenter;
            transform.position = v;
        }

        if (m_left)
        {
            v = transform.position;
            v.x = ResolutionController.s_cameraSize * ResolutionController.s_originalHVRatio * (ResolutionController.s_scaleRatio - 1) + transform.position.x * ResolutionController.s_scaleRatio + ResolutionController.s_leftCenter;
            transform.position = v;
        }

        if (m_right)
        {
            v = transform.position;
            v.x = ResolutionController.s_cameraSize * ResolutionController.s_originalHVRatio * (1 - ResolutionController.s_scaleRatio) + transform.position.x * ResolutionController.s_scaleRatio + ResolutionController.s_rightCenter;
            transform.position = v;
        }
    }
}
View Code

使用方法:

1.挂载Controller 设置对应预设值参数

2.挂载子对象控制器 设置其属性


 

不同缩放的距离说明(锚点不做说明)

1.情况1、2的缩放要求很多时候不一样 例如下图的妹子在勾选不同情况的缩放时···呈现的状态

如图上的妹子就应该 打开“横向缩放” 关闭"纵向缩放"

Update 1.1

1.以修改了Controller的适配BUG,原来有2个固定常量,现在修改成了变量(上面代码已经修改了但是忘记改版本号了)。

举个例子


 使用方式

1.导入NGUI插件,创建背景图,删掉UIRoot对象下的UIRoot组件(即它自己的分辨率适配部分)。

2.将ResolutionController挂载在UIRoot对象下,修改UIRoot的Transform节点缩放为1, 并根据背景图片大小设置 CameraSize 及ResolutionController的分辨率参数。

3.将要修改的摄像机挂载添加到ResolutionController的控制数组中。

4.给需要缩放的物体挂载ResolutionObject 对象并调整参数,一般背景图是挂载对象,也不缩放的

下面我用新版本再举个例子

适配出来以后 

----->

 

posted on 2018-05-22 13:45  未闻花语  阅读(554)  评论(0编辑  收藏  举报