Unity | Canvas 组件详解:渲染模式、屏幕适配

153 阅读5分钟

画布(canvas)是 UI 组件的容器,所有 UI 元素都必须放置在画布中。这就好比是电影幕布,所有的影像都在幕布上呈现。

画布的存在,让我们可以将一些通用的 UI 配置放到画布上来配置,比如:

  • 画布与游戏中其他物体是什么样的关系?(渲染模式
  • 对于不同分辨率的屏幕,画布如何进行适配?(画布缩放器 Canvas Scaler)

对于这些问题,画布及其关联组件都提供了多种配置项来适配不同的需求。


渲染模式

渲染模式是什么? 每种渲染模式的定义是什么? 每种渲染模式适用的场景是什么?为什么?有哪些典型案例?

渲染模式定义了画布与场景中其他物体在渲染上的关系。渲染模式关注两个核心问题:

1. 是在屏幕空间渲染还是在全局空间渲染?

用现实中的场景来举例,屏幕空间就像 google 眼镜中的界面,不管你在现实生活里怎么走动,眼镜界面都会在你眼前呈现;而全局空间,则是商场里的大屏广告,随着你的走动,屏幕位置不变,但是在你眼中呈现的效果不断变化。

2. 是覆盖在其他游戏对象之上,还是根据摄像机视野进行渲染?

覆盖模式下,我们不需要关心有无摄像机,这个画布总是会在屏幕最顶层出现;摄像机模式下,可以理解为画布固定在了摄像机的某个方位上,摄像机移动时,与摄像机相对位置保持不变。

在屏幕空间渲染,且覆盖在其他游戏对象之上,则是 Screen Space - Overlay 模式 在屏幕空间渲染,且根据摄像机视野进行渲染,则是 Screen Space - Camera 模式 在全局空间渲染,(一定是根据摄像机视野进行渲染的)是 World Space 模式 渲染模式的配置在 Canvas 组件的 Render Mode 选项中:

图1-canvas 渲染模式配置

下面我们来看一些更具体的案例以区分三种渲染模式: 以《塞尔达传说:旷野之息》举例,展示血量、温度、噪音、天气、英杰技能等的 HUD,适合使用「屏幕空间 - 覆盖模式」。

图2-塞尔达传说:旷野之息 HUD

背包界面中,游戏对象在背景前方,又在食物详细信息面板后方,这部分画布则适合使用「屏幕空间 - 摄像机」模式。猜测可能需要两层画布,一层作为背景,在游戏人物后方,一层作为信息面板,在游戏人物前方。

图3-塞尔达传说:旷野之息 背包界面

《激战2》中,可以看到鹰的上方有个黑色的屏幕,屏幕上有一些文字。这种场景则适合使用「世界模式」。

图4-激战2 冒险盒子


画布缩放器

当画布在屏幕空间中渲染时,画布尺寸一定能正好适配屏幕尺寸吗?当二者不一致时,该怎么进行缩放?

画布缩放器(Canvas Scaler 组件),提供了三种缩放模式来适配不同的需求:

  1. Constant Pixel Size:在此模式下,UI 元素的大小将不受 Canvas 的缩放影响,而是保持固定的像素大小。这种模式适用于需要确保 UI 元素在不同设备上的大小保持一致的情况。

  2. Scale With Screen Size:在此模式下,UI 元素的大小将根据 Canvas 的缩放比例进行缩放,以适应不同分辨率的设备。这种模式适用于需要在不同分辨率的设备上呈现一致的 UI 布局和视觉效果的情况。

  3. Constant Physical Size:在此模式下,UI 元素的大小将根据屏幕的物理大小进行缩放,以确保 UI 元素在不同设备上具有相同的物理大小。这种模式适用于需要确保 UI 元素在不同设备上具有相同的物理大小的情况,例如在使用触摸屏幕的设备上。

  • 为什么有 Constant Pixel Size ,还需要 Constant Physical Size ?

因为不同设备上的 1 像素,实际大小是不同的,实际大小是由设备像素比(DPR)和每英寸像素(PPI)共同决定的。

  • Scale With Screen Size 的计算公式研究

Scale Witdh Screen Size 主要用于:宽高比的适配。设想一下,原始 UI 与屏幕的宽高比一致,那么很简单,无需适配,就是原始 UI 缩放即可。但是,如果宽高比不一致呢?该放大或缩小多少倍? 这就是 Scale With Screen Size 想解决的问题。 场景假设: 原始屏幕 100* 100 横屏 200100 竖屏 100200

权重weight /屏幕分辨率原始屏幕 500*500横屏 1000*500竖屏 500*1000
Match: 0[见图5]横向:widthRatio = 1000 / 500 = 2纵向:heightRatio = 500 / 500 = 1加权平均widthRatio * (1-weight) + heightRatio * weight = 2所以最终缩放是 2。[见图6]横向:witdhRatio = 500 / 500纵向:heightRatio = 1000 / 500widthRatio * ( 1 - weight) + heightRatio * weight = 1 [见图7]
Match: 0.5.........
Match: 1.........

图5-1000*500屏幕,match参数为0

图6-500*500屏幕,match参数为0,结果:按钮放大 2 倍

图7-500*1000屏幕,match参数为0,结果:按钮大小不变

计算公式:水平与垂直缩放因子之间的平均值是基于 matchWidthOrHeight 值的加权平均值。