【Unity制作】Canvas 与 不同屏幕分辨率 的各种【坑】

  • 前言
  • Canvas线
  • Panel 嵌套显示不正确
  • 画布内UI元素布局不正确
  • 不同系统的适配应对方案
  • 方案一:修改 `Canvas -> Render mode` 选择 `Screen Space - Camera / World Space`
  • 方案二:调整缩放比 `Scaler Factor`
  • 方案三:调整 `UI Scale Mode -> Scale With Screen Size`
  • 补充一嘴


前言

  • 众所周知,Canvas 用于显示UI元素
    拿着对我在课上的浅薄知识来做项目,结果发现了一堆坑…
    这里记录一下我遇到的许多问题,以及他们的原因、解决方法
    由于自己是一个小白,所以仍然可能有许多内容不完全正确,术语不专业,恳请大家斧正!

Canvas线

  • 我们先创建一个新场景,当然有 Camera ,这个我姑且叫做 Camera 线,能实时告诉我们游戏的摄像机镜头我们能看到什么
  • 我们新建一个 Canvas ,这个就多出来一了一个线,我姑且叫做 Canvas 线 注意默认的 Canvas 的区域非常大,并不在 Camera 线
  • 根据实践,发现这根线会变动!这是怎么回事呢?
    然后我们发现(我刚刚才发现),这根线其实就是对于这个 Screen Space - Over lay 的 Canvas,我们游戏窗口摄像机内显示的区域。由于默认游戏窗口设置成 Free Aspect,窗口是可拖拽的,所以会导致 unity 修改设计分辨率 unity发布分辨率_unity 修改设计分辨率
  • 如下图,我们选择一个固定的分辨率后,发现 Canvas 线 也就变成了对应的形状,当然仍然不是在 Camera 线 内的

Panel 嵌套显示不正确

  • 我在Scene 界面做成这样

    这个是 Canvas 的设置:

    然后发现小窗体运行正确:

    但是最大播放运行错误:
  • 原因:使用了 Stretch它指定UI元素距离父对象的上下左右的像素距离

    显然,分辨率不同,虽然物体距离父对象的上下左右的像素距离相同,但是仍然会导致物体的大小出现偏差。
  • 解决方法:改成其他的模式,这个应该叫 锚点表示吧,选择红色的
    这样,物体就由 PosX,PosY,还有宽度和高度决定了!
  • 看一下改动后的效果:
  • 嗯,确实物体的相对大小正确了!但是这个布局怎么变了呀?
    这个错误我们见下面:

画布内UI元素布局不正确

  • 我们先使用 Free Aspect,我们在画布的这个位置放一个 Button
  • unity 修改设计分辨率 unity发布分辨率_unity_02

  • 在小屏幕的游戏窗口,显示正确
  • unity 修改设计分辨率 unity发布分辨率_UI_03

  • 但是勾选了 Maximize On Play 最大化播放后,按钮的位置变动了!
  • unity 修改设计分辨率 unity发布分辨率_3d_04

  • unity 修改设计分辨率 unity发布分辨率_unity 修改设计分辨率_05
    可以看到这个按钮的位置摆放在画布外面了
  • unity 修改设计分辨率 unity发布分辨率_游戏引擎_06

  • 但是全屏的时候仍然显示在里面
  • unity 修改设计分辨率 unity发布分辨率_游戏引擎_07

  • 那么解决方案呢?

不同系统的适配应对方案

  • 电脑如果是窗口端的话,会要求设置分辨率;全屏是默认本地分辨率
    (这里在 File->Build Settings -> Player Settings 下面设置)


    而手机端则只有默认全屏模式
  • 对于适配的调整,显然对于PC端,我们可以固定分辨率。
    但是对于PC端的全屏,或者手机端的全屏怎么办呢?
    我们仔细观察 Canvas 物体下的控件,主要的精力放在 CanvasCanvas Scaler 身上

方案一:修改 Canvas -> Render mode 选择 Screen Space - Camera / World Space

  • 优点:这就意味着,我们的画布是和摄像机相关的,可以把画布线与摄像机线对齐并进行修改
  • 缺点:使用不恰当会导致:所有的 UI 控件都需要额外缩放精修,操作繁琐,引发连环bug
    我们来看一下。
    我们先选择Screen Space - Camera ,给定摄像机为 Main Camera,发现画布线与摄像机线对齐了
    我们再选择World Space 。我们显然发现,画布被缩放了
  • 有人可能觉得,画布被缩放了有什么不好的吗?
    我们对画布下的 Button 做一个预设体,直接拖到 Assets Window 下面

    然后我们发现了,UI物体的预设体是有 Canvas环境的!
    不同 Canvas 环境的预设体如果不相同,你会得到一堆乱糟糟的、改都改不完的布局
  • 然后我惊讶的发现,通过调整 Canvas Render Mode -> World Space每个画布的缩放比都不同
    导致做出来的 UI 预设体乱七八糟,还以为是不同系统显示的问题
    结果是画布缩放比不同导致失配了

方案二:调整缩放比 Scaler Factor

  • 我们保持渲染模式为 Screen Space - Overlay 选择修改缩放比 Scaler Factor = 2 这个时候,我们发现确实画布下的UI都放大了,但是由于画布线和屏幕分辨率有关,UI物体还是出现在 Scene 的外面,但是出现在 Game Scene 的里面
  • unity 修改设计分辨率 unity发布分辨率_unity 修改设计分辨率_08

    unity 修改设计分辨率 unity发布分辨率_UI_09


  • 这个类似于上面的修改 Canvas Render Mode -> World Space 然后暴力修改子UI物体的缩放来达到 脆弱的平衡 一样,非常不适合我之前说的 PC全屏、手游分辨率的情况。

方案三:调整 UI Scale Mode -> Scale With Screen Size

  • 这个就是我发现的解决问题的完美办法
    既然之前的设置是让摄像机与显示屏缩放适配,我们当然也可以UI画布和显示屏缩放适配呀!
    (尽管这需要我们调整,系统默认的 UI Scale ModeConstant Pixel Size
  • 我们发现,下面的子参数:参考分辨率,屏幕适配方案
    参考分辨率非常好理解,根据某个参考分辨率进行适配方案的缩放。
    我们看一下屏幕适配方案
  • 我们这里没有什么贴图,单纯一个按钮,我们先选择 Expand 模式
    我们再来看一下各个场景的按钮位置是否一致:

  • 完美一致!
    当然,如果我们有一些贴图,如果强烈缩放之后会很丑,我们可以选择其他的适配模式
    比如选择 Match Width Or Height ,就会好的很多

补充一嘴

  • 如果选择了 Match Width Or Height ,比如选择参考分辨率为 1920 * 1080 的手机横屏
    你可能会发现画布的缩放会变动、不一致:

    之前说过了,画布环境不一致,会出现很多问题。
  • 我们应该固定 Game Scene 的显示分辨率,改成我们的参考分辨率

    这时画布的缩放比自动变为 1,1,1 ,适配成功!