UGUI的分辨率自适应的机制

UGUI中,Canvas(画布)可以看成电脑屏幕,其功能和属性都是一样的。游戏中的分辨率自适应主要包括两部分:

1. 缩放适应:是在不同尺寸的屏幕下,整体缩放比例的计算方式——Canvas Scaler。

2. 布局调整: 是在不同比例(宽高比)的屏幕下,控制UI控件位置——Rect Transform。

一、图片的分辨率&&屏幕的分辨率

图片的尺寸:用图片的宽度和高度来表示,例如1280*720:1280=宽度,720=高度。而宽度和高度表示是以像素为单位的,即图片的组成就需要92万左右的像素点来实现,这才是图片实际的尺寸(当然也有用厘米的,但是需要分辨率(dpi)来转换)。

分辨率:是指显示图片时的精度,单位是dpi(每英寸包含的像素数)。例如,对于同一张尺寸的数字图片1600*1200,在300dpi的打印机上打印出来,面积为:宽1600/300*2.54=13.5cm,高1200/300*2.54=10.2cm。而如果设置成150dpi打印,则面积为27*20cm。

因此,图片的表现尺寸,是由图片的像素数和分辨率共同决定的:

像素数不变,分辨率增加,表现尺寸减小;

像素数不变,分辨率减小,表现尺寸增大;

屏幕分辨率:是指屏幕显示的分辨率,屏幕分辨率确定计算机屏幕上显示多少信息的设置,与分辨率概念的表示方式不同,屏幕分辨率是以宽和高的像素数来衡量。例如:屏幕分辨率=160*128,表示屏幕在宽度(水平)包含160个像素,在高度(垂直)包含128个像素,而这些像素就是屏幕总共可以提供的像素数量,也是其性能表现之一。

注:屏幕分辨率表示与分辨率定义的表示不同的原因:

因为屏幕的物理尺寸在生产出来以后就是确定的,因此屏幕的尺寸(像素数量)与分辨率的关系是正线性的关系,而且屏幕的功能是为了展示出图片等内容,那么屏幕分辨率直接以它的像素数而不是dpi,来表示的话更为直接易于使用。

图片在屏幕上的表现与屏幕分辨率的关系:

图片的尺寸也是以像素数来衡量的,比如:1280*720的图片,想要在屏幕上展现图片的话,就需要将图片的像素全部在屏幕上表现出来。这就是说如果屏幕的分辨率也是1280*720的话,想要渲染出这张图片,那么这张图片的最开始的大小,将会铺满整个屏幕,如果屏幕分辨率小于图片尺寸的话,图片将无法完整的在屏幕上表现出来。

二、整体缩放比例(Canvas Scaler组件

UGUI中,Canvas(画布)可以看成电脑屏幕,其功能和属性都是一样的。Canvas Scaler组件是负责整体缩放机制的、控制UI元素的总体大小和像素密度的组件,Canvas Scaler的缩放比例会影响Canvas下的UI元素,包含字体大小和图像边界。

Size相关的概念:

Reference Resolution:参考分辨率,即预设的屏幕的大小。

Screen Size:当前屏幕的分辨率,屏幕大小。通过State->Screen查看。

Canvas Size: 画布的Rect Transform组件的Width和Height,即画布的大小。

(UI Scale Mode)缩放模式提供了三种方式:

1.  Constant Pixel Size(固定像素尺寸)

该算法下会使Canvas Size始终等于Screen Size,然后通过Scale Factor直接缩放所有UI元素(实际上是通过改变Canvas的分辨率,来改变UI元素的表现尺寸,以达成缩放的目的),     包括两个参数:

1). Scale Factor(缩放比例):在UI元素原尺寸上的缩放比例,实际上是用于缩放整个Canvas,来保证Canvas Size与Screen Size始终为一样的,默认值是1。

Canvas Scaler 通过设定Canvas下的Scale Factor,縮放所有在此Canvas下的元素

当Scale Factor为2时,Screen Size (800*600)、Canvas Size(400*300),图片表现大小2倍(像素数不变)。

2). Reference Pixels Per Unit(标准每单位对应的像素数):每个unity单位对应的像素数。

图片设置中的Pixels Per Unit

Pixels Per Unit:是在这张Sprite中,世界坐标中的一单位由几个Pixel组成。

举例来说:

场景中有一个1*1Cube和一个Sprite图片大小为100*100,两者的Scale都为1。

Pixels Per Unit=100时,每单位由100pixel组成,sprite是100*100Pixels,那么sprite

在世界中的大小就会变成1*1Unit;

Pixels Per Unit=10时,每单位由10Pixel组成,sprite是100*100Pixels,那么sprite

在世界中的大小就会变成10*10Unit;

因此可以得出结论:

图片在世界坐标中的大小 = 原图大小(像素)/ Pixels Per Unit;

Canvas中的Reference Pixels Per Unit是一个参考的值,当图片本身具备Pixels Per Unit值时候,会重新计算出一个新值来代替使用,计算公式如下:

Scale = New Pixels Per Unit  =  Pixels Per Unit  /  Reference Pixels Per Unit

Image在渲染出来的时候,就是使用New Pixels Per Unit,来确定Image的表现尺寸的:

表现尺寸  =  宽(高)/  Scale

综合以上关系,可以得到一个公式:

UI大小(表现尺寸)= 原图大小(Pixels)  /  (Pixels Per Unit / Reference Pixels Per Unit)

2.  Scale With Screen Size(根据屏幕尺寸缩放)

按Reference Resolution(预设的的屏幕尺寸)进行缩放的方式,包括四个参数:

1). Reference Resolution(参考分辨率):

这是我们提供给美术做图的标准分辨率,所有的UI素材都应该按这个分辨率去做。

2). Screen Match Mode(缩放模式):

a. Expand(扩大):通过将Canvas Size进行宽或高扩大,让其高于Reference Resolution。就是说如果实际屏幕分辨率与预设的不一致,那么将会往大了调整

例如:Reference Resolution = 1280*720,Screen Size = 800*600的情况。

ScaleFactor Width: 800/1280=0.625

ScaleFactor Height:600/720=0.83333

因为要使用最大程度的放大的方式,那么此时就会选用ScaleFactor Width的值0.625,用它求得的值都是进行了扩大。

Canvas Size的求解公式:

Canvas Size = Screen Size / Scale Factor

 

Canvas Width:800 / 0.625 = 1280

Canvas Height:600 / 0.625 = 960

Canvas Size 为 1280*960,高度从720变成了960,最大程度的放大Canvas的尺寸。(其中UI元素的在高度方向的表现尺寸会变小,这样更有利于显示所有元素)。

b. Shrink(收缩):与扩大相反,将Canvas Size进行宽或高的收缩,让其分辨率始终低于Reference Resolution的值。

例如:例如:Reference Resolution = 1280*720,Screen Size = 800*600的情况。

ScaleFactor Width: 800/1280=0.625

ScaleFactor Height:600/720=0.83333

因为要使用最大程度的放大的方式,那么此时就会选用ScaleFactor Width的值0.8333,用它求得的值都是进行了扩大。

Canvas Size的求解公式:

Canvas Size = Screen Size / Scale Factor

Canvas Width:800 / 0.8333 = 960

Canvas Height:600 / 0.8333 = 720

Canvas Size 为 960*720,高度从1280变成了960,最大程度的缩小Canvas的尺寸。(其中UI元素的在宽度方向的表现尺寸会变大)。

c. Match Width or Height(根据宽和高进行混合缩放):该算法首先分别对ScaleFactor Width/Height取对数,然后在进行平均混合。

比较一般混合和取对数混合的差别:

例如:Reference Resolution=400*300,Screen Size为200*600的情况,如下图:

ScaleFactor Width:200/400=0.5

ScaleFactor Height:600/300=2

当march=0.5时,

一般混合:

ScaleFactor = March * ScaleFactor Width + March * ScaleFactorHeight

ScaleFactor = 0.5 * 0.5 + 0.5 * 2 = 1.25

对数混合:

logWidth:log2(0.5) = -1

logHeight:log2(2) = 1

logWeightedAverage:0

ScaleFactor:20 = 1

很明显,对数混合得到的1更加合理,能够更完美的修正Canvas的大小。

宽高所占权重:默认值是0,相当于以“标准分辨率的宽”和“实际屏幕的宽”的比例作为缩放比例;如果值是1,相当于以“标准分辨率的高”和“实际屏幕的高”的比例作为缩放比例;如果值是0.5,则相当于宽和高的比例权重相等,最终的缩放比=宽缩放比*宽权重+高缩放比*高权重

3). Reference Pixels Per Unit:每个unity单位对应的像素数。

         3.  Constant Physical Size(固定物理尺寸)

这种方法是通过给定dpi(dots Per Inch 每英寸点数),来进行缩放。

1).Phsical Unit:使用的单位的种类

单位种类

中文

与1英寸的关系

Centimeters

公分(cm,厘米)

2.54

Millimeters

公毫(mm,毫米)

25.4

Inches

英寸

1

Points

72

Picas

皮卡(十二点活字)

6

2). Fallback Screen DPI:对应物理单位的像素密度。

3). Default Sprite DPI:默认的图片的dpi值。

功能总结:

在这种算法下的缩放比例Scale Factor计算公式:

Scale Factor = Physical Unit / Default Sprite DPI。

Reference Pixels Per Unit要跟目前的dpi共同作用运算处新值以后,传入Canvas中求出大小,公式如下:

New Reference Pixels Per Unit = Reference Pixels Per Unit * Scale Factor

UI大小 = 原图大小(Pixels)  /  (Pixels Per Unit  /  New Reference Pixels Per Unit)

=原图大小(Pixels)  /(Pixels Per Unit* Pixels Per Unit / Reference Pixels Per Unit * Physical Unit )

在这种情况下,的Canvas Size是始终等于Screen Size的。依据像素进行放缩,实际上是将UI元素的放缩单独拿出来,脱离了与Canvas 的关系,主要影响它的放缩值的是预设的dpi的值。

实施步骤:

1. 确定设备屏幕分辨率的宽高比例。

一般情况下,需要根据要覆盖的机型(手机基本在1.5:1~1.8:1的范围内),得到其大概的宽高比的范围 ,选择确定一个合适的宽高比。

2. 确定UI制作的目标分辨率

确定了宽高比以后,选择目标分辨率,通常以1024作为宽,以1024*1.7=602作为高比较合适,因为一般的压缩格式会要求宽高是2的次幂或4倍数。

3. 设置Unity中适配规则

通常是做一张比较大的背景图,图中上下左右边的内容允许被裁剪。但适配到1.8:1的设备上的时候,由于背景图内容宽度小于设备宽度,此时需要使用“宽”适配。这时背景图上的上下边被裁剪掉;反之,使用“高”适配。

标准分辨率下,此时背景图是最完整的。

三、布局(Rect  Transform组件

布局是对Canvas内的UI元素而言的。在适配分辨率方面,除了等比缩放外,还有一方面是对UI控件位置的适配,例如角色头像一般处在屏幕的左上角,虚拟摇杆处在屏幕的左下角,要想在不同的分辨率下都处在比较合适的位置,就需要理解“锚点”的作用了。

当我们在标准分辨率下定位好控件后,设置好合适的锚点,不论在那种分辨率下,控件都会处于一个合适的位置。

具体内容见——《Unity中的Rect Transform》。

UGUI学习——Canvas基础组件的更多相关文章

  1. UNITY3D UGUI学习--canvas

    首先从canvas的参数说起走. Canvas Component是UI布局和渲染的抽象空间,所有的UI元素都必须在此组件之下. Render Mode UI的渲染方式,有三种: Screen Spa ...

  2. HTML5移动开发学习笔记之Canvas基础

    1.第一个Canvas程序 看的是HTML5移动开发即学即用这本书,首先学习Canvas基础,废话不多说,直接看第一个例子. 效果图为: 代码如下: <!DOCTYPE html> < ...

  3. Ext学习-基础组件介绍

    1.目标    学习对象获取,组件基础,事件模型以及学习ExtJS中的基础组件的应用. 2.内容   1.对象获取   2.组件原理以及基础   3.事件模型   4.常用组件的介绍 3.学习步骤 1 ...

  4. Ext JS 6学习文档-第3章-基础组件

    Ext JS 6学习文档-第3章-基础组件 基础组件 在本章中,你将学习到一些 Ext JS 基础组件的使用.同时我们会结合所学创建一个小项目.这一章我们将学习以下知识点: 熟悉基本的组件 – 按钮, ...

  5. Spark学习之基础相关组件(1)

    Spark学习之基础相关组件(1) 1. Spark是一个用来实现快速而通用的集群计算的平台. 2. Spark的一个主要特点是能够在内存中进行计算,因而更快. 3. RDD(resilient di ...

  6. android学习——必学基础组件

    android基础组件是一个Android的开发人员必须要了解,且深刻理解的东西: 1.应用程序基础 2.应用程序组件 2.1.活动(Activities) 2.2.服务(Services) 2.3. ...

  7. canvas一周一练 -- canvas基础学习

    从上个星期开始,耳朵就一直在生病,里面长了个疙瘩,肿的一碰就疼,不能吃饭不能嗨 (┳_┳)……在此提醒各位小伙伴,最近天气炎热,一定要注意防暑上火,病来如山倒呀~ 接下来我正在喝着5块一颗的药学习ca ...

  8. canvas基础学习

    /** * Created by ty on 2016/7/11. * canvas 基础 */ window.onload = function() { var canvas = document. ...

  9. Unity UGUI之Canvas&EventSystem

    最近想写一套关于UGUI所有控件的基础使用教程系列,主要是根据本人的使用心得来写的,所以其中可能难以避免会有不正确的地方. 好了进入主题,既然是第一篇,我觉得我有必要先介绍一下UGUI必不可缺的两个组 ...

随机推荐

  1. html中form表单的使用方法和介绍

    from表单的使用方法 一.表单赏析 二.了解表单功能:用于搜集不同类型的用户输入的内容 有了表单,网页的内容可以由用户自己创建,那么对于网页来说,我们既是网页创建都者,也是网页的消费者. 三.常用的 ...

  2. [图形学] B样条曲线 - 原理和C++实现的演示程序(附源码)

    http://blog.csdn.net/mahabharata_/article/details/71856907 大二的时候,曾受老师所托,用C++而不是OpenGL去写B样条曲线的教学程序.时隔 ...

  3. windows环境下,spring boot服务使用docker打包成镜像并推送到云服务器私有仓库

    最近在淘宝上学习springcloud教程,其中有几节课是讲解讲本地springboot服务打包成镜像并推送到云服务器私有仓库,但是教程里面用的事Mac环境,我的是Windows环境,而且课程里面没有 ...

  4. python中下划线的特殊用法

    python下划线用法总结: ① _XXX 不能用于“ from  model import * ”的导入: ②__XXX__ 系统定义名字: ③__XXX 类中的私有变量名. 总结:避免随意用下划线 ...

  5. Linux监控

    第三十次课 Linux监控 目录 一. Linux监控平台介绍 二. zabbix监控介绍 三. 安装zabbix 四. 忘记Admin密码如何做 五. 主动模式和被动模式 六. 添加监控主机 七. ...

  6. AJAX的简单示例:注册校验

    众所周知,我们每次需要注册一个网站的用户名时,都会校验该邮箱.用户名是不是正确的格式.是不是有被使用过,密码是否符合规则,二次确认是否符合. 如果这些校验都采用form表单提交的话,会给用户带来极不好 ...

  7. jsp脚本的九个内置对象

    JSP脚本中包含9个内置对象, 这9个内置对象都是Servlet API 接口实例, 只是JSP规范对它们进行了默认初始化(由JSP 页面对应Servlet 的jspService()方法来创建这些实 ...

  8. django之信号

    Django中提供了“信号调度”,用于在框架执行操作时解耦.通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者. 1.Django内置信号 Model signals     pr ...

  9. python 实现程序重启

    def restart_program(): """Restarts the current program. Note: this function does not  ...

  10. nim读写注册表的小例子

    nim读写注册表的小例子 2018年5月7日 15:11:58 codegay 贴一个nim读写注册表的例子,虽然简单,但是nim官方没有写windows注册表相关的文档, 我贴的例子兴许能帮大家省点 ...