• 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 对象并调整参数,一般背景图是挂载对象,也不缩放的

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

    适配出来以后 

    ----->

  • 相关阅读:
    【Java集合】-- LinkedList源码解析
    【Java集合】--ConcurrentHashMap源码解析
    【Java集合】--ConcurrentHashMap源码解析
    【Java集合】-- CopyOnWriteArrayList源码解析
    【Java集合】-- CopyOnWriteArrayList源码解析
    【Java集合】-- ArrayList源码解析
    【Java集合】-- ArrayList源码解析
    【Java集合】-- HashMap源码解析
    工厂模式和抽象工厂模式
    常见的排序算法整理
  • 原文地址:https://www.cnblogs.com/jwv5/p/9071653.html
Copyright © 2020-2023  润新知