一:前言
RectMask2D是矩形遮罩组件,继承自UIBehaviour、IClipper(裁剪者)、ICanvasRaycastFilter 它只能裁剪一个矩形区域,不依赖于Graphic
二:实现原理
OnEnable时将当前RectMask2D对象添加到裁剪者序列中(ClipperRegistry.Register),接着计算当前RectMask2D下所有可被裁剪的子对象并添加到相对应的RectMask2D待裁剪序列中(m_ClipTargets或m_MaskableTargets),画布更新时会依次调用裁剪者序列中的每个元素的PerformClipping方法实现具体裁剪操作,最终是由Shader实现的裁剪,当Shader接收到矩形区域后,片元着色器中判断像素是否在矩形区域内,不在则透明度设置为0,Shader会丢弃掉alpha小于0.001的元素
——AddClippable
添加裁剪对象 设置m_ShouldRecalculateClipRects为true,接着判断裁剪对象是否为MaskableGraphic,并添加到IClippable序列或MaskableGraphic序列中,最后将m_ForceClip设置为true 此方法在MaskableGraphic类的UpdateClipParent方法中被调用,将待裁剪对象添加到当前RectMask2D的待裁剪序列中中
——RemoveClippable
移除裁剪对象 设置m_ShouldRecalculateClipRects为true,接着调用裁剪对象的SetClipRect方法关闭矩形裁剪,接着判断裁剪对象是否为MaskableGraphic,并从IClippable序列或MaskableGraphic序列中移除,最后将m_ForceClip设置为true 此方法在MaskableGraphic类的UpdateClipParent方法中被调用
——OnEnable
首先将自身添加到裁剪序列中,然后调用Notify2DMaskStateChanged方法遍历子对象中挂载了实现IClippable接口的对象(待裁剪对象),调用每个待裁剪对象的RecalculateClipping方法,将待裁剪对象添加到相对应RectMask2D的待裁剪序列中
——OnDisable
清空IClippable序列、MaskableGraphic序列、RectMask2D序列,并将自身从裁剪者序列中移除,最后调用Notify2DMaskStateChanged方法遍历子对象中挂载了实现IClippable接口的对象(待裁剪对象),调用每个待裁剪对象的RecalculateClipping方法,将待裁剪对象添加到相对应RectMask2D的待裁剪序列中
——UpdateClipSoftness
设置m_ClipTargets和m_MaskableTargets序列中每一个待裁剪元素的渐变度(UpdateClipSoftness)
?
——PerformClipping
实现裁剪操作 如果m_ShouldRecalculateClipRects为true,则调用GetRectMasksForClip方法找到父对象身上所有有效的RectMask2D组件(为了处理RectMask2D组件嵌套的情况,因为当有两个RectMask2D时,裁切范围是两个共同作用的区域),接着调用Clipping.FindCullAndClipWorldRect方法计算裁切区域,当确定了裁剪区域后,对m_ClipTargets和m_MaskableTargets序列中每一个待裁剪元素进行裁剪(SetClipRect)和设置渐变度(UpdateClipSoftness) 此方法在ClipperRegistry类中的Cull方法中被调用
|