声明:此篇文章是个人学习笔记,并非教程,所以内容可能不够严谨。可作参考,但不保证绝对正确。如果你发现我的文章有什么错误,非常欢迎指正,谢谢哦

UI自适应

在学习Canvas Scaler组件之前,先来了解一下UI自适应,UI自适应就是让我们可以不对每种分辨率的屏幕上都设计一种UI布局,而只需要在开发的时候设计一种UI布局,就可以让UI在不同分辨率的屏幕上都能尽量正常的显示,这将会节省巨大的工作量。

而这一次要学习的Canvas Scaler组件就是用来快速的实现UI自适应功能的组件。

Canvas Scaler组件

官方文档:https://docs.unity3d.com/cn/current/Manual/script-CanvasScaler.html

画布缩放器组件用于控制画布中 UI 元素的整体缩放和像素密度。此缩放会影响画布下的所有内容,包括字体大小和图像边框。我们可以利用该组件去缩放全部UI元素从而适配不同分辨率的屏幕。

Canvas Scaler组件有三种模式,依次介绍

属性 功能
UI Scale Mode 缩放模式
Constant Pixel Size 无论屏幕大小如何,UI 元素都保持相同的像素大小。
Scale With Screen Size 屏幕越大,UI 元素越大。常用来设置UI自适应。
Constant Physical Size 无论屏幕大小和分辨率如何,UI 元素都保持相同的物理大小。

第一种模式 Constant Pixel Size

这个模式也是在Canvas在没有附加任何Canvas scaler情况下的默认功能。但是,借助Canvas Scaler中的“Scale Factor”属性,可以自由设定UI元素缩放的比例。

在这种模式下,锚点如果采用“矩形模式”(我自己取得名字)就会呈现一种在Rect Transform中提到的缩放效果,不过看起来挺奇怪的

在这种模式下,锚点如果采用“点模式”(还是我自己取得名字)也依然会按照在Rect Transform中提到的固定效果。但需要注意的是,这个时候UI元素的效果就会像该元素的名字一样,保持像素大小不变,不管屏幕大小如何变动。

属性 功能
Scale Factor 按此系数缩放画布中的所有 UI 元素,即这个数是全部UI元素的缩放比例。
Reference Pixels Per Unit 如果精灵具有此“Pixels Per Unit”设置,则精灵中的每个像素将覆盖 UI 中的一个单位。

在Constant Pixel Size模式下,用代码实现UI自适应

在这种模式下,不管屏幕大小如何变化,UI元素会保持原大小不变。但是我们可以通过Scale Factor去缩小放大这些UI元素,缩放是按照UI元素原比例进行缩放,所以要实现UI自适应关键是确定Scale Factor设为多大值。

可以看出,当屏幕尺寸发生变化时,UI元素无非是太宽,太长或者既太宽又太长而造成重叠。

通常屏幕尺寸变化要同时考虑宽、高两边的变化。但是我们只能设置一个缩放比例Scale Factor。因此要实现能用的UI自适应就要在这个系数上面做文章。

为了便于理解,先只考虑一侧的变化,这里拿宽度举例。

1.首先所有的UI元素的锚点要为“点模式”(可以将锚点放在四个角之一,这样UI元素距离四个角的距离不变),这样所有UI元素才能统一实现原比例显示。

2.在代码中将“运行时的屏幕宽度”除以“编辑时的屏幕宽度”,将Scale Factor的值设为该值,从而让所有UI元素缩放相应倍数。为了方便观察我把自适应代码放在了Update函数,实际上只需要放在Start函数中,运行一次即可。

void Start(){canvasScaler = GetComponent<CanvasScaler>();}// Update is called once per framevoid Update(){//获取运行时的屏幕分辨率screenWidth = UnityEngine.Screen.width;screenHeight = UnityEngine.Screen.height;//编辑时屏幕分辨率为650x400//将ScaleFactor设为  实际屏幕宽度/编辑时屏幕宽度canvasScaler.scaleFactor = screenWidth / 650;}

效果:当屏幕宽度随意变化,UI元素能随之按比例缩放。但当屏幕高度变化时,UI无变化,有可能会发生UI元素重叠的情况。
当同时考虑宽和高的变化时,可以有很多方案。这里记录三种:

方案一:按宽高权重大小决定最终缩放效果

方案逻辑:

分别计算出宽高的缩放比例,再根据权重来分配宽缩放比例、高缩放比例对最终效果的影响程度。

这个方案可以选择宽、高的缩放分别对最终结果的影响大小。

 void Update(){//获取运行时的屏幕分辨率screenWidth = UnityEngine.Screen.width;screenHeight = UnityEngine.Screen.height;        //总之,应当随下面两个浮点数的较小那个变化float w = screenWidth / 650;float h = screenHeight / 400;//编辑时屏幕分辨率为650x400canvasScaler.scaleFactor = propotion * h + (1 - propotion) * w;}

效果:当propotion为0时,只有宽度会影响UI缩放,高度不影响。当propotion为1时,只有高度会影响UI缩放,宽度不会。而propotion在0~1之间时,宽高按权重影响UI缩放。在某些分辨率下也会出现UI重叠的情况。
效果图

方案二 :按缩放比例较小的那一侧缩放:

方案逻辑:

1.如果高、宽两侧中有一侧缩小一侧放大,那么就取缩小那一侧的值

2.如果高、宽两侧都缩小,那么就取缩小程度较大的那一侧的值

3.如果高、宽两侧都放大,那么就取放大程度较小的那一侧的值

总之就取 实际屏幕高/编辑时屏幕高 实际屏幕宽/编辑时屏幕宽 较小的那个值

代码:为了更好观察才放在了Update函数中,实际上只需要放在Start函数中,运行一次即可。

 void Update(){//获取运行时的屏幕分辨率screenWidth = UnityEngine.Screen.width;screenHeight = UnityEngine.Screen.height;        //总之,应当随下面两个浮点数的较小那个变化float w = screenWidth / 650;float h = screenHeight / 400;//编辑时屏幕分辨率为650x400if (w < h)canvasScaler.scaleFactor = w;elsecanvasScaler.scaleFactor = h;}

效果:当屏幕宽度随意变化,UI元素能随之按比例缩放,UI不会发生重叠。但如果有背景UI,就会发现当屏幕大小发生变化时,如果宽高变化率不同就会相比原来多扩展(expand)出一部分空白(下图呈黑色)。

方案三:按缩小比例较大的那一侧缩放

方案逻辑:

1.如果高、宽两侧中有一侧缩小一侧放大,那么就取放大那一侧的值

2.如果高、宽两侧都缩小,那么就取缩小程度较小的那一侧的值

3.如果高、宽两侧都放大,那么就取放大程度较大的那一侧的值

总之就取 实际屏幕高/编辑时屏幕高 实际屏幕宽/编辑时屏幕宽 较大的那个值

代码:为了更好观察才放在了Update函数中,实际上只需要放在Start函数中,运行一次即可。

 void Update(){//获取运行时的屏幕分辨率screenWidth = UnityEngine.Screen.width;screenHeight = UnityEngine.Screen.height;        //总之,应当随下面两个浮点数的较小那个变化float w = screenWidth / 650;float h = screenHeight / 400;//编辑时屏幕分辨率为650x400if (w > h) //只需要把这里的<改成>canvasScaler.scaleFactor = w;elsecanvasScaler.scaleFactor = h;}

效果:在一定程度上能够自适应,但是会出现UI元素重叠的情况.如果有背景UI就可以发现,随屏幕变化背景UI会出现裁剪的情况。
效果图

三种方案的总结:

方案一:可以通过调整权重,来影响在不同分辨率屏幕的效果。最终可以通过不断调整数值选择一种在所有已知的分辨率里面平均效果不错的权重。

方案二:在所有分辨率里面UI均不会重叠,可以自动缩放。但是可能会在某些分辨率下的效果不好,比如缩得太小。

方案三:在宽、高变化程度差不多得情况下得效果和方案二差不多,但是有一点点视觉上得区别。不适合宽高比例变化程度差异很大得情况。

这三种方案并不需要手写代码,可以直接设置,怎么设置看下面。

第二种模式 Scale With Screen Size

属性 功能
Reference Resolution 参考分辨率/编辑时的分辨率/设计UI布局时的分辨率。最好在每次项目开始时就设置好。
Screen Match Mode 当实际分辨率与参考分辨率(Reference Resolution)不同时,缩放画布的模式。这个属性就是用来直接设置上面那三种方案的。
Match Width or Height 仅以宽度或高度或按二者的某种权重比值对画布进行缩放,这一项和上面的方案一类似,但是效果有些差异,估计是计算方法有异,权重具体看Match属性。
Expand 水平和垂直方向都会缩放,经过测试,此项效果和上面的方案二效果一模一样。
Shrink 经过测试,此项效果和上面的方案三效果一模一样。
偶然间发现自己上面手写的三个方案的代码功能竟然和这里一样,所以我有理由猜测这个模式是基于Constant Pixels Size模式写出来的,或者二者有同样的父类?
这三种模式的特点上面已经说过了,估计实际项目中要根据上线平台的屏幕分辨率多多尝试,看哪个效果更好就选哪个。
Match 当Match移到最左边时,仅宽度变化会影响画布缩放,当Match移到最右边时,仅高度会影响画布缩放。当Match移到中间某个点时,按二者的权重对画布进行缩放。
Reference Pixels Per Unit 如果精灵具有此“Pixels Per Unit”设置,则精灵中的每个像素将覆盖 UI 中的一个单位。

第三种模式:Constant Physical Size

这种模式看起来就感觉不常用,先不过多研究,等涉及到的时候再回过头来看看。

属性 功能
Physical Unit 用于指定位置和大小的物理单位。;centimeter 厘米;millimeter 毫米;inche 英寸;Point 点;pica 派卡
Fallback Screen DPI 在屏幕 DPI 未知时采用的 DPI。
Default Sprite DPI 用于精灵的每英寸像素,使其“Pixels Per Unit”设置与“Reference Pixels Per Unit”设置匹配。
Reference Pixels Per Unit 如果精灵具有此“Pixels Per Unit”设置,则其 DPI 将与“Default Sprite DPI”设置匹配。

【Unity学习笔记】Canvas Scaler组件相关推荐

  1. 【Unity 学习笔记】动画组件和动画控制器

    动画是一款游戏不可缺少的一部分.在Unity中,我们可以直接使用Unity自带的动画系统来制作我们想要的动画,其操作相当便捷. 帧动画是2D像素游戏的主流,我将以帧动画为例记录我最近学习动画系统的一些 ...

  2. unity番外学习笔记-canvas在3d里的设置以及3d物体之间的碰撞

    学习笔记 canvas在3d里的设置 3d物体之间的碰撞 canvas在不同系统中如何做到适配 canvas在3d里的设置 需要在canvas里找到worldspace,canvas才能匹配3d的大小 ...

  3. Unity学习笔记(4)-----粒子效果的实现

    Unity学习笔记(4)-–粒子效果的实现 一.效果展示 下面用若干张张动图展示效果: 大概就是这样,并不是很难. 实际效果要比图中的好一点(顺畅得多). 实现步骤 大致可以分为如下几个步骤,然后逐个 ...

  4. Unity学习笔记1 简易2D横版RPG游戏制作(一)

    这个教程是参考一个YouTube上面的教程做的,原作者的教程做得比较简单,我先参考着做一遍,毕竟我也只是个初学者,还没办法完全自制哈哈.不过我之前也看过一个2D平台游戏的系列教程了,以后会整合起来,做 ...

  5. 【Unity学习笔记】[Unity中文课堂教程] C#中级编程代码

    [Unity学习笔记][Unity中文课堂教程] C#中级编程代码 最近想补一补C#基础,Unity官方的C#中级编程教程质量很高,于是开个帖子把跟着敲+记录了部分价讲解和我自己的理解的代码存在这 原 ...

  6. Unity学习笔记:个人学习项目《疯狂天才埃德加》纠错文档

    Unity学习笔记:个人学习项目<疯狂天才埃德加>纠错文档 本文档是完成学校Unity课程作业时建立的纠错文档.用于记录自己开发过程中遇到的各种问题,以便下次遇到相同的问题时及时找到解决方 ...

  7. Unity学习笔记:Unity 3D 飞机大战

    Unity学习笔记:Unity 3D 飞机大战 1.打开unity软件后,首先新建Quad作为背景,导入飞机模型,并为其添加刚体 然后创建C#脚本,挂载到飞机上. 2.给飞机创建子弹,让子弹成为预制体 ...

  8. unity学习笔记-番外(3d模型的动作设计以及导入-2018版)材质的替换以及动作穿模(自己的手穿模到自己的其他部位)

    unity学习笔记-番外(3d模型的动作设计以及导入) 动作设计白嫖方法 方法一:小k网 需要注意的地方 方法二:mixamo 需要注意的地方 材质的替换 一 动作的穿模 2021.5.13更新 -2 ...

  9. unity学习笔记-有关透明材质的一些问题记录

    unity学习笔记- 问题一 实现镜面效果 问题一 事情是这样,根据老板的需求,需要给模型添加一个透明的金属材质感 但是这两个在小弟目前看来是不可能同时实现的 但是小弟还是试着去尝试了一下,发现在材质 ...

  10. 【Unity学习笔记】b站Unity架构课Unity3D 商业化的网络游戏架构(高级/主程级别)

    [Unity学习笔记]b站Unity架构课Unity3D 商业化的网络游戏架构(高级/主程级别) 自己跟着学完了,写了不少代码,会放在CSDN代码库,因为老师并没有提供源码,录屏也不是完全连续,所以难 ...

最新文章

  1. 【新无人机数据集】从 行人重识别 到 无人机目标定位
  2. 解决hash冲突的常用方法
  3. 指定一个开始日期和结束日期,算出中间的日期
  4. Mybatis like模糊查询的写法
  5. AliOS Things 硬件抽象层(HAL)对接系列2 — SPI driver porting
  6. Java基础知识强化26:Object类之hashCode()方法、getClass()方法
  7. linux top 命令各参数详解
  8. 计算机 考 二级结构工程师,下半年河北省结构工程师二级专业结构:计算机软件的组成及功能考试试题.doc...
  9. java项目打成jar包后,图片不显示等情况
  10. mysql里any是什么_sql中any和all的区别?
  11. ODL中版本变化引起包位置的变化
  12. 电脑html动态桌面壁纸制作,电脑如何制作动态壁纸_电脑上怎么搞动态壁纸-win7之家...
  13. nginx.pid-nginx: [error] open() /var/run/nginx.pid failed (2: No such file or direc
  14. XCTF-PWN pwn-200(使用DynELF利用write泄露system地址)
  15. C语言sprintf函数解析(实现数据类型转换到字符串)
  16. nodejs aes 加解密
  17. 月薪20KPython程序员2018年Python学习进阶书籍推荐
  18. vue3小兔鲜商城项目学习笔记+资料分享08
  19. COI实验室技能:MATLAB控制PCO相机
  20. AR模型(Autoregress)

热门文章

  1. 经典鸡兔同笼同类型问题
  2. DFS判断回路及回路个数
  3. P4234(最小差值生成树 lct维护生成树)
  4. CentOS8离线安装mono
  5. Maven实战 Item4 -- Maven核心概念
  6. 将m个相同的球全部放到n个相同的盒子里面有几种放法,盒子不能为空
  7. 通过css实现按钮高亮
  8. [备忘] 下载youtube表单的工具
  9. usb无线网卡安装在服务器上,外置无线网卡怎么安装_外置无线网卡怎么用-win7之家...
  10. 华为5G产品大配套,火星人光电互联大科普