78.禁用画布及避免使用Animator

78.性能优化-GPU-UI系统优化-禁用画布及避免使用Animator


78.1 知识点

禁用 Canvas(画布)带来的优化

在 UGUI 中,有以下几种方式可以隐藏 UI 元素:

  1. 通过 SetActive 设置 UI 元素所依附对象的激活/失活状态:会触发 Canvas 重建,恢复时也要重建,开销较大。
  2. 通过失活 UI 元素的图形组件:该元素不渲染,但仍会导致所在 Canvas 重建。
  3. 通过 CanvasGroup 组件的整体透明度改为 0
  4. 通过组件颜色属性将透明度改为 0
    方式 3 和 4 仍然会生成网格、送入渲染流程,GPU 依然在画,只是全透明。
  5. 通过将 Canvas(画布)组件失活:只禁用该 Canvas 的渲染器,整个 Canvas 下的 UI 元素不参与渲染和事件检测。

综合以上方案,若要隐藏某些 UI 控件,可以通过失活其所属 Canvas(画布)来实现,好处是可以直接跳过渲染和事件检测,避免无意义的重建和渲染。

注意:通过禁用 Canvas 的方式隐藏 UI 元素的前提是做好动静分离、多 Canvas 合理分配,否则禁用一个 Canvas 可能会让很多不相关的 UI 一起消失。

避免使用 Animator 带来的优化

若在 UI 中使用 Animator 组件播放 UI 动画,Animator 会在每帧根据动画状态机计算 Transform 或其他属性变化,例如位置、旋转、缩放,以及颜色、图片变换等。

结合前文可知,若某个 Canvas 下的 UI 元素发生变换,会产生画布污染,进而导致 Canvas 重建。也就是说,Animator 动画组件会给 UGUI 带来更多性能开销;且 Animator 本质是状态机驱动,每帧都会运行状态逻辑,开销较大。

若 UI 界面确实需要动态效果,可以采用以下方案:

  1. 使用 DoTween 等插件做缓动效果
  2. 自己实现动态效果:例如用协程或 Lerp 做插值动画,控制更新频率和时机,避免每帧无意义更新。
  3. 用 Shader 实现动态效果:把计算交给 GPU,例如进度条流光、动态血条、按钮高亮等。
  4. 动静分离:将动态效果单独放在一个 Canvas 下,减少重建范围。

78.2 知识点代码

Lesson78_性能优化_GPU_UI系统优化_禁用画布及避免使用Animator.cs

public class Lesson78_性能优化_GPU_UI系统优化_禁用画布及避免使用Animator
{
    #region 知识点一 禁用Canvas(画布)带来的优化

    //在UGUI中,有以下几种方式可以隐藏UI元素
    //1.通过SetActive方法 设置UI元素依附对象的激活失活状态
    //  会触发 Canvas 重建,恢复时也要重建,开销较大
    //2.通过失活UI元素的 图形组件
    //  该元素不渲染,但仍会导致所在 Canvas 重建
    //3.通过CanvasGroup组件的整体改变透明度为0
    //4.通过组件颜色属性改变透明度为0
    //  3和4仍然会生成网格、送入渲染流程;
    //  GPU 依然在画,只是全透明
    //5.通过将Canvas(画布)组件失活
    //  只禁用这个 Canvas 的渲染器
    //  整个 Canvas 下 UI元素 不参与渲染和事件检测

    //从以上方案来考虑
    //如果想要隐藏某些UI控件时,可以通过失活其所属Canvas(画布)达到目的
    //并且好处是可以直接跳过渲染和事件检测,避免无意义的重建和渲染!

    //注意:
    //通过禁用Canvas(画布)的方式去隐藏UI元素的前提
    //是 动静分离、多 Canvas 合理分配
    //否则禁用一个 Canvas 可能会让很多不相关 UI 一起消失

    #endregion

    #region 知识点二 避免使用Animator带来的优化

    //如果在UI中使用Animator组件来播放一些UI动画
    //Animator 会在每帧根据动画状态机计算 Transform或其他属性变化
    //比如:
    //1.位置、旋转、缩放
    //2.颜色、图片变换
    //等等

    //通过之前的学习我们知道
    //如果一个Canvas(画布)下UI元素发生变换会产生画布污染
    //画布污染就意味着会造成Canvas(画布)重建
    //也就是说Animator动画组件会为UGUI带来更多的性能开销
    //并且Animator本质是状态机驱动,每帧都会运行状态逻辑,会有更多开销

    //如果UI界面上一定需要动态效果,可以采用以下方案
    //1.利用DoTween插件做缓动效果
    //2.自己实现动态效果,比如利用协程或Lerp实现插值动画,控制更新频率和时机,避免每帧无意义更新
    //3.用Shader实现动态效果,把计算交给GPU,比如进度条流光、动态血条更新、按钮高亮等
    //4.动静分离进行拆分,将动态效果分离到一个专门的Canvas下,减少重建开销

    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏