diff options
author | chai <chaifix@163.com> | 2021-04-07 19:10:30 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-04-07 19:10:30 +0800 |
commit | e7dfbec8e8634e767d78959941daf71a96e021cf (patch) | |
tree | 58895a7c60df0bd3f316e6461051eabd1c0a51e1 /Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask | |
parent | ff5a3fbf31db349db11bbc5c60ba199d26780f19 (diff) |
*移动目录
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask')
12 files changed, 836 insertions, 0 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs new file mode 100644 index 0000000..ffe7aed --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs @@ -0,0 +1,11 @@ +using System; + +namespace UnityEngine.UI +{ + [Obsolete("Not supported anymore.", true)] + public interface IMask + { + bool Enabled(); + RectTransform rectTransform { get; } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs.meta new file mode 100644 index 0000000..2eab58a --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d54c702726ac4fa4daf18719b41de69f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs new file mode 100644 index 0000000..8f8a28c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs @@ -0,0 +1,9 @@ +using System; + +namespace UnityEngine.UI +{ + public interface IMaskable + { + void RecalculateMasking(); + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs.meta new file mode 100644 index 0000000..298aac8 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5775a30dcbc6e484c8795bb7e18ada44 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs new file mode 100644 index 0000000..39dc291 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs @@ -0,0 +1,166 @@ +using System; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.Rendering; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Mask", 13)] + [ExecuteInEditMode] + [RequireComponent(typeof(RectTransform))] + [DisallowMultipleComponent] + public class Mask : UIBehaviour, ICanvasRaycastFilter, IMaterialModifier + { + [NonSerialized] + private RectTransform m_RectTransform; + public RectTransform rectTransform + { + get { return m_RectTransform ?? (m_RectTransform = GetComponent<RectTransform>()); } + } + + [SerializeField] + [FormerlySerializedAs("m_ShowGraphic")] + private bool m_ShowMaskGraphic = true; + public bool showMaskGraphic + { + get { return m_ShowMaskGraphic; } + set + { + if (m_ShowMaskGraphic == value) + return; + + m_ShowMaskGraphic = value; + if (graphic != null) + graphic.SetMaterialDirty(); + } + } + + [NonSerialized] + private Graphic m_Graphic; + public Graphic graphic + { + get { return m_Graphic ?? (m_Graphic = GetComponent<Graphic>()); } + } + + [NonSerialized] + private Material m_MaskMaterial; + + [NonSerialized] + private Material m_UnmaskMaterial; + + protected Mask() + {} + + public virtual bool MaskEnabled() { return IsActive() && graphic != null; } + + [Obsolete("Not used anymore.")] + public virtual void OnSiblingGraphicEnabledDisabled() {} + + protected override void OnEnable() + { + base.OnEnable(); + if (graphic != null) + { + graphic.canvasRenderer.hasPopInstruction = true; + graphic.SetMaterialDirty(); + } + + MaskUtilities.NotifyStencilStateChanged(this); + } + + protected override void OnDisable() + { + // we call base OnDisable first here + // as we need to have the IsActive return the + // correct value when we notify the children + // that the mask state has changed. + base.OnDisable(); + if (graphic != null) + { + graphic.SetMaterialDirty(); + graphic.canvasRenderer.hasPopInstruction = false; + graphic.canvasRenderer.popMaterialCount = 0; + } + + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = null; + StencilMaterial.Remove(m_UnmaskMaterial); + m_UnmaskMaterial = null; + + MaskUtilities.NotifyStencilStateChanged(this); + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + + if (!IsActive()) + return; + + if (graphic != null) + graphic.SetMaterialDirty(); + + MaskUtilities.NotifyStencilStateChanged(this); + } + +#endif + + public virtual bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera) + { + if (!isActiveAndEnabled) + return true; + + return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, sp, eventCamera); + } + + /// Stencil calculation time! + public virtual Material GetModifiedMaterial(Material baseMaterial) + { + if (!MaskEnabled()) + return baseMaterial; + + var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); + var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas); + if (stencilDepth >= 8) + { + Debug.LogError("Attempting to use a stencil mask with depth > 8", gameObject); + return baseMaterial; + } + + int desiredStencilBit = 1 << stencilDepth; + + // if we are at the first level... + // we want to destroy what is there + if (desiredStencilBit == 1) + { + var maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, m_ShowMaskGraphic ? ColorWriteMask.All : 0); + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = maskMaterial; + + var unmaskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0); + StencilMaterial.Remove(m_UnmaskMaterial); + m_UnmaskMaterial = unmaskMaterial; + graphic.canvasRenderer.popMaterialCount = 1; + graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); + + return m_MaskMaterial; + } + + //otherwise we need to be a bit smarter and set some read / write masks + var maskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, m_ShowMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = maskMaterial2; + + graphic.canvasRenderer.hasPopInstruction = true; + var unmaskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit - 1, StencilOp.Replace, CompareFunction.Equal, 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); + StencilMaterial.Remove(m_UnmaskMaterial); + m_UnmaskMaterial = unmaskMaterial2; + graphic.canvasRenderer.popMaterialCount = 1; + graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); + + return m_MaskMaterial; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs.meta new file mode 100644 index 0000000..50caa3d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfc675de41855c44aaedb7af695ba899 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs new file mode 100644 index 0000000..c975dc6 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs @@ -0,0 +1,182 @@ +using System.Collections.Generic; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + public class MaskUtilities + { + public static void Notify2DMaskStateChanged(Component mask) + { + var components = ListPool<Component>.Get(); + mask.GetComponentsInChildren(components); + for (var i = 0; i < components.Count; i++) + { + if (components[i] == null || components[i].gameObject == mask.gameObject) + continue; + + var toNotify = components[i] as IClippable; + if (toNotify != null) + toNotify.RecalculateClipping(); + } + ListPool<Component>.Release(components); + } + + public static void NotifyStencilStateChanged(Component mask) + { + var components = ListPool<Component>.Get(); + mask.GetComponentsInChildren(components); + for (var i = 0; i < components.Count; i++) + { + if (components[i] == null || components[i].gameObject == mask.gameObject) + continue; + + var toNotify = components[i] as IMaskable; + if (toNotify != null) + toNotify.RecalculateMasking(); + } + ListPool<Component>.Release(components); + } + + public static Transform FindRootSortOverrideCanvas(Transform start) + { + var canvasList = ListPool<Canvas>.Get(); + start.GetComponentsInParent(false, canvasList); + Canvas canvas = null; + + for (int i = 0; i < canvasList.Count; ++i) + { + canvas = canvasList[i]; + + // We found the canvas we want to use break + if (canvas.overrideSorting) + break; + } + ListPool<Canvas>.Release(canvasList); + + return canvas != null ? canvas.transform : null; + } + + public static int GetStencilDepth(Transform transform, Transform stopAfter) + { + var depth = 0; + if (transform == stopAfter) + return depth; + + var t = transform.parent; + var components = ListPool<Mask>.Get(); + while (t != null) + { + t.GetComponents<Mask>(components); + for (var i = 0; i < components.Count; ++i) + { + if (components[i] != null && components[i].MaskEnabled() && components[i].graphic.IsActive()) + { + ++depth; + break; + } + } + + if (t == stopAfter) + break; + + t = t.parent; + } + ListPool<Mask>.Release(components); + return depth; + } + + public static bool IsDescendantOrSelf(Transform father, Transform child) + { + if (father == null || child == null) + return false; + + if (father == child) + return true; + + while (child.parent != null) + { + if (child.parent == father) + return true; + + child = child.parent; + } + + return false; + } + + public static RectMask2D GetRectMaskForClippable(IClippable clippable) + { + List<RectMask2D> rectMaskComponents = ListPool<RectMask2D>.Get(); + List<Canvas> canvasComponents = ListPool<Canvas>.Get(); + RectMask2D componentToReturn = null; + + clippable.rectTransform.GetComponentsInParent(false, rectMaskComponents); + + if (rectMaskComponents.Count > 0) + { + for (int rmi = 0; rmi < rectMaskComponents.Count; rmi++) + { + componentToReturn = rectMaskComponents[rmi]; + if (componentToReturn.gameObject == clippable.gameObject) + { + componentToReturn = null; + continue; + } + if (!componentToReturn.isActiveAndEnabled) + { + componentToReturn = null; + continue; + } + clippable.rectTransform.GetComponentsInParent(false, canvasComponents); + for (int i = canvasComponents.Count - 1; i >= 0; i--) + { + if (!IsDescendantOrSelf(canvasComponents[i].transform, componentToReturn.transform) && canvasComponents[i].overrideSorting) + { + componentToReturn = null; + break; + } + } + return componentToReturn; + } + } + + ListPool<RectMask2D>.Release(rectMaskComponents); + ListPool<Canvas>.Release(canvasComponents); + + return componentToReturn; + } + + public static void GetRectMasksForClip(RectMask2D clipper, List<RectMask2D> masks) + { + masks.Clear(); + + List<Canvas> canvasComponents = ListPool<Canvas>.Get(); + List<RectMask2D> rectMaskComponents = ListPool<RectMask2D>.Get(); + clipper.transform.GetComponentsInParent(false, rectMaskComponents); + + if (rectMaskComponents.Count > 0) + { + clipper.transform.GetComponentsInParent(false, canvasComponents); + for (int i = rectMaskComponents.Count - 1; i >= 0; i--) + { + if (!rectMaskComponents[i].IsActive()) + continue; + bool shouldAdd = true; + for (int j = canvasComponents.Count - 1; j >= 0; j--) + { + if (!IsDescendantOrSelf(canvasComponents[j].transform, rectMaskComponents[i].transform) && canvasComponents[j].overrideSorting) + { + shouldAdd = false; + break; + } + } + if (shouldAdd) + masks.Add(rectMaskComponents[i]); + } + } + + ListPool<RectMask2D>.Release(rectMaskComponents); + ListPool<Canvas>.Release(canvasComponents); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs.meta new file mode 100644 index 0000000..5e7829c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 469f0aa53de5d4c4fb69e83419090a01 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskableGraphic.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskableGraphic.cs new file mode 100644 index 0000000..4995dc1 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskableGraphic.cs @@ -0,0 +1,229 @@ +using System; +using UnityEngine.Events; +using UnityEngine.Rendering; + +namespace UnityEngine.UI +{ + public abstract class MaskableGraphic : Graphic, IClippable, IMaskable, IMaterialModifier + { + [NonSerialized] + protected bool m_ShouldRecalculateStencil = true; + + [NonSerialized] + protected Material m_MaskMaterial; + + [NonSerialized] + private RectMask2D m_ParentMask; + + // m_Maskable is whether this graphic is allowed to be masked or not. It has the matching public property maskable. + // The default for m_Maskable is true, so graphics under a mask are masked out of the box. + // The maskable property can be turned off from script by the user if masking is not desired. + // m_IncludeForMasking is whether we actually consider this graphic for masking or not - this is an implementation detail. + // m_IncludeForMasking should only be true if m_Maskable is true AND a parent of the graphic has an IMask component. + // Things would still work correctly if m_IncludeForMasking was always true when m_Maskable is, but performance would suffer. + [NonSerialized] + private bool m_Maskable = true; + + [NonSerialized] + [Obsolete("Not used anymore.", true)] + protected bool m_IncludeForMasking = false; + + [Serializable] + public class CullStateChangedEvent : UnityEvent<bool> {} + + // Event delegates triggered on click. + [SerializeField] + private CullStateChangedEvent m_OnCullStateChanged = new CullStateChangedEvent(); + + public CullStateChangedEvent onCullStateChanged + { + get { return m_OnCullStateChanged; } + set { m_OnCullStateChanged = value; } + } + + public bool maskable + { + get { return m_Maskable; } + set + { + if (value == m_Maskable) + return; + m_Maskable = value; + m_ShouldRecalculateStencil = true; + SetMaterialDirty(); + } + } + + [NonSerialized] + [Obsolete("Not used anymore", true)] + protected bool m_ShouldRecalculate = true; + + [NonSerialized] + protected int m_StencilValue; + + public virtual Material GetModifiedMaterial(Material baseMaterial) + { + var toUse = baseMaterial; + + if (m_ShouldRecalculateStencil) + { + var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); + m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0; + 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 > 0 && (maskComponent == null || !maskComponent.IsActive())) + { + var maskMat = StencilMaterial.Add(toUse, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0); + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = maskMat; + toUse = m_MaskMaterial; + } + return toUse; + } + + public virtual void Cull(Rect clipRect, bool validRect) + { + var cull = !validRect || !clipRect.Overlaps(rootCanvasRect, true); + UpdateCull(cull); + } + + private void UpdateCull(bool cull) + { + var cullingChanged = canvasRenderer.cull != cull; + canvasRenderer.cull = cull; + + if (cullingChanged) + { + UISystemProfilerApi.AddMarker("MaskableGraphic.cullingChanged", this); + m_OnCullStateChanged.Invoke(cull); + SetVerticesDirty(); + } + } + + public virtual void SetClipRect(Rect clipRect, bool validRect) + { + if (validRect) + canvasRenderer.EnableRectClipping(clipRect); + else + canvasRenderer.DisableRectClipping(); + } + + protected override void OnEnable() + { + base.OnEnable(); + m_ShouldRecalculateStencil = true; + UpdateClipParent(); + SetMaterialDirty(); + + if (GetComponent<Mask>() != null) + { + MaskUtilities.NotifyStencilStateChanged(this); + } + } + + protected override void OnDisable() + { + base.OnDisable(); + m_ShouldRecalculateStencil = true; + SetMaterialDirty(); + UpdateClipParent(); + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = null; + + if (GetComponent<Mask>() != null) + { + MaskUtilities.NotifyStencilStateChanged(this); + } + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + m_ShouldRecalculateStencil = true; + UpdateClipParent(); + SetMaterialDirty(); + } + +#endif + + protected override void OnTransformParentChanged() + { + base.OnTransformParentChanged(); + + if (!isActiveAndEnabled) + return; + + m_ShouldRecalculateStencil = true; + UpdateClipParent(); + SetMaterialDirty(); + } + + [Obsolete("Not used anymore.", true)] + public virtual void ParentMaskStateChanged() {} + + protected override void OnCanvasHierarchyChanged() + { + base.OnCanvasHierarchyChanged(); + + if (!isActiveAndEnabled) + return; + + m_ShouldRecalculateStencil = true; + UpdateClipParent(); + SetMaterialDirty(); + } + + readonly Vector3[] m_Corners = new Vector3[4]; + private Rect rootCanvasRect + { + get + { + rectTransform.GetWorldCorners(m_Corners); + + if (canvas) + { + Canvas rootCanvas = canvas.rootCanvas; + for (int i = 0; i < 4; ++i) + m_Corners[i] = rootCanvas.transform.InverseTransformPoint(m_Corners[i]); + } + + return new Rect(m_Corners[0].x, m_Corners[0].y, m_Corners[2].x - m_Corners[0].x, m_Corners[2].y - m_Corners[0].y); + } + } + + 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; + } + + public virtual void RecalculateClipping() + { + UpdateClipParent(); + } + + public virtual void RecalculateMasking() + { + m_ShouldRecalculateStencil = true; + SetMaterialDirty(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskableGraphic.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskableGraphic.cs.meta new file mode 100644 index 0000000..07f0d51 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskableGraphic.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1316d79994e789c448714be540d28f4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs new file mode 100644 index 0000000..87d2dbf --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Rect Mask 2D", 13)] + [ExecuteInEditMode] + [DisallowMultipleComponent] + [RequireComponent(typeof(RectTransform))] + public class RectMask2D : UIBehaviour, IClipper, ICanvasRaycastFilter + { + [NonSerialized] + private readonly RectangularVertexClipper m_VertexClipper = new RectangularVertexClipper(); + + [NonSerialized] + private RectTransform m_RectTransform; + + [NonSerialized] + private HashSet<IClippable> m_ClipTargets = new HashSet<IClippable>(); + + [NonSerialized] + private bool m_ShouldRecalculateClipRects; + + [NonSerialized] + private List<RectMask2D> m_Clippers = new List<RectMask2D>(); + + [NonSerialized] + private Rect m_LastClipRectCanvasSpace; + [NonSerialized] + private bool m_LastValidClipRect; + [NonSerialized] + private bool m_ForceClip; + + public Rect canvasRect + { + get + { + Canvas canvas = null; + var list = ListPool<Canvas>.Get(); + gameObject.GetComponentsInParent(false, list); + if (list.Count > 0) + canvas = list[list.Count - 1]; + ListPool<Canvas>.Release(list); + + return m_VertexClipper.GetCanvasRect(rectTransform, canvas); + } + } + + public RectTransform rectTransform + { + get { return m_RectTransform ?? (m_RectTransform = GetComponent<RectTransform>()); } + } + + protected RectMask2D() + {} + + protected override void OnEnable() + { + base.OnEnable(); + m_ShouldRecalculateClipRects = true; + ClipperRegistry.Register(this); + MaskUtilities.Notify2DMaskStateChanged(this); + } + + protected override void OnDisable() + { + // we call base OnDisable first here + // as we need to have the IsActive return the + // correct value when we notify the children + // that the mask state has changed. + base.OnDisable(); + m_ClipTargets.Clear(); + m_Clippers.Clear(); + ClipperRegistry.Unregister(this); + MaskUtilities.Notify2DMaskStateChanged(this); + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + m_ShouldRecalculateClipRects = true; + + if (!IsActive()) + return; + + MaskUtilities.Notify2DMaskStateChanged(this); + } + +#endif + + public virtual bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera) + { + if (!isActiveAndEnabled) + return true; + + return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, sp, eventCamera); + } + + public virtual void PerformClipping() + { + //TODO See if an IsActive() test would work well here or whether it might cause unexpected side effects (re case 776771) + + // if the parents are changed + // or something similar we + // do a recalculate here + if (m_ShouldRecalculateClipRects) + { + MaskUtilities.GetRectMasksForClip(this, m_Clippers); + m_ShouldRecalculateClipRects = false; + } + + // get the compound rects from + // the clippers that are valid + bool validRect = true; + Rect clipRect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); + bool clipRectChanged = clipRect != m_LastClipRectCanvasSpace; + if (clipRectChanged || m_ForceClip) + { + foreach (IClippable clipTarget in m_ClipTargets) + clipTarget.SetClipRect(clipRect, validRect); + + m_LastClipRectCanvasSpace = clipRect; + m_LastValidClipRect = validRect; + } + + foreach (IClippable clipTarget in m_ClipTargets) + { + var maskable = clipTarget as MaskableGraphic; + if (maskable != null && !maskable.canvasRenderer.hasMoved && !clipRectChanged) + continue; + + clipTarget.Cull(m_LastClipRectCanvasSpace, m_LastValidClipRect); + } + } + + public void AddClippable(IClippable clippable) + { + if (clippable == null) + return; + m_ShouldRecalculateClipRects = true; + if (!m_ClipTargets.Contains(clippable)) + m_ClipTargets.Add(clippable); + + m_ForceClip = true; + } + + public void RemoveClippable(IClippable clippable) + { + if (clippable == null) + return; + + m_ShouldRecalculateClipRects = true; + clippable.SetClipRect(new Rect(), false); + m_ClipTargets.Remove(clippable); + + m_ForceClip = true; + } + + protected override void OnTransformParentChanged() + { + base.OnTransformParentChanged(); + m_ShouldRecalculateClipRects = true; + } + + protected override void OnCanvasHierarchyChanged() + { + base.OnCanvasHierarchyChanged(); + m_ShouldRecalculateClipRects = true; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs.meta new file mode 100644 index 0000000..3f31967 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c06d6b758f7cbc148afa25153c439510 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |