• (五)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的重建流程。

  • 相关阅读:
    解决SharePoint 文档库itemadded eventhandler导致的上传完成后,编辑页面保持报错的问题,错误信息为“该文档已经被编辑过 the file has been modified by...”
    解决SharePoint 2013 designer workflow 在发布的报错“负载平衡没有设置”The workflow files were saved but cannot be run.
    随机实例,随机值
    Spring4笔记
    struts2笔记(3)
    struts2笔记(2)
    获取文本的编码类型(from logparse)
    FileUtil(from logparser)
    DateUtil(SimpleDateFormat)
    struts2笔记
  • 原文地址:https://www.cnblogs.com/llstart-new0201/p/12639362.html
Copyright © 2020-2023  润新知