• (五)UGUI CanvasUpdate


    1.前言

    ugui的图像显示核心是Graphic类,而这一切Graphic又由Canvas相关类进行管理。在ugui系统中Canvas是管理ui元素的生命周期与样式变化,而CanvasRenderer则负责ui的显示,包括网格、材质以及rect裁剪等。由于Canvas与CanvasRenderer真正核心代码未开源,所以只能从Graphic类一探究竟。

    2.UGUI运作原理图

    ugui系统的运作核心是CanvasUpdateRegistry类,它通过Canvas的willRenderCanvases回调入手,即每帧在Canvas进行渲染前更细各个Graphic的位置以及渲染信息(mesh、material等),然后根据渲染信息进行渲染,整个运作图如下所示,包括mask在内:
    在这里插入图片描述

    2.1 CanvasUpdateRegistry

    此类维护了两个队列,即Layout重构队列和Graphic重构队列。这两个队列分别存储了Layout的重构信息(位置、大小)和图像更改信息(mesh、材质等)。在Canvas渲染前通过PerformUpdate进行更新,更新流程如下所示:

    第一步,移除队列中的非法元素,比如null或者destroyed。
    第二步,进行Layout更新,会调用LayoutRebuilder里的Rebuild进行重构。
    第三步,剔除(或者说遮罩),此部是进行RectMask2D的作用,调用ClipperRegister中的Cull方法进行。
    第四步,进行Graphic的更新,因为Graphic的mesh等信息跟ui的Rect位置有关系,所以最后进行Graphic重建。

    2.2 Graphic/MaskableGraphic

    这两个类是ui显示的核心,后者通过IClippable和IMaskable可实现遮罩效果。这两个类是“被动”类,即我只标记下一帧需要的操作(更新Layout或者Graphic),至于何时更新由管理者CanvasUpdateRegistry去操作。重点是如下三个方法和两个接口:

    1)SetLayoutDirty
    标记布局需要更细,比如刚启动时或者父类更改等。以父类更改为例,由于更改父类后存在新父类含有LayouGroup组件(比如HorizontalLayoutGroup),则其布局需要更新,所以需要将此ui添加到LayoutRebuilder中(Canvas会调用LayouRebuilder中的Rebuild方法进行Layout重构)。
    2)SetMaterialDirty
    此方法是用来标记Graphic需要重构的,比如贴图更改、材质更改(图像的表现形式)。此时会调用CanvasRenderer的SetMaterial方法。
    3)SetVerticesDirty
    此方法也是用来标记Graphic需要重构的,只是用来标记mesh更改,需要调用OnPopulateMesh进行重新更新mesh。OnPopulateMesh也是Graphic类使用时经常需要自定义Mesh的路口。此时会调用CanvasRenderer的SetMesh方法。
    4)IClippable与IMaskable
    IMaskable是实现Mask遮罩的关键,它是通过材质来实现“像素遮罩”的。而IClippable则是实现RectMask2D的遮罩的关键,他是通过CanvasRenderer的EnableRectClipping以及Cull实现的,它只能实现Rect遮罩。这也是Mask和RectMask2D的差别。

    2.3 RectMask2D遮罩

    RectMask2D的遮罩是通过CanvasRenderer的EnableRectClipping以及Cull实现的,它的工作流程比较复杂,流程如下:
    1)启动时调用MaskUtilities.Notify2DMaskStateChanged方法,通知所有子游戏物体的MaskableGraphic(所有继承IClippable的组件),RectMask2D遮罩产生变化。同时将自己添加的ClipperRegistry的Clipper中。
    2)所有的子MaskableGraphic(所有继承IClippable的组件)根据此通知更新自己遮罩生效的RectMask2D,并加入到RectMask2D的ClipTarget中。
    3)当CanvasUpdateRegistry在更新Canvas时,会调用ClipperRegistry的cull方法,然后依次调用所有RectMask2D的PerformClipping方法。在PerformClipping方法中RectMask2D依次调用ClipTarget元素的SetClipRect和Cull方法,完成剔除。
    4)当以上所有工作完成后,Canvas更新重建,显示我们想要的效果。

    3.结语

    以上为整个Canvas的重建流程。

  • 相关阅读:
    JDBC
    过滤器
    Servlet-web.xml 常见配置
    Servlet-HttpSession接口
    Servlet-Cookie对象
    Servlet-HttpServlet对象
    kmp算法及应用
    线段树入门到自闭
    tarjan算法与拓扑排序
    马拉车模板
  • 原文地址:https://www.cnblogs.com/llstart-new0201/p/12639362.html
Copyright © 2020-2023  润新知