UGUI之MaskableGraphic
MaskableGraphic继承自Graphic,并且继承了IClippable, IMaskable, IMaterialModifier三个接口。它是RawImage、Image和Text的父类。
继承自Graphic的方法:
OnEnable:设置m_ShouldRecalculateStencil(是否需要重新计算模板)为true,调用UpdateClipParent(更新裁剪的父对象),调用SetMaterialDirty(设置材质为脏,Graphic的函数)。若有Mask组件,调用静态函数MaskUtilities.NotifyStencilStateChanged,重新计算Mask。
OnDisable:设置m_ShouldRecalculateStencil为true,依次调用 SetMaterialDirty和UpdateClipParent。在StencilMaterial中移除m_MaskMaterial,并把m_MaskMaterial设为null。若有Mask组件,调用静态函数MaskUtilities.NotifyStencilStateChanged。
OnTransformParentChanged(当父对象改变):设置 m_ShouldRecalculateStencil为true,依次调用UpdateClipParent、SetMaterialDirty。
OnCanvasHierarchyChanged(父对象的Canvas状态改变):设置 m_ShouldRecalculateStencil为true,依次调用UpdateClipParent、SetMaterialDirty。
看一下UpdateClipParent的代码:
private void UpdateClipParent()
{
var newParent = (maskable && IsActive()) ? MaskUtilities.GetRectMaskForClippable(this) : null; // if the new parent is different OR is now inactive
if (m_ParentMask != null && (newParent != m_ParentMask || !newParent.IsActive()))
{
m_ParentMask.RemoveClippable(this);
UpdateCull(false);
} // don't re-add it if the newparent is inactive
if (newParent != null && newParent.IsActive())
newParent.AddClippable(this); m_ParentMask = newParent;
}
调用MaskUtilities.GetRectMaskForClippable找到父对象的RectMask2D组件(RectMask2D组件可以根据RectTransform裁剪子对象,子对象超出父RectTransform范围的部分会被裁剪掉)。
如果newParent不等于m_ParentMask或者newParent是未激活的,就调用RemoveClippable(在RemoveClippable中调用clippable.SetClipRect(new Rect(), false)关闭矩形裁剪,并且把自己从RectMask2D的m_ClipTargets中删除),然后更新剔除。
如果newParent激活,就调用AddClippable(把自己添加到RectMask2D的m_ClipTargets中)。
把newParent赋值给m_ParentMask。
继承自IClippable的方法:
RecalculateClipping(当父对象的IClippable状态改变时调用):调用UpdateClipParent。
Cull:如果validRect为false或者clipRect与rootCanvasRect矩形不重合,调用UpdateCull。UpdateCull中,如果canvasRenderer.cull不等于输入的cull,则canvasRenderer.cull=cull,回调m_OnCullStateChanged,再调用Graphic的OnCullingChanged函数。
SetClipRect:根据传入的validRect值,选择开启或者关闭canvasRenderer的矩形裁剪。
继承自IMaskable的方法:
RecalculateMasking:在StencilMaterial中移除m_MaskMaterial,把m_MaskMaterial设为null,m_ShouldRecalculateStencil设为true,调用SetMaterialDirty函数。
继承自IMaterialModifier的方法:
public virtual Material GetModifiedMaterial(Material baseMaterial)
{
var toUse = baseMaterial; if (m_ShouldRecalculateStencil)
{
var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);
m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : ;
m_ShouldRecalculateStencil = false;
} // if we have a enabled Mask component then it will
// generate the mask material. This is an optimisation
// it adds some coupling between components though :(
Mask maskComponent = GetComponent<Mask>();
if (m_StencilValue > && (maskComponent == null || !maskComponent.IsActive()))
{
var maskMat = StencilMaterial.Add(toUse, ( << m_StencilValue) - , StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, ( << m_StencilValue) - , );
StencilMaterial.Remove(m_MaskMaterial);
m_MaskMaterial = maskMat;
toUse = m_MaskMaterial;
}
return toUse;
}
GetModifiedMaterial:如果m_ShouldRecalculateStencil为true,通过MaskUtilities.FindRootSortOverrideCanvas获取rootCanvas,根据maskable,给m_StencilValue赋值为模板深度或者0,m_ShouldRecalculateStencil设为false。
如果 m_StencilValue大于0且Mask组件不存在或者未激活,就把baseMaterial,stencilID,operation等参数添加到StencilMaterial中,并把m_MaskMaterial替换成新的材质。
最新文章
- 选择学习Pomelo
- python(7)&ndash; 类的反射
- SQL Server触发器以及如何在SQL Server Manager中调试触发器
- npm 好用工具 for 前端
- Sort(归并)
- IP:网际协议
- windows 计划任务执行python脚本
- 移动端适配方案以及rem和px之间的转换
- EOJ3536 求蛇形矩阵每一行的和---找规律
- SSH 连接慢
- pop() 删除掉数组的最后一个元素
- firstPage
- Android Error:Could not find lottie.jar
- JDK1.6 Java.lang.Null.Pointer.Exception
- Java复习 之流
- UFT12 更新模式
- Java学习--数组的定义和使用
- Windows10右键添加“在此处打开命令窗口";
- JavaScript--浅谈DOM操作
- Spring Boot Admin 2.1.0 全攻略