※Unity2019では動作しましたが2018では動作しなかった・・・
SpriteRenderer では Inside Mask と Outside Mask が選択できどちらの Mask をするか選択できますが
uGUI には Inside Mask しかありません
なので、Mask の処理を拡張し、 Outside Maskの機能を作成しました
使い方
Mask の 子要素でしか動作しないため、Mask の子として Unmask と Image を追加する
Mask (Mask, Image)
├ Unmask (UnMask, Image)
└ Image (Image)
そうすることで、Outside Mask の機能が実現できる
が 通常の Mask と同じく Alpha が 0 もしくは 1 しかとれないので きれいな Mask にはならない
コード
using System; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; public class UnMask : Mask { [NonSerialized] private Material m_MaskMaterial; protected override void OnDisable() { if (graphic != null) { graphic.SetMaterialDirty(); if (graphic is MaskableGraphic) (graphic as MaskableGraphic).isMaskingGraphic = false; } StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = null; MaskUtilities.NotifyStencilStateChanged(this); } public override Material GetModifiedMaterial(Material baseMaterial) { if (!MaskEnabled()) return baseMaterial; var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas); if (stencilDepth >= 8) { Debug.LogWarning("Attempting to use a stencil mask with depth > 8", gameObject); return baseMaterial; } var desiredStencilBit = 1 << stencilDepth; var maskMaterial = StencilMaterial.Add( baseMaterial, desiredStencilBit - 1, StencilOp.Zero, CompareFunction.Always, showMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1) ); StencilMaterial.Remove(m_MaskMaterial); m_MaskMaterial = maskMaterial; return m_MaskMaterial; } }