UGUI(二)- Canvas Scaler

25 篇文章 1 订阅
14 篇文章 0 订阅
本章节只讲 Canvas Scaler 组件,关于 UI 的屏幕适配在学完 UGUI 基础组件之后会单独写一章节,文章略长

什么是 Canvas Scaler

Canvas Scaler 这个组件用来做整体 UI 屏幕适配的。为什么是整体适配?因为适配时还会用到 RectTransform 中的 Anchor 属性。Canvas Scaler 同样挂在 Canvas Gameobject 下。
image

Canvas Scaler 的缩放模式

缩放模式与 Canvas 的渲染模式相关:当 Canvans 渲染模式为 Screen Space - OverlayScreen Space - Camera 时,缩放模式有三种;当 Canvans 渲染模式为 World Space 时,缩放模式只有一种

三种缩放模式:

image

模式简要说明
Constant Pixel Size恒定(逻辑)像素大小
ConstantPhysical Size依据屏幕大小等比缩放
Scale With Screen Size恒定物理尺寸
  • 任何模式都不会改变 Canvas 设计宽高比和 UI 元素的相对位置
  • 上述中的相对定位有个前提是 UI 元素没有使用 Achor,这条会在 RectTransform 章节详细讲述
  • 第 1、3 种模式游戏开发中很少用,主要用第 2 种模式进行 UI 适配。以下内容注意讲解顺序
  • 属性 Reference Pixels Per Unit 的说明在文未

Constant Pixel Size

不根据屏幕分辨率调整 Canvas 的缩放, 以 UI 元素的像素值 * Scale Factor 对应真实屏幕的像素点进行渲染。当 Scale Factor 为 1 时,屏幕上显示为 UI 元素的给定像素大小。

Scale Factor 画布的缩放比例。默认况下为 1,表示正常大小。

Reference Pixels Per Unit 每个 UI 单位代表的像素量。
官方的解释是 “如果 sprite(精灵,下同) 具有 Pixels Per Unit 设置,则 sprite 中的一个像素将覆盖 UI 中的一个单位”,个人理解这个值是用来覆盖 sprite 导入设置中的 Pixels Per Unit 值,即决定每个 UI 单位应包含多少像素。

验证:

1.Canvas 下 创建 Image 并赋值一张图片,图片导入设置中 Pixels Per Unit 默认为 100, 当 Canvas Scaler 中 Reference Pixels Per Unit 值为 100 时,点击 Image 组件中的 Set Native Size 按钮,记录此时屏幕上的图片大小 2.更改 Canvas Scaler 中 Reference Pixels Per Unit 值为 200,再次点击 Image 组件中的 Set Native Size 按钮,会发现图片比原来大了一倍。

图一:sprite 导入设置中的 Pixels Per Unit 为 100
image

图二:切换分辨率时,同一 sprite 在 Constant Pixel Size 模式下的表现
image

ConstantPhysical Size

此缩放模式比较难理解,不常用

Constant Pixel Size 模式本质相同, Constant Pixel Size 通过逻辑像素大小调节来维持缩放,Constant Physical Size 通过物理大小调节来维持缩放。使用这种模式必须指定一个像素转换物理大小的因数,运行时通过具体设备的 DPI 计算最终的 Canvas 像素大小和缩放比例。

Physical Unit 用于指定 UI 位置和大小 的物理单位

属性描述计算中的 targetDPI
Centimeters厘米2.54
Millimeters毫米25.4
Inches英寸,约 25.4 毫米1
Points点,1/72 英寸,1/12 派卡72
Picas派卡,1/6 英寸6

Fallback Screen DPI 如果未获取到屏幕的 DPI,将使用此值参与计算缩放

Default Sprite DPI 与 Reference Pixels Per Unit 共同计算 每 UI 单位 像素数

Reference Pixels Per Unit 与 Default Sprite DPI 共同计算 每 UI 单位 像素数,计算公式在下面源码最后一行。

贴出源码

///<summary>
///Handles canvas scaling for a constant physical size.
///</summary>
protected virtual void HandleConstantPhysicalSize()
{
    float dpi = (currentDpi == 0 ? m_FallbackScreenDPI : currentDpi);
    float targetDPI = 1;
    switch (m_PhysicalUnit)
    {
        case Unit.Centimeters: targetDPI = 2.54f; break;
        case Unit.Millimeters: targetDPI = 25.4f; break;
        case Unit.Inches:      targetDPI =     1; break;
        case Unit.Points:      targetDPI =    72; break;
        case Unit.Picas:       targetDPI =     6; break;
    }

    SetScaleFactor(dpi / targetDPI);
    //设置Canvas中每个单位有多少像素
    SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit * targetDPI / m_DefaultSpriteDPI);
}

DPI = Dots Per Inch Dots 是屏幕物理点,以对角线计算
PPI = Pixel Per Inch Pixel 是像素,以对角线计算
好屏幕一个像素需要多个物理点来显示,于是又有了 DPPX
DPPX = Dots per Pixel
好屏幕 DPPX 都大于 1
image

接下来最重要的缩放模式来了,这种模式也是目前大多数游戏中进行 UI 适配模式所采用的模式

Scale With Screen Size

image

根据真实屏幕的宽高来缩放 Canvas

image

  • Match Width or Height 根据真实屏幕的宽高比按指定的 Match 值来缩放 Canvas。

    Reference Resolution UI 的设计尺寸,这个值需要自已定,也是美术做图的依据,一般为 1920 * 1080(16:9,当然现在的刘海屏手机屏大部分是 18:9 或更宽,后面 UI 适配章节详细讲)

    Match 决定 Canvas 按宽高缩放的权重值,当 Match = 0 时,按宽度进行 Canvas 等比缩放;当 Match 值 = 1 时,按高度度进行 Canvas 等比缩放。一般情况下这个值非 0 即 1,不用纠结中间值。

    case ScreenMatchMode.MatchWidthOrHeight:
    {
        // We take the log of the relative width and height before taking the average.
        // Then we transform it back in the original space.
        // the reason to transform in and out of logarithmic space is to have better behavior.
        // If one axis has twice resolution and the other has half, it should even out if widthOrHeight value is at 0.5.
        // In normal space the average would be (0.5 + 2) / 2 = 1.25
        // In logarithmic space the average is (-1 + 1) / 2 = 0
        float logWidth = Mathf.Log(screenSize.x / m_ReferenceResolution.x, kLogBase);
        float logHeight = Mathf.Log(screenSize.y / m_ReferenceResolution.y, kLogBase);
        float logWeightedAverage = Mathf.Lerp(logWidth, logHeight, m_MatchWidthOrHeight);
        scaleFactor = Mathf.Pow(kLogBase, logWeightedAverage);
        break;
    }
    

    image

上图中 UI 设计尺寸为 1920 _ 1080,为了方便观察,图片(Image)的大小设为 1920 _ 1080,此时图片的边界即可看作 Canvas 的边界。线框为 摄像机边界 = Game 视图中指定分辨率(800 * 600)

  • Expand 在屏幕大小上 “内接” 画布。以 Canvas 小于 屏幕 为例,放大画布直至宽或高有一边与屏幕重合停止。此模式下为 Canvas 全部显示在屏幕中 的前提下 Canvas 的最大缩放值

image

  • Shrink 在屏幕大小上 “外切” 画布。以 Canvas 小于 屏幕 为例,放大画布直至宽或高最后一边与屏幕重合停止。此模式下为 Canvas 被裁切,不能完全显示在屏幕中

image

  • 三种 Screen Match Mode 中,用的最多的是 Match Width or Height
  • 再次强调,任何缩放模式都不会改变 Canvas 固有设计宽高比

特殊情况缩放

当 Canvans 渲染模式为 World Space 时,缩放模式只有一种

image

Dynamic Pixels Per Unit Canvas 缩放值取决于此值的设定值

Reference Pixels Per Unit 官方说 “如果此值设置为 1,那么 sprite 中的‘Pixels Per Unit’设置将按原样使用,即每个世界单位 100 像素”,而我在实际运用中并不是这样,而是比 100 时缩小了很多,因此判定这里 Reference Pixels Per Unit 属性的意义和上文中提到的一致


欢迎关注公众号,定期分享Unity的实用技巧~~
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值