主要代码:UIRoot,UIOrthoCamera,UIRect.GetSides(UIPanel使用UIRect的)里的GetSides,代码量很少,但需要思考和测试验证。

一、UIRoot的基本内容:
1.提供2种适配方式:pixel perfect和fixsize(新版本改成Flexible和Constrained,但一样的)
  前者是一个50x50的图标,无论在1280x720还是500x500的分辨率(屏幕尺寸)的屏幕上,都占屏幕中50x50的像素数目,所以在500x500的分辨率下会显得很大(因为它屏占比变大了许多);
  后者是无论在什么分辨率下,只要分辨率的比例是一样的,图标的屏占比不变。
  一开始我以为是后者做了额外的东西,深入了解后发现其实是前者做了额外的东西,后者啥都没干,现在先来看后者的效果是怎么出来的:
    fixsize保持UIRoot的scale恒定,且UICamera的orthographicSize=1恒定,并且每个dc对应的mesh的位置,顶点世界坐标等都不变,
屏幕尺寸变化时(比例不变),变的只有屏幕尺寸,所以它只是把相同的东西(mesh)渲染到不同的分辨率屏幕而已,就这样有了不变的屏占比。
    而如果分辨率比例变了,需要更新各个锚了UIPanel的物体的坐标,让他们新的水平边界,如果比例小于manulWidth/manulHeight,
则物体往中间“挤”,如果大于则往外面拉。
  而pixel perfect则根据屏幕尺寸不断变化UIRoot的scale,触发了2件事情,一个是各个锚点的更新(主要是需要更新锚UIPanel的物体),
一个是dc的重绘,所以各个mesh的位置,坐标等都发生了改变,为的就是维护图标的占的像素数目不变

2.无论是哪种方案,锚在UIPanel的物体可以认为是锚在uicamera的视口矩形上,这个矩形是height=2(即中心到上下边界都是1)的矩形,width根据视口比例得到,
所以当比例变的时候需要更新锚点,得到的mesh也会变。
(注:height能保持2这么小且固定是因为uiroot上加了缩放,把mesh都缩到这个固定矩形里了,具体我后面会谈到)

3.所以NGUI的适配做了2件事情:
  1).当分辨率比例变换时,更新锚点,让那些锚在视口的物体更新位置,移动物体的位置保证物体锚在视口的正确位置。
  2).当分辨率比例不变,只是尺寸变了,根据不同的适配方式对UIRoot设置不同scale,并且当scale变时更新锚点(因为最上层scale变时,下层的position变了,需要更新锚点)。
  UIRoot的处理是,先2后1,即先设置scale,缩放物体,然后更新锚点,让缩放后的物体锚到height=2的矩形里,所以无论scale是多少,
只要物体是锚在UIPanel上,那物体都在视口内。

4.但做适配的一般思路应该是,设置UICamera的orthographicsize,来确定相机的视口矩形(视口矩阵就是height=2*orthographicsize的矩形)
以在更新锚点后,物体的位置和大小能正确显示在视口内,估计NGUI原来也是这样做的,可以参考UIOrthoCamera脚本,我把orthographicsize
设死为720/2后,并且把UIRoot去掉,效果和fixsize一模一样,而设为screenheight/2,并加上发送UpdateAnchors事件后,效果和pixel perfect一样。
这种思路是拿相机去套物体,细节是设好相机视口,然后把物体锚到视口矩形里。
  fixsize模式:
    分辨率相同比例但不同尺寸下:视口矩形保持不变,所以只是把相同的东西显示到不同尺寸的屏幕而已。
    分辨率比例不同:视口矩形变了,更新锚点,物体的位置变化,一般保持视口矩形的height,根据视口比例算出width
  pixel perfect模式:
    视口矩形直接用屏幕分辨率矩形,所以视口矩形随屏幕尺寸变而变,更新锚点,物体都“挤”在视口矩形中,所以图标占的像素数目是不变的。
5.但NGUI的新版本使用另外的思路:保持视口矩形的height=2,缩小物体,然后更新锚点,把物体塞到这么小的视口矩形中,缩小物体是通过UIRoot.localScale做的。

透过UIRoot深入理解NGUI提供的屏幕适配方案的更多相关文章

  1. Unity2D多分辨率屏幕适配方案(转载)

    一下内容转自:http://imgtec.eetrend.com/forum/3992 此文将阐述一种简单有效的Unity2D多分辨率屏幕适配方案,该方案适用于基于原生开发的Unity2D游戏,即没有 ...

  2. [原创]一种Unity2D多分辨率屏幕适配方案

    此文将阐述一种简单有效的Unity2D多分辨率屏幕适配方案,该方案适用于基于原生开发的Unity2D游戏,即没有使用第三方2D插件,如Uni2D,2D toolkit等开发的游戏,NGUI插件不受这个 ...

  3. Android 屏幕适配方案

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/45460089: 本文出自:[张鸿洋的博客] 1.概述 大家在Android开发 ...

  4. 实用Android 屏幕适配方案分享

    转载地址:http://blog.csdn.net/gao_chun/article/details/45645051 真正可用,并且简单易行,可以在多个屏幕大小和屏幕密度上有良好表现的Android ...

  5. 一种Unity2D多分辨率屏幕适配方案

    http://www.cnblogs.com/flyFreeZn/p/4073655.html 此文将阐述一种简单有效的Unity2D多分辨率屏幕适配方案,该方案适用于基于原生开发的Unity2D游戏 ...

  6. JavaScript强化教程 —— Cocos2d-JS的屏幕适配方案

    1. 设置屏幕适配策略(Resolution Policy) 如果你还没有用过Resolution Policy,只需要在游戏载入过程完成之后(cc.game.onStart函数回调中),调用下面的代 ...

  7. Cocos2d-JS的屏幕适配方案

    Cocos2d引擎为游戏开发者提供了屏幕适配策略(Resolution Policy)解决方案. 使用方式 1. 设置屏幕适配策略(Resolution Policy) 如果你还没有用过Resolut ...

  8. 给你一个全自动的屏幕适配方案(基于SW方案)!—— 解放你和UI的双手

    Calces系列相关文章:Calces自动实现Android组件化模块构建 前言 屏幕适配一直是移动端开发热议的问题,但是适配方案往往在实际开发的时候会和UI提供的设计稿冲突.本文主要是基于官方推荐的 ...

  9. Web 端屏幕适配方案

    基础知识 像素相关 1.像素 :像素是屏幕显示最小的单位. 2.设备像素 :设备像素又称物理像素(physical pixel),设备能控制显示的最小单位,我们可以把这些像素看作成显示器上一个个的点. ...

随机推荐

  1. day13. 迭代器与高阶函数

    一.迭代器 """ 能被next调用,并不断返回下一个值的对象,叫做迭代器(对象) 概念: 迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果 ...

  2. 笨办法学python3练习代码ex21.py

    def add(a, b): print(f"ADDING {a} + {b}") return (a + b) def subtract(a, b): #subtract :减去 ...

  3. 【NOIP2015】斗地主 题解(DFS+贪心)

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的AAA到KKK加上大小王的共545454张牌来进行的扑克牌游戏.在斗地主中,牌的大小关 系根据牌的数码表示如下: ...

  4. spring-Sessions are not supported by the MongoDB cluster to which this client is connected

    原因: 1.mongodb版本过低4.0以下不支持事务的情况下会报这个 2.安全认证问题参考如下连接 https://blog.csdn.net/ssehs/article/details/10530 ...

  5. 使用 Python 为女神挑选口红

    口红对于女生来说永远不嫌多,而男生也搞不明白珊瑚红.番茄色.斩男色等等颜色有什么区别,不都是红色么?当送给女神的口红是她不适合的,那结果就是口红进入垃圾箱还算是轻的,重则拉黑处理.男生们也不用着急,我 ...

  6. 同一台服务器部署三个Tomcat

    工具 apache-tomcat-8.0.30 安装tomcat步骤           1. 下载apache-tomcat-8.0.30 ,下载下来的文件为apache-tomcat-8.0.30 ...

  7. ECS7天实践进阶训练营Day1:使用阿里云ECS,快速搭建、管理VuePress静态网站

    一.概述 VuePress是2018年由尤雨溪发布的一个全新的基于Vue的静态网站生成器,它是一个非常轻量级的静态网站生成器.VuePress主要用于生成技术文档,其类似于Gitbook,我们可以用于 ...

  8. 基于Socket访问西门子PLC系列教程(二)

    本文是西门子开放式TCP通信的第2篇,上一篇我们讲了使用西门子1200PLC作为TCP服务器的程序编写,可以点击下方链接阅读:[公众号dotNet工控上位机:thinger_swj] 基于Socket ...

  9. 新司机的致胜法宝,使用ApexSql Log2018快速恢复数据库被删除的数据

    作为开发人员,误操作数据delete.update.insert是最正常不过的了,比如: 删除忘记加where条件: 查询为了图方便按了F5,但是数据里面夹杂着delete语句. 不管是打着后发动机声 ...

  10. RabbitMQ 基础概念进阶

    上一篇 RabbitMQ 入门之基础概念 介绍了 RabbitMQ 的一些基础概念,本文再来介绍其中的一些细节和其它的进阶的概念. 一.消息生产者发送的消息不可达时如何处理 RabbitMQ 提供了消 ...