UGUI源码解析(Grahic)

Runtime类图

Graphic

Grahic是UGUI的核心组件,负责显示图像,继承了UIBehaviour,ICanvasElement。它是一个抽象类,是MaskableGraphic(可遮罩图像)的基类,而后者是RawImage,Image和Text的基类。

 

继承自UIBehaviour的方法:

OnEnable方法

调用了CacheCanvas方法,从父节点中获取Canvas列表,取得第一个激活并且可用的Canvas赋值给m_Canvas,把m_Canvas注册到GraphicRegistry中(一个注册处,可以从m_Graphics获取指定Canvas所包含的Graphic,如果m_Graphics不包含,则把当前Graphic和Canvas注册添加到m_Graphics中),接着设置s_WhiteTexture(对应属性MainTexture,用来绘制图形的纹理),最后SetAllDirty(分别设置Layout布局、Vertices顶点和Material材质为Dirty)。

OnDisable方法

从GraphicRegistry和CanvasUpdateRegistry解除注册,并清空canvasRenderer,通知LayoutRebuilder重建Layout。

OnRectTransformDimensionsChange方法(当RectTransform尺寸发生变化时),如果在重建中,只设置SetVerticesDirty,否则调用SetVerticesDirty和SetLayoutDirty。

OnBeforeTransformParentChanged方法,从GraphicRegistry解除注册,并通知LayoutRebuilder重建Layout。

OnTransformParentChanged方法,设置m_Canvas为空,调用CacheCanvas方法。从父节点中获取Canvas列表,取得第一个激活并且可用的Canvas赋值给m_Canvas,把m_Canvas注册到GraphicRegistry中,最后SetAllDirty(分别设置Layout布局、Vertices顶点和Material材质为Dirty)。

OnDidApplyAnimationProperties方法,调用SetAllDirty(分别设置Layout布局、Vertices顶点和Material材质为Dirty)。

OnCanvasHierarchyChanged方法,当父Canvas的状态发生改变时调用(当父Canvas被启用,禁用或嵌套Canvas的OverrideSorting被改变时,该函数被调用),把m_Canvas设置到currentCanvas,设置m_Canvas为空,调用CacheCanvas方法。从父节点中获取Canvas列表,取得第一个激活并且可用的Canvas赋值给m_Canvas,如果currentCanvas与m_Canvas不同,从GraphicRegistry解除注册,如果Graphic是激活并且可用时,重新注册到GraphicRegistry。

SetAllDirty方法

  • SetLayoutDirty(),通知LayoutRebuilder重建Layout,调用m_OnDirtyLayoutCallback()回调
  • SetVerticesDirty(),设置m_VertsDirty为true,把自己注册到CanvasUpdateRegistry的图形重建序列中,并调用m_OnDirtyVertsCallback()回调
  • SetMaterialDirty(),设置m_MaterialDirty为true,把自己注册到CanvasUpdateRegistry的图形重建序列中,并调用m_OnDirtyMaterialCallback()回调

 

继承自ICanvasElement的方法

Rebuild方法

在Canvas渲染前被调用,在这个方法里会调用UpdateGeometry和UpdateMaterial更新顶点和材质。

UpdateGeometry方法

调用DoMeshGeneration(DoLegacyMeshGeneration,使用旧版的网格生成)方法,如果rectTransform不为空,且宽高都大于0,调用OnPopulateMesh,实际上只是把顶点和三角形信息保存到了s_VertexHelper里。然后获取所有的IMeshModifier类型的组件,(IMeshModifier是一个接口,需要依据顶点信息的组件继承自它,例如Shadow就间接继承自它),调用IMeshModifier的ModifyMesh方法,修改Mesh信息。最后将s_VertexHelper里修改后的信息赋值给workerMesh,并将workerMesh设置给canvasRenderer。

UpdateMaterial方法

更新canvasRenderer的材质和纹理。在给canvasRenderer设置材质时,会遍历所有IMaterialModifier类型的组件,调用IMaterialModifier.GetModifiedMaterial方法,用于重建图像时,获取修改后的Material,来实现遮罩效果。

OnPopulateMesh方法

在CanvasUpdateRegistry布局重建和图形重建时,会调用重建序列中的Graphic的Rebuild方法,Rebuild方法会调用OnPopulateMesh方法,为CanvasRenderer的Mesh提供了顶点位置、顶点颜色、UV和三角形信息。OnPopulateMesh方法把顶点数据和三角形信息保存到VertexHelper中。这个方法,会在RawImage,Image和Text中被重写,用来绘制图片和文字。

CrossFadeColor方法

ColorTween是渐变效果的方法,通过m_ColorTweenRunner启动一个协程来运行,m_ColorTweenRunner是在Graphic构造函数里创建的,是TweenRunner<ColorTween>的实例。

Raycast方法

通过ICanvasRaycastFilter(Image继承了这个接口)的IsRaycastLocationValid方法,判断射线在该组件是否有效。这个方法在GraphicRaycaster的Raycast方法里也被使用到,用于筛选出被射线 照射到的Graphic。GraphicRaycaster继承自BaseRaycaster,输入模块通过Raycast来获取被影响的对象。

 

OnCullingChanged

当CanvasRenderer.cull is modified的时候调用

PixelAdjustPoint

调整给点的像素以达到完美像素,当canvas.pixelPerfect勾选上时调用

GetPixelAdjustedRect

获取完美像素下的举行区域

RegisterDirtyLayoutCallback

UnregisterDirtyLayoutCallback

注册和反注册布局改变的回调

RegisterDirtyVerticesCallback

UnregisterDirtyVerticesCallback

注册和反注册顶点改变的回调

RegisterDirtyMaterialCallback

UnregisterDirtyMaterialCallback

注册和反注册材质改变的回调

 

GraphicRegistry

用于注册一个Graphic属于的是哪一个画布

内部维护一个字典Dictionary<Canvas, IndexedSet<Graphic>> m_Graphics = new Dictionary<Canvas, IndexedSet<Graphic>>();

IndexedSet ,内部的列表都是唯一值

重要方法:

void RegisterGraphicForCanvas(Canvas c, Graphic graphic),将graphic和c关联起来

void UnregisterGraphicForCanvas(Canvas c, Graphic graphic),解除graphic和c的关联

 IList<Graphic> GetGraphicsForCanvas(Canvas canvas),获取canvas关联着的所有的graphic列表

 

GraphicRaycaster

继承自BaseRaycaster,用于画布下的射线检测

public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList)

1,调用GraphicRegistry.GetGraphicsForCanvas(canvas)获取canvas下的所有关联的Graphic

2,获取displayIndex,

if (canvas.renderMode == RenderMode.ScreenSpaceOverlay || currentEventCamera == null)
                displayIndex = canvas.targetDisplay;
else
                displayIndex = currentEventCamera.targetDisplay;

 

3,判断eventPosition是否为Vector3.zero,

如果不是,求出  int eventDisplayIndex = (int)eventPosition.z;如果eventDisplayIndex != displayIndex直接return

如果是,eventPosition = eventData.position;

4,将当前的eventPosition转换到当前的视口坐标系中求出其坐标位置

5,从这个位置发射一条射线,求出射线得到的结果,判断是否为有效击中,将有效击中的存到结果列表中

 

private static void Raycast(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, IList<Graphic> foundGraphics, List<Graphic> results)

过滤掉无效的结果,并按照depth排序

                if (graphic.depth == -1 || !graphic.raycastTarget || graphic.canvasRenderer.cull)
                    continue;

                if (!RectTransformUtility.RectangleContainsScreenPoint(graphic.rectTransform, pointerPosition, eventCamera))
                    continue;

                if (eventCamera != null && eventCamera.WorldToScreenPoint(graphic.rectTransform.position).z > eventCamera.farClipPlane)
                    continue;

                if (graphic.Raycast(pointerPosition, eventCamera))
                {
                    s_SortedGraphics.Add(graphic);
                }

   s_SortedGraphics.Sort((g1, g2) => g2.depth.CompareTo(g1.depth));

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值