Graphic
是一个抽象类,是MaskableGraphic
的基类,而MaskableGraphic
是Image,RawImage,Text的基类。负责显示界面。继承自UIBehavior
类以及ICanvasElement
接口。
重写UIBehavior的方法
OnEnable
首先调用CacheCanvas
方法,获取第一个处于激活状态的Canvas,然后赋值给m_Canvas
,然后将m_Canvas注册进GraphicRegistry
(之后再看注册进去的作用),然后设置s_WhiteTexture
(也就是mainTexture),最后调用SetAllDirty()
: Layout,Material,Vertices(标记Dirty后会触发重新绘制)
OnDisable
从GraphicRegistry
,CanvasUpdateRegistry
取消注册,清空canvasRender,然后重建Layout。
OnDestroy
删除 Mesh
OnRectTransformDimensionsChange
当RectTransform参数发生变化后会调用这个方法。
如果正在重建就标记顶点
为Dirty,否则标记顶点和Layout为Dirty。
OnBeforeTransformParentChanged
取消从GraphicRegistry
注册,标记重建Layout.
OnTransformParentChanged
重新给m_Canvas
赋值,从GraphicRegistry
注册Canvas,然后SetAllDirty()
。
OnDidApplyAnimationProperties
当 animation 属性发生变化后出发,会SetAllDirty()
。
OnCanvasHierarchyChanged
Called when the state of the parent Canvas is changed. 如果当前Canvas不是第一个处于激活状态的Canvas,那么就取消注册之前的Canvas,然后重新注册新的Canvas。
实现ICanvasElement 接口的方法
Rebuild(CanvasUpdate update)
用来重建当前stage,会在渲染前调用,
如果 canvasRenderer==null || canvasRenderer.cull(忽略渲染)就return掉。
符合条件就根据是否标记了VertsDirty
或MaterialDirty
而进行更新三角面和Material。
其他的一些方法
UpdateGeometry()
根据useLegacyMeshGeneration
不同而执行DoLegacyMeshGeneration()
或者DoMeshGeneration()
方法。
- DoLegacyMeshGeneration。 首先会调用
OnPopulateMesh()
添加四个顶点,以及两个三角面到VertexHelper(这就是创建一个基础的四边形,而四个顶点和两个三角面是必不可少的)这个方法会在Image等组件中重写,然后绘制出不同的东西。
1 | protected virtual void OnPopulateMesh(VertexHelper vh) |
然后进行填充网格(FillMesh),这里要求顶点数不超过65000个。
1 | public void FillMesh(Mesh mesh) |
之后会拿到所有继承IMeshModifier
的组件然后全部通过IMeshModifier.ModifyMesh()
进行修改Mesh信息。最后将Mesh提交给CanvasRenderer。
- DoMeshGeneration() 其实和DoLegacyMeshGeneration差不多。
UpdateMaterial()
更新材质球
和贴图
到CanvasRender。设置材质球时会获取所有的IMaterialModifier
组件,然后遍历这些组件通过IMaterialModifier.GetModifiedMaterial(currentMat)
的方式获取修改过的Material,然后返回。
1 | protected virtual void UpdateMaterial() |
CrossFadeColor()
在TweenRunner中开启协程,像NGUI的Tween动画。
Raycast()
- 首先说一下点击屏幕后如何判断是否点击到某和物体的原理:当点击屏幕,会发出一条由屏幕的点击位置射向屏幕后方的一条射线,检测这条射线是否射中某个GameObject,然后去响应对应事件即可。
在Raycast
方法中通过ICanvasRaycastFilter.IsRaycastLocationValid
进行判断传入的射线是否有效。该方法在GraphicRaycaster中被调用。