Unity官方博文翻译——UGUI优化02

首先附上原文地址:https://unity3d.com/cn/learn/tutorials/topics/best-practices/fundamentals-unity-ui

                                                                    UGUI概要

        理解UGUI系统不同部分的组成非常重要。整个系统是由一些基础类和组件共同构成。本章首先定义了一些贯穿整个系列文章的专业术语,接着讨论了UGUI关键系统的底层行为。


术语

        Canvas,是Unity渲染系统给层状几何体提供的可以被画入、被放在上面或者放在世界空间的底层Unity组件。

        Canvas负责将它包含的几何体组合成batch,生成合适的渲染命令发送给Unity图形系统。这个过程在底层的C++代码中完成,这个过程被称为一次rebatch或者一次batch build。当一个Canvas被标记为包含需要rebatch的几何体时,这个Canvas被认为是dirty的。

        几何体由Canvas Renderer组件提供给Canvas。

        一个子Canvas仅仅是一个嵌套在父Canvas中的组件,子Canvas将它的子物体和它的父Canvas隔离,一个子Canvas下dirty的子物体不会触发父Canvas的rebuild,反之亦然。(这些在某些特殊情况下是不确定的,比如说改变父Canvas的大小导致子Canvas的大小改变。)

        Graphic是UGUI的C#库提供的一个基类。它是UGUI所有类的基类,给所有的UGUI类提供可以画在Canvas系统上的几何图形。大多数Unity内置的继承Graphic的类都是通过继承一个叫MaskableGraphic的子类来实现,这使得他们可以通过IMaskable接口来被隐藏。Drawable类的子类主要是image和text,已经提供了同名的组件。

        Layout组件控制着RectTransform的大小和位置,经常被用于要生成具有相似的大小和位置关系内容的复杂布局。它只依靠RectTransform,只影响与其相关的RectTransform的属性。这些layout组件不依赖于Graphic类,可以独立于UGUI的Graphic组件之外使用。

        Graphic和Layout组件都依赖于CanvasUpdateRegistry类,它不会在Unity编辑器的界面中显示。这个类追踪那些Graphic和Layout组件必须被更新的时候,还有与其对应的Canvas触发了willRenderCanvases事件的时候。

        更新Graphic类和Layout类叫做rebuild。rebuild的过程将在本文后续详细讨论。


渲染细节

        在使用UGUI制作UI时,请牢记Canvas中所有几何体的绘制都在一个透明队列中,这就意味着由UGUI制作的几何体将从始至终伴随着alpha混合,所以从多边形栅格化的每个像素都将被采样,即使它被完全不透明的物体所覆盖。在手机设备上,这种高等级的过度绘制将迅速超过GPU填充频率的承受能力。在移动设备上,这种高级别的过度绘制将迅速超过GPU填充频率的承受能力。


Batch构建过程(Canvas)

        Batch构建过程是指Canvas通过结合网格绘制它所承载的UI元素,生成适当的渲染命令发送给Unity图形流水线。Batch的结果被缓存复用,直到这个Canvas被标为dirty,当Canvas中某一个构成的网格改变的时候就会标记为dirty。

        Canvas的网格从那些Canvas下的CnavasRenderer组件中获取,但不包含任何子Canvas。

        计算Batch要求按照深度排序网格,测试它们是否有重叠,共享材质等等。这个过程是多线程的,在不同的CPU架构下性能表现非常不同,特别是在手机芯片(通常CPU核心很少)和现代桌面CPU(通常拥有四核心或者更多)之间非常不同。


Rebuild过程(Graphics)

        Rebuild过程是指Layout和UGUI的C#的Graphic组件的网格被重新计算,这是在CanvasUpdateRegistry类中执行的。请记住,这是一个C#类,它的源码可以在Unity的Bitbucket上找到。

        在CanvasUpdateRegistry类中,最有意思的就是PerformUpdate方法,当一个Canvas组件触发它的WillRenderCanvases事件时,这个方法就会被执行。这个事件每帧调用一次。

        PerformUpdate函数运行的三个步骤:

        1.通过ICanvasElement.Rebuild函数,请求rebuild被Dirty的Layout组件。

        2.所有被注册的裁剪组件(例如Mask),对需要被裁剪的组件进行剔除。这在ClippingRegistry.Cull中执行。

        3.dirty的Graphic组件被要求rebuild其图形元素。

        对于Layout和Graphic的rebuild,过程被分为多个部分。Layout的rebuild有三个部分(PreLayout, Layout and PostLayout),而Graphic的rebuild有两个部分(PreRender和LatePreRender)。


Layout的rebuild

        要重新计算一个或者多个Layout组件所包含的UI组件的适当位置(以及可能的大小),有必要对Layout应用层次的排序。在GameObject的hierarchy中靠近root的Layout可能会影响改变嵌套在它里面的其他Layout的位置和大小,所以必须首先计算。

        为此,UGUI根据层次结构中的深度对dirty的Layout组件列表进行排序。层次结构中较高的Layout(即拥有较少的父transform)将被移到列表的前面。

        然后,排序好的Layout组件的列表将被rebuild,在这个步骤Layout组件控制的UI元素的位置和大小将被实际改变。关于独立的UI元素如何受Layout组件影响的详细细节,请参阅Unity Manual的UI Auto Layout章节。


Graphic的rebuild

        当Graphic组件被rebuild的时候,UGUI将控制传递给ICanvasElement接口的Rebuild方法。Graphic执行了这一步,并在rebuild过程中的PreRender阶段运行了两个不同的rebuild步骤:

        1.如果顶点数据已经被标为Dirty(例如组件的RectTransform已经改变大小),则重建网格。

        2.如果材质数据已经被标为Dirty(例如组件的material或者texture已经被改变),则关联的Canvas Renderer的材质将被更新。

        Graphic的Rebuild不会按照Graphic组件的特殊顺序进行,也不会进行任何的排序操作。

你可能感兴趣的:(Unity官方博文翻译——UGUI优化02)