Skip to content
UI表现与性能优化

UI表现与性能优化

阅读本文大概需要 10 分钟

本文提供了一些游戏界面开发中的建议,包括如何合理使用UI功能以提升UI表现效果,并减少性能消耗。

UI表现优化建议

TIP

美观精细的游戏界面通常是高品质游戏的重要一环,建议开发者增加对UI效果表现问题的关注,否则模糊/有锯齿的UI会影响玩家对于这款游戏的最初印象和基础体验。

UI图标避免大尺寸图缩小使用导致的锯齿现象

  • UI贴图一定是上传的资源尺寸越大越清晰吗?其实并非如此,因为上传前的UI贴图处理过锯齿,如果实际使用时过度缩小这张UI贴图,就会破坏原图的抗锯齿,导致图像边缘有强烈的锯齿感。

  • 出现这种情况时,需要重新上传尺寸合适的UI贴图资源, 图标及图标底板推荐上传与UI编辑器中使用大小最接近的二次幂尺寸(在64×64/128×128/256×256这三种尺寸类型中选择)

  • 目前编辑器提供了默认DPI缩放规则,以确保在各种分辨率的屏幕上,同一套UI的实际表现尺寸都比较合理,但这会导致同一张UI贴图在UI编辑器中使用大小与最终玩家设备上的使用大小不可能完全一致,除非玩家设备和UI编辑器的设计尺寸(默认1920×1080)完全相同,否则贴图或多或少的都会存在一定缩放。

  • 二次幂尺寸的意义在于编辑器中的二次幂尺寸UI贴图会自动开启Mipmap,能预先生成不同缩小倍率的图像缩略图(如下图),根据最终玩家设备上这张UI贴图的实际使用大小选择最接近的缩略图,使其UI贴图缩小使用时仍然能保持细节和清晰度,减轻锯齿感和摩尔纹。但是在某些情况下,Mipmap自动生成的缩略图可能会导致图像失真或者变形,尤其是较小倍率的缩略图,因此即使二次幂尺寸能开启Mipmap也不宜制作尺寸过大的图标。

    • 请注意图像未填满整个区域的UI贴图(尤其是圆形),其上下左右在处理抗锯齿之前不要完全贴边,否则处理抗锯齿之后贴边处的过渡区域无法保留在图片范围内,Mipmap自动生成的较小倍率缩略图会出现变形;推荐留出上下左右留出3个像素的空白
  • 下面举个例子,这组图标在UI编辑器中(设计尺寸1920×1080)的使用大小均为100×100,在低端玩家设备上(OPPOA57,分辨率1280×720)经过DPI缩放后的实际使用尺寸为67×67,实际表现如下图:

    • 无论是白色图标还是灰色底板,使用尺寸为300×300贴图资源时,边缘都会有强烈的锯齿感;
    • 使用尺寸为128×128贴图资源时,凭借Mipmap技术选用了64×64的缩略图,其边缘没有锯齿;而在分辨率较高的玩家设备上,会选用128×128的原图,清晰度也不会有问题。

避免使用尺寸过小的UI贴图,切忌上传前压缩原始图片

  • 不止大图小用会影响UI效果,如果原始贴图尺寸比实际使用大小小太多,比如下图中,64×64的贴图尺寸实际使用大小是118×114,与旁边正常尺寸UI对比明显模糊一些,这种情况需要制作128×128的贴图并重新上传。

  • 需要留意游戏中使用的UI贴图原资源本身是否模糊、细节处理是否有问题;以下图中的奖杯图标为例,同样是使用64×64尺寸,优化细节后效果会有一定提升空间。

  • 另外,不要为了节省内存而在上传之前压缩原始图片资源,因为按照编辑器cook流程, UI贴图最终在游戏中所占的内存大小只和UI贴图本身的尺寸有关 ,与其格式没有任何关系,编辑器在上传后的资源cook阶段会统一压缩贴图,因此上传前压缩原始图片只会导致贴图清晰度降低,不会对性能带来任何优化

上传前注意检查原图是否处理黑边,尽量避免使用小尺寸且内容复杂的UI贴图

  • 目前编辑器在上传后的资源cook阶段会将开发者上传的UI贴图自动压缩为ASTC等格式,这能节省贴图1/4~1/9的内存占用,在一些情况下,格式压缩会对UI贴图的清晰度有一定影响:
    • 用Figma等作图软件导出的原始图片需要在Photoshop中处理一下RGB溢出流程,否则会有黑边,例如下图中左侧处理过黑边,右侧没有处理过黑边;格式压缩有可能导致黑边被涂抹到图片边缘产生杂色,虽然大多数情况下区别并不明显,但如有发现这类情况可以尝试将原始图片进行RGB溢出流程并重新传图;
    • 尽量避免使用尺寸小且内容复杂的UI贴图,这类贴图经过格式压缩清晰度受影响会比较明显;
    • 非必要情况下,尽量避免让UI贴图的边缘带半透明阴影效果,否则有可能出现边缘杂色情况,原理与上文的黑边问题类似。

UI性能优化建议

TIP

对于UI界面较多的游戏,UI优化尤其是游戏内存瘦身的重中之重,当遇到性能瓶颈时可以检查下制作的UI时是否遵守以下优化原则。

留意UI贴图原始尺寸,大图小用会占用多余内存

  • 大图小用除了会导致前文提到的锯齿问题,还会造成资源浪费,例如下图中将一张1100×1032的UI背景图缩小到100×100进行使用,单就这张UI贴图就会占用高达1M内存,造成了上百倍的内存多余占用;因此, 务必注意使用与UI编辑器中实际大小最接近的二次幂尺寸, 图标及图标底板的尺寸要求为64×64/128×128/256×256这三种尺寸类型。
  • 单张UI贴图上传前尺寸最大不允许超过2048×2048,建议不要超过1280×720(低端机型的总屏幕分辨率,如OPPOA57),切记当贴图尺寸大于最终玩家设备上的使用大小时,不会有任何效果提升。

UI底板尽可能使用九宫格节省内存

  • 灵活使用图片绘制类型中的九宫格功能,可以将一张小尺寸的UI贴图不失真的放大到任何大小,节省内存空间,同时保持图片的清晰度和美观度。九宫格UI底板的资源尺寸要求小于等于256×256。
  • 如果有较多细节的UI底板无法使用九宫格,但是由重复花纹组成,建议把花纹拆分成四方连续贴图上传以节省内存。
  • 九宫格绘制类型演示 :使用方法请见 UI 控件-图片

合理使用拆分重用原则,能复用的图片尽量复用

  • 左图是一张整图,而这张整图可以使用右图进行旋转拼接成左图;由此可见,合理的拆分重用一张整图能节省内存。

结合以上两条原则,我们可以实现以下不同UI底板样式(类似的还有很多)。

3324x1378

1734x1370

1734x1370

1734x1370

而事实上,只需要用到下面两张图,并且合理利用拆分重用原则、九宫格绘制类型、再加上修改图片颜色就可以组合出上面所有图的样子,这将能节省上千倍的内存占用。

198x127

100x100

推荐使用Collapsed隐藏UI而不是Hidden

  • 在调整UI控件的可见性时,如果不需要考虑布局空间,推荐使用Collapsed来隐藏UI,因为Hidden在隐藏后依然占据布局空间(Layout Space),而Collpsed隐藏后不占用布局空间,因此在隐藏后不会进行Prepass的计算,性能优于 Hidden;合理选择更好的可见性模式可以有效优化性能,降低耗时。
ts
//UI节点显示规则
    enum SlateVisibility {
        /** 可见 */
        Visible = 0,
        /** 隐藏 并且不占用大小 */
        Collapsed = 1,
        /** 隐藏 占用计算大小 */
        Hidden = 2,
        /** 可见 自身以及子节点不可响应事件 */
        HitTestInvisible = 3,
        /** 可见 自身不可响应事件 */
        SelfHitTestInvisible = 4
    }
//UI节点显示规则
    enum SlateVisibility {
        /** 可见 */
        Visible = 0,
        /** 隐藏 并且不占用大小 */
        Collapsed = 1,
        /** 隐藏 占用计算大小 */
        Hidden = 2,
        /** 可见 自身以及子节点不可响应事件 */
        HitTestInvisible = 3,
        /** 可见 自身不可响应事件 */
        SelfHitTestInvisible = 4
    }

示例:

ts
const btn = this.uiWidgetBase.findChildByPath('Canvas/Button_Jump') as Button
//隐藏 并且在布局中不占用大小,节省性能
btn.visibility= SlateVisibility.Collapsed
//隐藏 并且在布局中占用大小
btn.visibility= SlateVisibility.Hidden
const btn = this.uiWidgetBase.findChildByPath('Canvas/Button_Jump') as Button
//隐藏 并且在布局中不占用大小,节省性能
btn.visibility= SlateVisibility.Collapsed
//隐藏 并且在布局中占用大小
btn.visibility= SlateVisibility.Hidden