这是很久之前写的一篇Note,现在移到Blog上来,可能有些参数,NGUI插件等等不和现在版本相同.不过大概的思路应该不会错.

ps:

  可能有部分內容是摘抄自其他作者,没办法考证了,如有请务必联系我.标明来源

  大部分游戏都是高度适配,即固定高度,根据宽高比裁剪两边的宽度,而由于这个Note文档是为一个竖版游戏写的.所以有点特立独行的采用了宽度不变适配,而且只裁剪上方高度,以下边缘对齐.不过,高度or宽度适配的原理是相同的.

第一部分 对于非NGUI相机
/* 
     * Unity 宽度不变适配的原理 
     *  
     * 以宽度确定为640,适配最小宽高比 1.5 - 1.8,即 640*960 - 640*1152 为例 (宽不变,高度从960 - 1152 之间裁剪) 
     *  
     * 1. 计算当前屏幕分辨率下,保持屏幕宽高比不变,宽度缩放为640时的高度 
     *      屏幕实际高/屏幕实际宽 = x/640 
     *      x = (屏幕实际高/屏幕实际宽) * 640 
     *  
     *      eg: 手机分辨率为 1136 * 640 -> x = (1136 / 640) * 640 = 1136 
     *  
     * 2. 计算当前相机Size 
     *      Unity的相机高度由相机Size确定,Size定了之后,相机高度就固定了,不同的手机会根据这个高度和自身分辨率,确定宽度. 
     *      Unity相机的高度像素 = Size * 2 * 100 (100为Unity相机Size和实际像素的对应关系) 
     *      当确定宽度不变为640时,需要变的是高,而高的变化又因为Unity根据高度和分辨率确定宽,所以,反推高为 
     *      (Size * 2 * 100) / 640 = 屏幕实际高 / 屏幕实际宽 
     *      Size = ( (屏幕实际高/屏幕实际宽) * 640 ) / (2 * 100) 
     *      带入1步骤计算的x -->  Size = x / (2 * 100) 
     *       
     *      eg: Size = 1136 / 200 = 5.68 
     *  
     * 3. 计算相机需要在y轴上的移动距离 保持下面对齐 
     *      由于Unity是高度固定,当我们改变相机Size时,等比放大了宽和高,此时由于上面根据宽计算的高,所以宽度是正好合适的,而此时由于界面是居中的,在相机会在上下两个位置出现裁剪变化 
     *      (如果Size变小了,即上下两边被多裁掉,如果Size变大,则上下会多显示出来一些内容),为了UI的一致性,我们只允许相机在上面进行裁剪变化,这样就需要上下移动相机位置.保持下面不变, 
     *      移动距离 = (固定640宽度时的当前高度 - 1152) / ( 2 * 100 ) 
     *      说明: 如果由于要适配最大高为1152,所以,美术的UI尺寸按照1152进行设计,而固定640宽度的所有设备计算出来的高肯定低于1152(宽高比小于1.8),因此上下会被裁剪,若UI按底部对齐, 
     *      则需要将相机向下移动,此时,移动的距离即为上面公式得出 
     *  
     *      eg: (1136 - 1152) / 200 = -0.08 即相机在y轴需要移动 -0.08 单位高度 
     *  
     *  
     * 总结: 
     *      1. 设计最大高度1152,最小高度960,固定宽度640 
     *      2. 屏幕高/屏幕宽 * 640 = x; 
     *      3. Camera.Size = x / 200; 
     *      4. Camere.Transform.y += (x - 1152) / 200; 
     *  
     */

 
 
第二部分 对于NGUI相机 
 
1. 由于 NGUI的自带了适配的逻辑,并且由于Unity里一个单位等于实际的100个像素 ,例如:相机大小为1时,其实其高度为 1 * 2 * 100 = 200像素 
(相机大小是指的相机框一半的大小,相机中心在中点,所以乘以2)

这样在Unity里移动Obj十分麻烦,因为Position是100倍的(1单位等于100像素)
NGUI为了保证我们在场景里摆放Obj时方便逐像素的调整,所以在UI Root脚本上自动设置了LocalScale的缩放,详情见http://blog.csdn.net/monzart7an/article/details/23366443
而且保证了相机的尺寸始终保持为1.这样UIRoot上的缩放计算方式为:  ( 1 / 设定高度 ) * 2 例如 : 设置固定高为 960 则缩放应该为 0.0020833
若固定高为960 , 实际Camera.Size = 960 /( 2 * 100 )  = 4.8 为了把Size固定在1,相当于缩放了4.8个Unity单位,相当于缩放了4.8*100 = 480个像素单位,即缩放比例为 1/480 = 0.0020833
所以UIRoot的LocalScale =1 / ( 高 / (2 * 100) * 100 ) = 1/(高/2) = 2 / 高, 此时如果沿着高移动一个物体,当移动960像素时,实际移动的Unity单位为 960 * ( 2 / 960 ) = 2 ,而Camera.Size = 1,
Camera的高为 1 * 2 = 2. 所以正好是移动了一个相机的显示区域,所以,在相机的显示区域来看,高度 为2个Unity单位,也即960个像素单位,所以,我们在拼接UI时,可以按照像素进行拼接.
 
在我们进行宽度适配时,由于上述的NGUI适配算法,所以根据自身项目情况,我们需要动态的调整Camera.Size 和 Camera.LocalPostion.y 以保证显示区域始终是向下对齐而且宽度不变的,如下图

分别对上图进行解释,图中以固定NUGI高为1152进行示例,图中黑色区域为1152*640像素

1) 图一中: Camera.Size = 1. Camera.localPos.y = 0, 屏幕分辨率为 1152 * 640, 宽高比为 1.8 , UIPanel缩放为 2/1152

此时可以看到图中相机尺寸和UIPanel尺寸完全重合,不需要对Camera做任何调整

2) 图二中:Camera.Size = 1. Camera.localPos.y = 0, 屏幕分辨率为 960 * 640 , 宽高比为 1.5 , UIPanel缩放为 2/1152

此时可以看到当分辨率变了之后,宽高比变小,由于固定了高,所以高不变的情况下,宽变大(实际变为1152/1.5=768),此时需要缩小Camera.Size以使得在宽高比变小后,Camera显示的宽依然保持640,

所以根据固定高1152.和固定高之后实际宽=768,宽需要缩放到640,即缩放比例为 640 / 768 = 0.8333,所以Camera.Size = 0.8333 (见图三)

3)图三中:Camera.Size = 0.8333. Camera.localPos.y = 0, 屏幕分辨率为 960 * 640 , 宽高比为 1.5 , UIPanel缩放为 2/1152

此时Camera.Size已经缩放为0.8333,相机区域完全和960*640显示边界重合,但是由于相机的宽和高同时缩小.导致相机显示区域的上下部分被裁剪,而为了保证向下对齐,我们需要把相机向下移动,以保证实现宽适配+向下对齐.

Camera向下移动的计算方法为: (实际高 -  固定高) / 2 即为 ( 960 - 1152 ) / 2 = -96, 由于向下移动,所以得出负数
 
4)图四中:Camera.Size = 0.8333. Camera.localPos.y = -96, 屏幕分辨率为 960 * 640 , 宽高比为 1.5 , UIPanel缩放为 2/1152 
图四是根据宽度适配,向下对齐的原则完成调整后的效果,可以看到图四(分辨率960*640)的下半部分和图一(分辨率1152*640)的下半部分完全相同,只是在图一的上部分进行了裁剪,
所以,美术在拼UI界面时可以按照宽度不变,向下对齐的原则进行拼接

<如有错误,敬请指出,不胜感谢>

Unity 宽度适配 NGUI的更多相关文章

  1. Unity插件之NGUI学习(8)—— Table和NGUI尺寸转换为世界坐标系尺寸

    依据 Unity插件之NGUI学习(2),创建一个UI Root,在UI Root下创建一个Texture作为背景图,并设置图片,在Wiget下调整大小:然后在UI Root下再创建一个Panel. ...

  2. Unity该插件NGUI得知(9)—— Tween并转换成世界坐标系的大小NGUI尺寸

    在游戏中,还有一种比较常见的动画,这是进球后产生,分数将被显示在游戏,而快速移动,使其失去位置加入.就打算使用NGUI的Tween来制作这样的分数动画效果. 依据 Unity插件之NGUI学习(2), ...

  3. Unity插件之NGUI学习(4)—— 创建UI2DSprite动画

    创建一个新的Scene.并按 Unity插件之NGUI学习(2)创建UI Root,并在UI Root的Camera下创建一个Panel. 然后在选中Panel,在菜单中选择NGUI->Crea ...

  4. Unity插件之NGUI学习(5)—— 创建Label图文混排及文字点击

    创建一个新的Scene,并按 Unity插件之NGUI学习(2)创建UI Root. 准备工作,制作Font.如今Project窗体创建一个Font目录.然后从系统自带字体目录中选择自己须要的字体,我 ...

  5. 【学习中】Unity插件之NGUI 完整视频教程

    课程 章节 内容 签到 Unity插件之NGUI 完整视频教程 第一章 NGUI基础控件和基础功能学习 1.NGUI介绍和插件的导入 6月29日 2.创建UIRoot 6月29日 3.学习Label控 ...

  6. 关于Unity中的NGUI精灵

    NGUI精灵实例 1.创建Unity项目工程和文件目录,保存场景 2.创建一个精灵NGUI---->Create---->Sprite,发现它的UI Sprite组件的贴图属性只支持Atl ...

  7. 关于Unity中的NGUI和UGUI

    一.用Unity开发2D游戏,有三套关系 1.GUI:Unity本身自带的GUI 2.NGUI:以前在Unity中广泛来做2D的,是第三方的包,需要安装 3.UGUI:Unity5.X后(其实是Uni ...

  8. Unity开发之NGUI系列

    Unity插件收集 在Unity开发过程中会收集一些插件,收集这些插件的目的并不是我喜欢在开发中使用插件,而是本着喜欢的态度去收集的,就像我喜欢收集模型一样: 还有一点就是通过了解插件能让我知道Uni ...

  9. 关于Unity中的NGUI字体

    NGUI字体类型 1: UIFont字体,UIFont类实现的2: TTF动态字体的使用3: BBCode的特殊字体的使用4: NGUI字体制作5: BMFont字体制作和艺术字体的制作6: UILa ...

随机推荐

  1. Java 13新特性

    switch表达式 switch表达式是Java 12开始就提供的预览特性,到了Java 13仍然没有被转正.此特性可以把switch的执行结果组合到复合表达式中进行运算. import java.t ...

  2. mac安装 bcolz出现错误

    使用的是命令pip install bcolz c-blosc//snappy-stubs-:: fatal error: 'algorithm' file not found #include &l ...

  3. js下利用userData实现客户端保存表单数据

    对于多数网页制作的朋友,实现在客户端保存在网页表单上的信息,比较多的是采用Cookie技术来实现,这些功能例如:下拉列表框选择的选项,文本框输入的数据等. 事实上,我们可以利用微软DHTML默认行为中 ...

  4. Python编译出现错误SyntaxError: Non-ASCII character '\xe7' 时解决方法

    转载个解决办法:https://blog.csdn.net/wangchao701123/article/details/57084244 转自https://blog.csdn.net/jim742 ...

  5. AWS 云上安全最佳实践

    目录 一.账号及访问管理 1.1.多 VPC 还是多账号模式 1.2.多账户模式,选择主 master 账号 二.系统架构安全 2.1.子网建议 2.2.每个可用区子网划分 2.3.安全组的建议 2. ...

  6. 微服务之Polly熔断策略

    NET Core 微服务之Polly熔断策略 紧接着上一篇说,咱们继续介绍Polly这个类库 熔断策略(Circuit-breaker) 如果调用某个目标服务出现过多超时.异常等情况,可以采取一定时间 ...

  7. codevs1227:方格取数2

    题目描述 Description 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= )现在从(,)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该 ...

  8. CDH6.2的fair-scheduler.xml

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?><alloc ...

  9. Python基础——循环语句、条件语句、函数、类

    注:运行环境  Python3 1.循环语句 (1)for循环 注:for i in range(a, b):  #从a循环至b-1 for i in range(n):      #从0循环至n-1 ...

  10. [转帖]hdfs hbase hive hbase适用场景

    hdfs hbase hive hbase适用场景 https://www.cnblogs.com/liyulong1982/p/6001822.html Hive 不想用程序语言开发MapReduc ...