Unity 宽度适配 NGUI

摘要:
这是很久之前写的一篇Note,现在移到Blog上来,可能有些参数,NGUI插件等等不和现在版本相同.不过大概的思路应该不会错.ps:可能有部分內容是摘抄自其他作者,没办法考证了,如有请务必联系我.标明来源大部分游戏都是高度适配,即固定高度,根据宽高比裁剪两边的宽度,而由于这个Note文档是为一个竖版游戏写的.所以有点特立独行的采用了宽度不变适配,而且只裁剪上方高度,以下边缘对齐.不过,高度or宽度

这是很久之前写的一篇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 宽度适配 NGUI第1张

这样在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 以保证显示区域始终是向下对齐而且宽度不变的,如下图
Unity 宽度适配 NGUI第2张Unity 宽度适配 NGUI第3张Unity 宽度适配 NGUI第4张Unity 宽度适配 NGUI第5张

分别对上图进行解释,图中以固定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》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇java如何操作注册表(Preferences类)(在windows的注册表中保存、读取)POI读取公式的值下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Dalsa相机使用问题记录——————————(一)IP配置

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Date: 20180821 1. 由于IP原因导致找不到相机 解决方法:查看相机IP,并配置好本地网口的网络属...

Unity基本操作

主要内容: C#学习 Unity项目 打砖块:BreakBricks Unity操作 Unity操作: 调试 碰撞体 触发器 视角键盘视角平移 光照贴图 游戏对象Gameobject 访问对象 实体化对象 Instantiate 得到组件 对象的移动 交互类 鼠标输入 键盘输入 调试 在某函数内进行`Debug.Log(...)...

unity inputfield 过滤emoji输入

unity版本:unity2017.1.5f1 复现步骤:InputField在安卓手机InputField连续输入两个emoji会报错 报错内容: 2020-01-08 19:56:38.366 22894-22931/? E/Unity: ArgumentOutOfRangeException: Argument is out of range....

unity 协程与async、await

协程(Coroutine) 协程就像一个函数,能够暂停执行并将控制权返还给 Unity,然后在指定的时间继续执行。协程本质上是一个用返回类型 IEnumerator 声明的函数,并在主体中的某个位置包含 yield return 语句。yield return 是暂停执行并随后在下一个时间点恢复。注意:Fade 函数中的循环计数器能够在协程的生命周期内保持...

《unity项目》打包安卓APK时Build Setting中的三种Build System

Internal(Default):Unity内置,仅需Android SDK支持。不能导出工程,适用于仅适用Unity开发的工程 apk。 Gradle(New):使用Gradle进行构建,需要Android SDK与Gradle支持,可以导出Android Studio工程 apk ; 选这个才能勾选下面的Export Project,适用于Uni...

线阵相机参数计算,选择合适的相机与镜头

1、精度=物宽/像素,此公式用来选相机。 如要求精度为0.3mm/pixel,物体宽1200mm,那么像素就是4K,所以选择4K相机。 2、物体最大移速=精度×最大行频,此公式用来计算相机是否满足移动速度。 0.3mm/pixel×26000Hz=7617mm/s,即物体移速低于457m/min即可,所以选的4K相机没有问题。 3、物距=焦距×精度/像元尺...