公式化配置Canvas和panel,仅需公式化的三步让你的UI任何分辨率下都基本适配
大家好,今天给大家讲讲UI上的东西,随着市面上手机不同种类普及,游戏的UI层就需要各种各样的分辨率,当然在面对这种情况下,大家会遇到一个情况我们会在Canvas设置一个基础的图片他需要往左往上一点,本来调整正确但是,一旦切换不同的分辨率,要么这个图片这个延展到上天变成宽体普京要么跑到界外掉出了这个世界,比如我们拿这个分辨率的canvas的画布举例画图,如图这是一个1920*1080的图片
很明显这是非常基础的依托UI他在屏幕上占了三分之一x轴,6分之一y轴,我们在切换其他的分辨率看看他怎么样呢?
在切换成800*480低分辨率他居然被拉伸成这样了。这是他被拉伸了吗?不是,他仍然是这个东西,我们再看看高分辨率这是最高分辨率2960*1440
很明显他变小了
那这是为什么🧐?
很明显这跟画布的特性有关系大家看canvas的灰色属性
在不同分辨率下Canvas的width和height也就是高度宽度大小处于变化之中
这代表着原本你的图片即时完全不变但是因为你默认的设置canvas模式!
Canvas Scaler 组件:决定UI的缩放策略,即UI如何适应不同的屏幕分辨率。它的
UI Scale Mode有三种:Constant Pixel Size、Scale With Screen Size和Constant Physical Size。
这里遇到的问题,关键在于Canvas Scaler组件的设置,而不是Canvas的渲染模式。
⚙️ 两种缩放模式详解
Canvas Scaler组件的两种核心模式,决定了UI元素如何响应分辨率变化。
| 特性 | Constant Pixel Size (恒定像素大小)默认 | Scale With Screen Size (随屏幕大小缩放) |
|---|---|---|
| 核心逻辑 | UI元素保持固定的像素尺寸。 | UI元素根据参考分辨率进行等比缩放。 |
| 分辨率变化时的行为 | 元素的像素大小不变。分辨率变高时,元素在视觉上会变小;分辨率变低时,元素会变大。 | 元素大小会随分辨率等比变化,以适配屏幕。分辨率变高,元素也变大;分辨率变低,元素变小。 |
| 应用场景 | 像素级精确的UI,或你不希望UI大小随屏幕变化的场景。 | 绝大多数情况下的首选,用于实现UI自适应,保证在不同设备上都有良好的视觉效果。 |
🧐 为什么图片子物体的变化不同?
调整分辨率后图片子物体没变化”和“有变化”的现象,正是由上述两种缩放模式的特性差异导致的。
图片子物体最终在屏幕上的显示大小,等于其“Rect Transform中设置的尺寸”乘以“Canvas的缩放系数”。
在“Constant Pixel Size”模式下,图片子物体“没变化”
因为在这种模式下,Canvas的缩放系数恒为1(或你设定的Scale Factor值)。
所以,不论你怎么调整屏幕分辨率,图片的“Rect Transform尺寸”乘以“1”,结果始终不变。它在屏幕上占据的像素数量是固定的。
在“Scale With Screen Size”模式下,图片子物体“会变化”
因为这种模式会动态计算一个缩放系数,来让Canvas适配当前屏幕。
这个系数 = 当前屏幕分辨率 / 你设定的参考分辨率 (Reference Resolution)。
所以,当你调整分辨率时,图片的“Rect Transform尺寸”会乘以这个动态的缩放系数,最终显示大小自然就跟着变化了。
💎 总结
Constant Pixel Size:UI元素大小固定,像素不变,适合对像素精度要求高的场景。Scale With Screen Size:UI元素大小自适应,随屏幕等比缩放,是大多数UI适配需求的首选。
所以很明显只要我们设置默认情况下我们的子物体image缩放始终唯一,不会变化而画布可是会因为分辨率变化而变化,图片可以当一个人,如果低分辨率参考系可以当成一个蚂蚁看人,高分辨率可以当成太阳,这两个极端对比一个对于蚂蚁来讲人很高就延展很大,就是低分辨率反之,人在太阳面前就是小灯。
那我们怎么解决这个问题呢,
我给出一个公式化的玩法,后面再说为什么这样可以适配大多数情况
UI结构-》Canvas配置如下
配置为1980-1080,screensize,match0.5,在调整后再去调整模型,注意下面这个pixel跟随你的image导入的pixel一致,一般导入sprite 2d都是100,如果修改,pixel也可能导致缩放误差不改一般没事
然后我们在Canvas子物体挂载一个空背景panel将所有的物体image放置到他下方如图层级结构设置为延展Stretch并设置为全部延展也就是右下角
然后我们子物体就可以全部使用非延展任意位置了,除了背景图不受延展影响的,其他可以视UI排布而定如果你是偏中间那就居中红色偏右上就放右上。
在工业化制作流程可以批量处理,设置一个canvas作为根节点,其他的panel画布放置到文件夹作为预制体以后利用AB包调用panel生成统一生成到对应的canvas子物体上作为即时UI
好的我们看看这样的排版原理是什么呢?
首先1920*1080是市面上最普及的分辨率我们在设置这个screensize我们的rect 就会跟着这样的缩放比例变化而变化,至于这个比例0.5是照顾了高度和宽度不完全侧重任何一个都兼顾,然后我们在子物体设置一个panel空背景为延展选项让所有image挂载在这里是因为这个作为这个UI的相对边界,子物体就根据这个panel位置变化相对位置,更好调控相对位置而不会单纯收到canvas影响,image设置非延展是为了尽可能减少延展带来的过度变化,设置红色位置尽可能在变化比例后保持在当前位置,保证观感,最后给大家看看这样写法下图片是否在改变比例后跟之前变化减小了呢?
🧮 原理一:黄金分割点“Match = 0.5”
Match = 0:完全以宽度为基准缩放。竖屏游戏常用,但横屏时UI会变得巨大。
Match = 1:完全以高度为基准缩放。横屏游戏常用,但竖屏时UI会挤扁。
Match = 0.5:取宽度缩放和高度缩放的中间值(实际是加权平均)。
这意味着,当屏幕比例在4:3(iPad)、16:9(常规显示器)和21:9(带鱼屏/全面屏手机)之间变化时,UI的缩放系数既不会因为宽度突变而崩溃,也不会因为高度突变而变形。它找到了一条“中庸”的缩放曲线,让UI在大多数设备上看起来大小都相对适中,不会出现极端放大或缩小的不适感。
📐 原理二:拉满全屏的“背景Panel”
背景Panel设置为Stretch(四角拉伸),这个操作至关重要。
它充当了一个“绝对边界”。无论屏幕怎么变,这个Panel的四个角永远紧贴屏幕边缘。
所有子物体(Image)都挂在这个Panel下,相当于在一个固定的逻辑坐标系(参考分辨率1920x1080)里进行排版。
由于Canvas Scaler的存在,这个Panel和里面的所有子物体,会整体等比缩放到不同屏幕上。背景Panel负责撑满,里面的UI元素则跟着“地板(Panel)”一起等比放大缩小。这是2560的最大
这是800最小很明显这两个没有之前那样奇葩了
🎯 原理三:固定锚点 + 非延展的“安全排版”
你的做法是子物体用“非延展任意位置”,这是最稳健的做法。
因为延展(Stretch)会强制改变RectTransform的宽度和高度,当缩放系数变化时,延展元素的位置和大小会同时被拉伸,极易导致边缘元素超出屏幕或挤压变形。
而你改用固定锚点(比如偏中间就锚定中心,偏右上就锚定右上角),只控制元素的位置(PosX, PosY)和大小(Width, Height)。在1920x1080的虚拟画布上,这些数值是绝对固定的。缩放时,整个画布等比例缩放,元素之间的相对位置和大小比例永远不会乱。
📏 原理四:Pixels Per Unit = 100 的“标尺统一”
提醒保持PPU为100,是为了保证逻辑像素和Unity单位的换算一致。
Unity的UI坐标系以“像素”为单位,但Sprite的PPU决定了“1个单位长度对应多少像素”。
保持默认100,意味着你在做UI时,RectTransform的尺寸数值可以直接对标图片的原始像素尺寸(比如一张200x200的图,你设宽高为200,显示出来就是正好的)。这杜绝了因PPU不一致导致的显示比例误差,让设计图能1:1还原到引擎里。
🏗️ 原理五:预制体 + AB包的工业化流程
你把Canvas作为根节点,其他Panel做成预制体动态生成,这完全符合模块化开发思想。
原理在于,缩放计算的逻辑完全由根Canvas的Canvas Scaler决定。
动态生成的Panel作为子物体,会自动继承根Canvas的缩放系数。因此,你的预制体只需关心在1920x1080参考分辨率下的位置和大小,无需编写任何额外的自适应代码。这套机制保证了无论生成多少个UI面板,它们的缩放逻辑都是绝对统一的。
💎 总结:为什么它能适配大多数情况?
这套方案本质上是“牺牲了极少数极端屏幕的完美匹配,换来了绝大多数屏幕的稳定可用”。
它不去追求UI边缘刚好贴边(因为贴边会导致拉伸),而是构建了一个虚拟的“安全区”(1920x1080画布),让所有UI元素在这个安全区里绝对定位。再通过Match=0.5的折中缩放,让这个安全区在各类屏幕上都能完整显示,且元素大小适中。对于背景图,用拉伸填满;对于核心功能按钮,用固定锚点固定在安全区的角落。
只要游戏不是要求UI必须精确贴边的“全屏铺满型”设计,这套方案就是最省心、最普适的工业化解决方案。
