博客
关于我
(五)UGUI源码分析之Rebuild(布局重建、图形重绘)
阅读量:508 次
发布时间:2019-03-07

本文共 2255 字,大约阅读时间需要 7 分钟。

CanvasUpdateRegistry 和 ICanvasElement 相关 Rebuild 操作 时机

最近在优化 UI 组件性能时,深入研究了 CanvasUpdateRegistry、ICanvasElement、LayoutGroup 等相关组件的工作原理,尤其是 Rebuild 操作的实现细节。通过阅读源码和调试实例,整理出以下关键信息,供开发者参考。


一、添加 需要 Rebuild 的 元素 时机

1. 自身 继承 ICanvasElement 的 类

ICanvasElement 接口的继承类(如 ScrollRect、Toggle、Slider 等)在以下时机添加布局元素:

  • ScrollRect

    • OnEnable 方法
    • SetDirtyCaching 方法(触发时赋值 viewport、horizontalScrollbar、verticalScrollbar 等属性时)
    • OnDisable 方法,会移除元素,并调用 LayoutRebuilder.MarkLayoutForRebuild(rectTransform)
    • OnRectTransformDimensionsChange(RectTransform尺寸变化时)
    • horizontalScrollbarVisibility、verticalScrollbarVisibility 修改时
  • Toggle

    • 编辑模式下,在PrefabUtility.IsPartOfPrefabAsset(this) 为 false 且未运行游戏时,调用 OnValidate 方法进行添加布局元素。
  • Slider

    • 同样在编辑模式下,调用 OnValidate 方法进行添加布局元素。

2. 非继承 ICanvasElement 的 类

对于不直接继承 ICanvasElement 的组件,需要通过 LayoutRebuilder.MarkLayoutForRebuild(rectTransform) 方法将父物体中拥有 LayoutGroup 组件的物体封装到布局列表中。具体规则如下:

  • 如果当前物体有 LayoutGroup 且父物体无,则将当前物体添加到布局列表。
  • 如果父物体有 LayoutGroup 而当前物体无,则将父物体添加到布局列表。
  • 如果当前物体和父物体均无 LayoutGroup,则不添加。

二、各大类的 Rebuild 方法 具体 内容

1. 只参与布局(布局前、布局后)

  • ScrollRect

    • 具体操作通过自身的 Rebuild 方法(继承自 ICanvasElement)。
    • 在编辑模式下,Toggle 和 Slider 会调用 onValueChange 方法(布局前)。
    • 借助 LayoutRebuilder 进行计算,确定水平和垂直布局容器的合适尺寸,然后确定子物体的尺寸和位置。
  • LayoutRebuilder

    • 在布局过程中,通过 Rebuild 方法计算 Horizontal 和 Vertical 布局容器的正确大小,并更新子物体的尺寸和位置。
  • 其他布局相关类(如 HorizontalLayout、VerticalLayout、GridLayout):

    • 在 Rebuild 方法中,根据容器大小参数计算子物体布局信息,完成布局更新。

2. 只参与绘制(绘制前、绘制后)

  • Graphic 类及其子类(如 Text、Image 等):

    • 在绘制前,通过 SetVerticesDirty(V)、SetMaterialDirty(M)、OnCullingChanged(C)等方法标记为需要更新。
    • 其他触发绘制列表更新的时机包括:
      • Text 类:设置 text、supportRichText、resizeTextForBestFit 等属性时。
      • Image 类:设置 type、preserveAspect、fillCenter 等属性时,或在 OnCanvasHierarchyChanged 方法。
      • Shadow/Outline:设置 useGraphicAlpha、effectDistance、effectColor 等属性时。
  • RawImage、BaseMeshEffect、AspectRatioFitter 等

    • 在属性改变时调用 V 方法(如 texture 改变、uvRect 改变)。
    • 或在 RectTransform 属性变化时触发(如 OnRectTransformDimensionsChange)。

三、其他注意事项

  • _prefabInstanceUpdated 事件:
    • 在 PrefabUtility namespace注册了 OnPrefabInstanceUpdates 方法。
    • 当预制体实例化后,会调用 LayoutRebuilder.MarkLayoutForRebuild(rectTransform)。
    • 主要用于更新场景中的 LayoutGroup 组件。

四、总结

通过以上分析,可以清晰地知道哪些组件在何时触发 LayoutRebuild 和 GraphicRebuild 操作。理解 Rebuild 的触发时机,对于优化 UI 更新效率至关重要。建议在实际开发中,结合项目需求,对相关组件的 Rebuild 行为做细致调试和优化。

如有疑问或需要更深入的实现细节,可以参考 UnityEditor.UI namespace 中的相关类实现。

转载地址:http://teucz.baihongyu.com/

你可能感兴趣的文章
Nginx反向代理配置
查看>>
Nginx启动SSL功能,并进行功能优化,你看这个就足够了
查看>>
nginx启动脚本
查看>>
Nginx和Tomcat的区别
查看>>
Nginx在Windows上和Linux上(Docker启动)分别配置基本身份认证示例
查看>>
Nginx在Windows下载安装启动与配置前后端请求代理
查看>>
Nginx在开发中常用的基础命令
查看>>
Nginx基础知识点与使用场景梳理
查看>>
Nginx多域名,多证书,多服务配置,实用版
查看>>
nginx如何实现图片防盗链
查看>>
Nginx学习总结(10)——Nginx前后端分离将多个请求转发到多个Tomcat,负载均衡反向代理
查看>>
Nginx学习总结(11)——提高Nginx服务器的安全性,稳定性和性能的12种技巧
查看>>
Nginx学习总结(12)——Nginx各项配置总结
查看>>
Nginx学习总结(13)——Nginx 重要知识点回顾
查看>>
Nginx学习总结(14)——Nginx配置参数详细说明与整理
查看>>
Nginx学习总结(15)—— 提升 Web 应用性能的十个步骤
查看>>
Nginx学习总结(1)——Nginx入门简介
查看>>
Nginx学习总结(2)——Nginx手机版和PC电脑版网站配置
查看>>
Nginx学习总结(3)——Nginx配置及应用场景之高级配置
查看>>
Nginx学习总结(4)——负载均衡session会话保持方法
查看>>