UGUI UI重建二三事(一)
UGUI UI重建二三事(二)
[UGUI源码二]Unity UI重建(Rebuild)源码分析
这一部分主要是通过以上几篇文章学习的,总结一下:
UI重建主要分类两类,一类是布局重建(Layout Rebuild),另一类是图形重建(Graphic Rebuild)。而一个UI若要重建,必须继承自ICanvasElement接口,因为执行重建操作的时候会调用接口中的Rebuild函数。
而Rebuild函数:
public virtual void Rebuild(CanvasUpdate update)
{if (canvasRenderer == null || canvasRenderer.cull)return;
switch (update){case CanvasUpdate.PreRender:if (m_VertsDirty){UpdateGeometry();m_VertsDirty = false;}if (m_MaterialDirty){UpdateMaterial();m_MaterialDirty = false;}break;}
}
可以看到,rebuild是否执行主要与这三个字段有关:
1.canvasRenderer.cull:指示是否忽略此渲染器发出的几何体。
2.m_VertsDirty:和函数SetVerticesDirty()有关。
3.m_MaterialDirty:和函数SetMaterialDirty()有关。
所以当我们要减少rebuild,首先应该从cull入手,目前只看到RectMask2D有与这个字段有关的代码,详细可以看参考文章一的最后一部分。
其次我们要避免后面两个字段被设置为true,查看这两个方法的引用就可以知道大致应该从哪些方面避免:
1.Text控件 文本的内容及颜色变化、设置是否支持富文本、更改换行模式、设置字体最大最小值、变更文本使用的对齐锚点、设置是否通过几何对齐、变更字体大小、变更是否支持水平及垂直溢出、修改行间距、变更字体样式(正常、斜体…)。
2.Image控件 颜色变化、变更显示类型(Simple、Sliced、Tiled、Filled)、变更是否应保留Sprite宽高比(Image.preserveAspect属性的变更),FillCenter属性变更(是否渲染平铺或切片图像的中心)、变更填充方式(Horizontal、Vertical、Radial360…)、变更图像填充率(fillAmount)、变更图像顺逆时针填充类型(Image.fillClockwise)、变更填充过程的原点(Image.FillOrigin)。
3.RawImage控件 设置Texture、变更纹理使用的UVRcet、Shadow效果 改变效果的距离(effectDistance)及颜色(effectColor)、变更是否使用Graphic中的Alpha透明度(useGraphicAlpha)。
4.Mask控件 设置是否展示与Mask渲染区域相关的图形(showMaskGraphic),enable发生变化
5.所有继承MaskableGraphic的控件(Image、RawImage、RectMask2D、Text) 设置此图形是否允许被遮盖、enable发生变化、父节点发生变化(TransFromParentChanged)、在Hierachy面板上发生改变(HierachyChanged)。
6.所有继承自BaseMeshEffect的效果类(目前只看到Shadow及PositionAsUV1)的enable变化及应用动画属性的操作。
7.所有继承自Graphic的UI控件材质(material)发生变化。
对于上述可能引发重建的操作,可以采取以下优化措施:
1.避免频繁更新:尽量减少对RectTransform、布局组件和图形属性的频繁更新。
2.分离动态和静态UI元素:将频繁更新的动态UI元素与静态UI元素分开,避免不必要的重建。
3.使用额外的Canvas:将频繁更新的UI元素放在单独的Canvas上,这样可以避免影响到其他不需要重建的UI元素。