diff --git a/CHANGELOG.md b/CHANGELOG.md
index ef1c75e..f48d285 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,23 @@
+# [1.0.0-preview.3](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.2...v1.0.0-preview.3) (2020-06-04)
+
+
+### Bug Fixes
+
+* outside interaction doesn't work when the RaycastFilter option is off ([1935650](https://github.com/mob-sakai/SoftMaskForUGUI/commit/19356500c5b777aa5857fa5176fc09f0fd7951cb))
+
+
+### Features
+
+* Add ignore self graphic option. ([91c0099](https://github.com/mob-sakai/SoftMaskForUGUI/commit/91c00993b9afbdda0386b8e426e181f8f31618b9))
+* TextMeshPro support ([5b0906b](https://github.com/mob-sakai/SoftMaskForUGUI/commit/5b0906b6086193bc8f62fa174955c9df901ef3f0))
+
+
+### BREAKING CHANGES
+
+* TextMeshPro support is now an option.
+If a shader or material has errors after a version upgrade, you will need to import the asset.
+Please see the README for more information.
+
# [1.0.0-preview.2](https://github.com/mob-sakai/SoftMaskForUGUI/compare/v1.0.0-preview.1...v1.0.0-preview.2) (2020-05-13)
diff --git a/README.md b/README.md
index 6b2a934..8471a09 100644
--- a/README.md
+++ b/README.md
@@ -66,6 +66,7 @@ By using SoftMask instead of the default Mask component, you can beautifully rep
+
## Demo
@@ -73,6 +74,7 @@ By using SoftMask instead of the default Mask component, you can beautifully rep
+
## Installation
@@ -117,23 +119,19 @@ Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension) to insta
+
## How to play demo
-#### For Unity 2019.1 or later
+- For Unity 2019.1 or later
+ - Open `Package Manager` window and select `UI Soft Mask` package in package list and click `Demo > Import in project` button
+- For Unity 2018.4 or earlier
+ - Click `Assets/Samples/UISoftMask/Import Demo` from menu
-1. Open `Package Manager` window and select `UI Soft Mask` package in package list
-2. Click `Import in project` button
-
-3. The demo will be imported into `Assets/Samples/UI Soft Mask/{version}/Demo`。
-Open `UISoftMask_Demo` scene and play it
+The assets will be imported into `Assets/Samples/UI Soft Mask/{version}/Demo`.
+Open `UISoftMask_Demo` scene and play it.
-#### For Unity 2018.4 or earlier
-1. Select `Assets/Samples/UI Soft Mask Demo` from menu
-
-2. The demo will be imported into `Assets/Samples/UI Soft Mask/{version}/Demo`.
-Open `UISoftMask_Demo` scene and play it
@@ -152,6 +150,20 @@ Or, add a SoftMaskable components from the inspector of the SoftMask component.
+
+
+## Support TextMeshPro
+
+To use SoftMask with TextMeshPro, import a sample asset.
+
+- For Unity 2019.1 or later
+ - Open `Package Manager` window and select `UI Soft Mask` package in package list and click `TextMeshPro Support > Import in project` button
+- For Unity 2018.4 or earlier
+ - Click `Assets/Samples/UISoftMask/Import TextMeshPro Support` from menu
+
+The assets will be imported into `Assets/Samples/UI Soft Mask/{version}/TextMeshPro Support`.
+
+
## Support soft masks with your custom shaders
@@ -183,7 +195,7 @@ This operation determines the final alpha according to the soft mask buffer.
color.a *= SoftMask(IN.vertex, IN.worldPosition);
```
-As an example of implementation, please see [UI-Default-SoftMask.shader](https://raw.githubusercontent.com/mob-sakai/SoftMaskForUGUI/upm/Shaders/Resources/UI-Default-SoftMask.shader).
+As an example of implementation, please see [UI-Default-SoftMask.shader](https://github.com/mob-sakai/SoftMaskForUGUI/blob/upm/Shaders/Resources/UI-Default-SoftMaskable.shader).
diff --git a/Shaders/TextMeshProSupport.meta b/Samples~/TextMeshPro Support.meta
similarity index 100%
rename from Shaders/TextMeshProSupport.meta
rename to Samples~/TextMeshPro Support.meta
diff --git a/Shaders/TextMeshProSupport/TMP_SDF (SoftMaskable).shader b/Samples~/TextMeshPro Support/TMP_SDF (SoftMaskable).shader
similarity index 100%
rename from Shaders/TextMeshProSupport/TMP_SDF (SoftMaskable).shader
rename to Samples~/TextMeshPro Support/TMP_SDF (SoftMaskable).shader
diff --git a/Shaders/TextMeshProSupport/TMP_SDF (SoftMaskable).shader.meta b/Samples~/TextMeshPro Support/TMP_SDF (SoftMaskable).shader.meta
old mode 100755
new mode 100644
similarity index 75%
rename from Shaders/TextMeshProSupport/TMP_SDF (SoftMaskable).shader.meta
rename to Samples~/TextMeshPro Support/TMP_SDF (SoftMaskable).shader.meta
index 85d6a3d..a1a301f
--- a/Shaders/TextMeshProSupport/TMP_SDF (SoftMaskable).shader.meta
+++ b/Samples~/TextMeshPro Support/TMP_SDF (SoftMaskable).shader.meta
@@ -1,7 +1,9 @@
fileFormatVersion: 2
guid: 935b7be1c88464d2eb87204fdfab5a38
ShaderImporter:
+ externalObjects: {}
defaultTextures: []
+ nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
diff --git a/Shaders/TextMeshProSupport/TMP_SDF-Mobile (SoftMaskable).shader b/Samples~/TextMeshPro Support/TMP_SDF-Mobile (SoftMaskable).shader
similarity index 100%
rename from Shaders/TextMeshProSupport/TMP_SDF-Mobile (SoftMaskable).shader
rename to Samples~/TextMeshPro Support/TMP_SDF-Mobile (SoftMaskable).shader
diff --git a/Shaders/TextMeshProSupport/TMP_SDF-Mobile (SoftMaskable).shader.meta b/Samples~/TextMeshPro Support/TMP_SDF-Mobile (SoftMaskable).shader.meta
old mode 100755
new mode 100644
similarity index 75%
rename from Shaders/TextMeshProSupport/TMP_SDF-Mobile (SoftMaskable).shader.meta
rename to Samples~/TextMeshPro Support/TMP_SDF-Mobile (SoftMaskable).shader.meta
index bbb1dda..4eca24f
--- a/Shaders/TextMeshProSupport/TMP_SDF-Mobile (SoftMaskable).shader.meta
+++ b/Samples~/TextMeshPro Support/TMP_SDF-Mobile (SoftMaskable).shader.meta
@@ -1,7 +1,9 @@
fileFormatVersion: 2
guid: e65241fa80a374114b3f55ed746c04d9
ShaderImporter:
+ externalObjects: {}
defaultTextures: []
+ nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
diff --git a/Shaders/TextMeshProSupport/TMP_Sprite (SoftMaskable).shader b/Samples~/TextMeshPro Support/TMP_Sprite (SoftMaskable).shader
similarity index 100%
rename from Shaders/TextMeshProSupport/TMP_Sprite (SoftMaskable).shader
rename to Samples~/TextMeshPro Support/TMP_Sprite (SoftMaskable).shader
diff --git a/Shaders/TextMeshProSupport/TMP_Sprite (SoftMaskable).shader.meta b/Samples~/TextMeshPro Support/TMP_Sprite (SoftMaskable).shader.meta
old mode 100755
new mode 100644
similarity index 75%
rename from Shaders/TextMeshProSupport/TMP_Sprite (SoftMaskable).shader.meta
rename to Samples~/TextMeshPro Support/TMP_Sprite (SoftMaskable).shader.meta
index 73aa212..f8797a5
--- a/Shaders/TextMeshProSupport/TMP_Sprite (SoftMaskable).shader.meta
+++ b/Samples~/TextMeshPro Support/TMP_Sprite (SoftMaskable).shader.meta
@@ -1,9 +1,9 @@
fileFormatVersion: 2
guid: 94593ebff37d04a64936ebe46ce7e769
-timeCreated: 1450517184
-licenseType: Pro
ShaderImporter:
+ externalObjects: {}
defaultTextures: []
+ nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
diff --git a/Scripts/Editor/EditorUtils.cs b/Scripts/Editor/EditorUtils.cs
index d41f9f7..6a8c097 100644
--- a/Scripts/Editor/EditorUtils.cs
+++ b/Scripts/Editor/EditorUtils.cs
@@ -5,7 +5,6 @@ using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
-
namespace Coffee.UISoftMask
{
internal static class EditorUtils
@@ -36,7 +35,7 @@ namespace Coffee.UISoftMask
var so = new SerializedObject(target);
so.Update();
- bool oldEnable = target.enabled;
+ var oldEnable = target.enabled;
target.enabled = false;
// Find MonoScript of the specified component.
diff --git a/Scripts/Editor/ImportSampleMenu.cs b/Scripts/Editor/ImportSampleMenu.cs
index c61a9d1..56d73c5 100644
--- a/Scripts/Editor/ImportSampleMenu.cs
+++ b/Scripts/Editor/ImportSampleMenu.cs
@@ -8,13 +8,18 @@ namespace Coffee.UISoftMask
{
public static class ImportSampleMenu
{
- [MenuItem("Assets/Samples/Import UISoftMask Sample")]
- private static void ImportSample()
- {
- const string jsonGuid = "c43fd233e88b347cdabc530c23ffe30a";
- const string dirName = "Demo";
+ private const string jsonGuid = "c43fd233e88b347cdabc530c23ffe30a";
- ImportSample(jsonGuid, dirName);
+ [MenuItem("Assets/Samples/UISoftMask/Import Demo")]
+ private static void ImportDemo()
+ {
+ ImportSample(jsonGuid, "Demo");
+ }
+
+ [MenuItem("Assets/Samples/UISoftMask/Import TextMeshPro Support")]
+ private static void ImportTextMeshProSupport()
+ {
+ ImportSample(jsonGuid, "TextMeshProSupport");
}
private static void ImportSample(string jsonGuid, string sampleName)
diff --git a/Scripts/Editor/SoftMaskEditor.cs b/Scripts/Editor/SoftMaskEditor.cs
index 8116ea0..ce32fd7 100644
--- a/Scripts/Editor/SoftMaskEditor.cs
+++ b/Scripts/Editor/SoftMaskEditor.cs
@@ -14,9 +14,9 @@ namespace Coffee.UISoftMask
[CanEditMultipleObjects]
public class SoftMaskEditor : Editor
{
- const string k_PrefsPreview = "SoftMaskEditor_Preview";
- static readonly List s_Graphics = new List();
- static bool s_Preview;
+ private const string k_PrefsPreview = "SoftMaskEditor_Preview";
+ private static readonly List s_Graphics = new List();
+ private static bool s_Preview;
private void OnEnable()
{
@@ -35,9 +35,7 @@ namespace Coffee.UISoftMask
if (0 < fixTargets.Count)
{
GUILayout.BeginHorizontal();
- EditorGUILayout.HelpBox(
- "There are child Graphics that does not have a SoftMaskable component.\nAdd SoftMaskable component to them.",
- MessageType.Warning);
+ EditorGUILayout.HelpBox("There are child Graphics that does not have a SoftMaskable component.\nAdd SoftMaskable component to them.", MessageType.Warning);
GUILayout.BeginVertical();
if (GUILayout.Button("Fix"))
{
@@ -59,9 +57,8 @@ namespace Coffee.UISoftMask
}
// Preview buffer.
- GUILayout.BeginHorizontal(EditorStyles.helpBox);
- if (s_Preview != (s_Preview = EditorGUILayout.ToggleLeft("Preview Buffer", s_Preview,
- GUILayout.MaxWidth(EditorGUIUtility.labelWidth))))
+ GUILayout.BeginVertical(EditorStyles.helpBox);
+ if (s_Preview != (s_Preview = EditorGUILayout.ToggleLeft("Preview Buffer", s_Preview)))
{
EditorPrefs.SetBool(k_PrefsPreview, s_Preview);
}
@@ -69,37 +66,35 @@ namespace Coffee.UISoftMask
if (s_Preview)
{
var tex = current.softMaskBuffer;
- var width = tex.width * 64 / tex.height;
- EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(width, 64), tex, null, ScaleMode.ScaleToFit);
+ var width = tex.width * 128 / tex.height;
+ EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(width, 128), tex, null, ScaleMode.ScaleToFit);
Repaint();
}
-
- GUILayout.FlexibleSpace();
- GUILayout.EndHorizontal();
+ GUILayout.EndVertical();
}
//%%%% Context menu for editor %%%%
[MenuItem("CONTEXT/Mask/Convert To SoftMask", true)]
- static bool _ConvertToSoftMask(MenuCommand command)
+ private static bool _ConvertToSoftMask(MenuCommand command)
{
return EditorUtils.CanConvertTo(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To SoftMask", false)]
- static void ConvertToSoftMask(MenuCommand command)
+ private static void ConvertToSoftMask(MenuCommand command)
{
EditorUtils.ConvertTo(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To Mask", true)]
- static bool _ConvertToMask(MenuCommand command)
+ private static bool _ConvertToMask(MenuCommand command)
{
return EditorUtils.CanConvertTo(command.context);
}
[MenuItem("CONTEXT/Mask/Convert To Mask", false)]
- static void ConvertToMask(MenuCommand command)
+ private static void ConvertToMask(MenuCommand command)
{
EditorUtils.ConvertTo(command.context);
}
diff --git a/Scripts/Editor/SoftMaskableEditor.cs b/Scripts/Editor/SoftMaskableEditor.cs
index 54272f9..d1814fe 100644
--- a/Scripts/Editor/SoftMaskableEditor.cs
+++ b/Scripts/Editor/SoftMaskableEditor.cs
@@ -2,15 +2,17 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
-using System.Linq;
-using System;
-using System.Reflection;
-using Object = UnityEngine.Object;
using MaskIntr = UnityEngine.SpriteMaskInteraction;
-using System.IO;
namespace Coffee.UISoftMask
{
+ internal enum MaskInteraction : int
+ {
+ VisibleInsideMask = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6),
+ VisibleOutsideMask = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6),
+ Custom = -1,
+ }
+
///
/// SoftMaskable editor.
///
@@ -18,18 +20,16 @@ namespace Coffee.UISoftMask
[CanEditMultipleObjects]
public class SoftMaskableEditor : Editor
{
- public enum MaskInteraction : int
- {
- VisibleInsideMask = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6),
- VisibleOutsideMask = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6),
- Custom = -1,
- }
+ private static readonly List s_TmpMasks = new List();
+ private static GUIContent s_MaskWarning;
+ private SerializedProperty _spMaskInteraction;
+ private bool _custom;
- MaskInteraction maskInteraction
+ private MaskInteraction maskInteraction
{
get
{
- int value = _spMaskInteraction.intValue;
+ var value = _spMaskInteraction.intValue;
return _custom
? MaskInteraction.Custom
: System.Enum.IsDefined(typeof(MaskInteraction), value)
@@ -46,31 +46,26 @@ namespace Coffee.UISoftMask
}
}
- bool _custom = false;
-
- static readonly List s_Graphics = new List();
- SerializedProperty _spMaskInteraction;
- List tmpMasks = new List();
- static GUIContent s_MaskWarning;
-
private void OnEnable()
{
_spMaskInteraction = serializedObject.FindProperty("m_MaskInteraction");
_custom = (maskInteraction == MaskInteraction.Custom);
- s_MaskWarning = new GUIContent(EditorGUIUtility.FindTexture("console.warnicon.sml"),
- "This is not a SoftMask component.");
- }
+ if (s_MaskWarning == null)
+ {
+ s_MaskWarning = new GUIContent(EditorGUIUtility.FindTexture("console.warnicon.sml"), "This is not a SoftMask component.");
+ }
+ }
private void DrawMaskInteractions()
{
var softMaskable = target as SoftMaskable;
if (softMaskable == null) return;
- softMaskable.GetComponentsInParent(true, tmpMasks);
- tmpMasks.RemoveAll(x => !x.enabled);
- tmpMasks.Reverse();
+ softMaskable.GetComponentsInParent(true, s_TmpMasks);
+ s_TmpMasks.RemoveAll(x => !x.enabled);
+ s_TmpMasks.Reverse();
maskInteraction = (MaskInteraction) EditorGUILayout.EnumPopup("Mask Interaction", maskInteraction);
if (!_custom) return;
@@ -80,10 +75,10 @@ namespace Coffee.UISoftMask
using (var ccs = new EditorGUI.ChangeCheckScope())
{
- int intr0 = DrawMaskInteraction(0);
- int intr1 = DrawMaskInteraction(1);
- int intr2 = DrawMaskInteraction(2);
- int intr3 = DrawMaskInteraction(3);
+ var intr0 = DrawMaskInteraction(0);
+ var intr1 = DrawMaskInteraction(1);
+ var intr2 = DrawMaskInteraction(2);
+ var intr3 = DrawMaskInteraction(3);
if (ccs.changed)
{
@@ -94,24 +89,24 @@ namespace Coffee.UISoftMask
EditorGUIUtility.labelWidth = l;
}
-
private int DrawMaskInteraction(int layer)
{
- Mask mask = layer < tmpMasks.Count ? tmpMasks[layer] : null;
- MaskIntr intr = (MaskIntr) ((_spMaskInteraction.intValue >> layer * 2) & 0x3);
+ var mask = layer < s_TmpMasks.Count ? s_TmpMasks[layer] : null;
+ var intr = (MaskIntr) ((_spMaskInteraction.intValue >> layer * 2) & 0x3);
if (!mask)
{
return (int) intr;
}
- using (new EditorGUILayout.HorizontalScope())
- {
- EditorGUILayout.LabelField(mask is SoftMask ? GUIContent.none : s_MaskWarning, GUILayout.Width(16));
- GUILayout.Space(-5);
- EditorGUILayout.ObjectField("Mask " + layer, mask, typeof(Mask), false);
- GUILayout.Space(-15);
- return (int) (MaskIntr) EditorGUILayout.EnumPopup(intr);
- }
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField(mask is SoftMask ? GUIContent.none : s_MaskWarning, GUILayout.Width(16));
+ GUILayout.Space(-5);
+ EditorGUILayout.ObjectField("Mask " + layer, mask, typeof(Mask), false);
+ GUILayout.Space(-15);
+ intr = (MaskIntr) EditorGUILayout.EnumPopup(intr);
+ GUILayout.EndHorizontal();
+
+ return (int) intr;
}
public override void OnInspectorGUI()
@@ -124,61 +119,20 @@ namespace Coffee.UISoftMask
serializedObject.ApplyModifiedProperties();
var current = target as SoftMaskable;
+ if (current == null) return;
- current.GetComponentsInChildren(true, s_Graphics);
- var fixTargets = s_Graphics.Where(x =>
- x.gameObject != current.gameObject && !x.GetComponent() &&
- (!x.GetComponent() || x.GetComponent().showMaskGraphic)).ToList();
- if (0 < fixTargets.Count)
+ var mask = current.softMask;
+ if (mask) return;
+
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.HelpBox("This is unnecessary SoftMaskable.\nCan't find any SoftMask components above.", MessageType.Warning);
+ if (GUILayout.Button("Remove", GUILayout.Height(40)))
{
- GUILayout.BeginHorizontal();
- EditorGUILayout.HelpBox(
- "There are child Graphics that does not have a SoftMaskable component.\nAdd SoftMaskable component to them.",
- MessageType.Warning);
- GUILayout.BeginVertical();
- if (GUILayout.Button("Fix"))
- {
- foreach (var p in fixTargets)
- {
- p.gameObject.AddComponent();
- }
- }
-
- if (GUILayout.Button("Ping"))
- {
- EditorGUIUtility.PingObject(fixTargets[0]);
- }
-
- GUILayout.EndVertical();
- GUILayout.EndHorizontal();
+ DestroyImmediate(current);
+ EditorUtils.MarkPrefabDirty();
}
- if (!DetectMask(current.transform.parent))
- {
- GUILayout.BeginHorizontal();
- EditorGUILayout.HelpBox("This is unnecessary SoftMaskable.\nCan't find any SoftMask components above.",
- MessageType.Warning);
- if (GUILayout.Button("Remove", GUILayout.Height(40)))
- {
- DestroyImmediate(current);
-
- EditorUtils.MarkPrefabDirty();
- }
-
- GUILayout.EndHorizontal();
- }
- }
-
- static bool DetectMask(Transform transform)
- {
- while (transform)
- {
- if (transform.GetComponent()) return true;
-
- transform = transform.parent;
- }
-
- return false;
+ GUILayout.EndHorizontal();
}
}
}
diff --git a/Scripts/GraphicConnector.cs b/Scripts/GraphicConnector.cs
index a437335..1627f5f 100644
--- a/Scripts/GraphicConnector.cs
+++ b/Scripts/GraphicConnector.cs
@@ -17,9 +17,20 @@ namespace Coffee.UISoftMask
GraphicConnector.FindConnector(graphic).SetMaterialDirty(graphic);
}
- public static Shader FindEffectShader(this Graphic graphic)
+ public static T GetComponentInParentEx(this Component component, bool includeInactive = false) where T : MonoBehaviour
{
- return GraphicConnector.FindConnector(graphic).FindEffectShader(graphic);
+ if (!component) return null;
+ var trans = component.transform;
+
+ while (trans)
+ {
+ var c = trans.GetComponent();
+ if (c && (includeInactive || c.isActiveAndEnabled)) return c;
+
+ trans = trans.parent;
+ }
+
+ return null;
}
}
@@ -27,10 +38,7 @@ namespace Coffee.UISoftMask
public class GraphicConnector
{
private static readonly List s_Connectors = new List();
-
- private static readonly Dictionary s_ConnectorMap =
- new Dictionary();
-
+ private static readonly Dictionary s_ConnectorMap = new Dictionary();
private static readonly GraphicConnector s_EmptyConnector = new GraphicConnector();
#if UNITY_EDITOR
@@ -75,15 +83,6 @@ namespace Coffee.UISoftMask
get { return -1; }
}
-
- ///
- /// Find effect shader.
- ///
- public virtual Shader FindEffectShader(Graphic graphic)
- {
- return Shader.Find("Hidden/UI/SoftMaskable");
- }
-
///
/// The connector is valid for the component.
///
diff --git a/Scripts/MaterialCache.cs b/Scripts/MaterialCache.cs
index 055abb2..47b80e4 100644
--- a/Scripts/MaterialCache.cs
+++ b/Scripts/MaterialCache.cs
@@ -1,42 +1,44 @@
using System.Collections.Generic;
using System;
using UnityEngine;
-using UnityEngine.UI;
namespace Coffee.UISoftMask
{
- internal class MaterialCache
+ internal class MaterialEntry
{
- public delegate void ModifyAction(Material material, Graphic graphic);
+ public Material material;
+ public int referenceCount;
- static Dictionary materialMap = new Dictionary();
-
- private class MaterialEntry
+ public void Release()
{
- public Material material;
- public int referenceCount;
-
- public void Release()
+ if (material)
{
- if (material)
- {
+#if UNITY_EDITOR
+ if (!Application.isPlaying)
UnityEngine.Object.DestroyImmediate(material, false);
- }
-
- material = null;
+ else
+#endif
+ UnityEngine.Object.Destroy(material);
}
+
+ material = null;
}
+ }
+
+ internal static class MaterialCache
+ {
+ static readonly Dictionary s_MaterialMap = new Dictionary();
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoadMethod]
private static void ClearCache()
{
- foreach (var entry in materialMap.Values)
+ foreach (var entry in s_MaterialMap.Values)
{
entry.Release();
}
- materialMap.Clear();
+ s_MaterialMap.Clear();
}
#endif
@@ -45,7 +47,7 @@ namespace Coffee.UISoftMask
if (!hash.isValid) return null;
MaterialEntry entry;
- if (!materialMap.TryGetValue(hash, out entry))
+ if (!s_MaterialMap.TryGetValue(hash, out entry))
{
entry = new MaterialEntry()
{
@@ -56,7 +58,7 @@ namespace Coffee.UISoftMask
};
onModify(entry.material);
- materialMap.Add(hash, entry);
+ s_MaterialMap.Add(hash, entry);
}
entry.referenceCount++;
@@ -67,13 +69,13 @@ namespace Coffee.UISoftMask
public static void Unregister(Hash128 hash)
{
MaterialEntry entry;
- if (!hash.isValid || !materialMap.TryGetValue(hash, out entry)) return;
+ if (!hash.isValid || !s_MaterialMap.TryGetValue(hash, out entry)) return;
//Debug.LogFormat("Unregister: {0}, {1}", hash, entry.referenceCount -1);
if (--entry.referenceCount > 0) return;
entry.Release();
- materialMap.Remove(hash);
+ s_MaterialMap.Remove(hash);
//Debug.LogFormat("Unregister: Release Emtry: {0}, {1} (Total: {2})", hash, entry.referenceCount, materialMap.Count);
}
}
diff --git a/Scripts/SoftMask.cs b/Scripts/SoftMask.cs
index 4c38ebb..3fc612c 100644
--- a/Scripts/SoftMask.cs
+++ b/Scripts/SoftMask.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;
@@ -25,7 +24,7 @@ namespace Coffee.UISoftMask
x8 = 8,
}
- static readonly List[] s_TmpSoftMasks = new List[]
+ private static readonly List[] s_TmpSoftMasks = new List[]
{
new List(),
new List(),
@@ -33,7 +32,7 @@ namespace Coffee.UISoftMask
new List(),
};
- static readonly Color[] s_ClearColors = new Color[]
+ private static readonly Color[] s_ClearColors = new Color[]
{
new Color(0, 0, 0, 0),
new Color(1, 0, 0, 0),
@@ -41,50 +40,49 @@ namespace Coffee.UISoftMask
new Color(1, 1, 1, 0),
};
- static bool s_UVStartsAtTop;
-
- static Shader s_SoftMaskShader;
- static Texture2D s_ReadTexture;
- static readonly List s_ActiveSoftMasks = new List();
- static readonly List s_TempRelatables = new List();
- static readonly Dictionary s_previousViewProjectionMatrices = new Dictionary();
- static readonly Dictionary s_nowViewProjectionMatrices = new Dictionary();
- static int s_StencilCompId;
- static int s_ColorMaskId;
- static int s_MainTexId;
- static int s_SoftnessId;
- static int s_GameVPId;
- static int s_GameTVPId;
- static int s_Alpha;
- MaterialPropertyBlock _mpb;
- CommandBuffer _cb;
- Material _material;
- RenderTexture _softMaskBuffer;
- int _stencilDepth;
- Mesh _mesh;
- SoftMask _parent;
- readonly List _children = new List();
- bool _hasChanged = false;
- bool _hasStencilStateChanged = false;
+ private static bool s_UVStartsAtTop;
+ private static Shader s_SoftMaskShader;
+ private static Texture2D s_ReadTexture;
+ private static readonly List s_ActiveSoftMasks = new List();
+ private static readonly List s_TempRelatables = new List();
+ private static readonly Dictionary s_PreviousViewProjectionMatrices = new Dictionary();
+ private static readonly Dictionary s_NowViewProjectionMatrices = new Dictionary();
+ private static int s_StencilCompId;
+ private static int s_ColorMaskId;
+ private static int s_MainTexId;
+ private static int s_SoftnessId;
+ private static int s_GameVPId;
+ private static int s_GameTVPId;
+ private static int s_Alpha;
+ private MaterialPropertyBlock _mpb;
+ private CommandBuffer _cb;
+ private Material _material;
+ private RenderTexture _softMaskBuffer;
+ private int _stencilDepth;
+ private Mesh _mesh;
+ private SoftMask _parent;
+ internal readonly List _children = new List();
+ private bool _hasChanged = false;
+ private bool _hasStencilStateChanged = false;
- [Tooltip("The desampling rate for soft mask buffer.")] [SerializeField]
- DesamplingRate m_DesamplingRate = DesamplingRate.None;
+ [SerializeField, Tooltip("The desampling rate for soft mask buffer.")]
+ private DesamplingRate m_DesamplingRate = DesamplingRate.None;
- [Tooltip(
- "The value used by the soft mask to select the area of influence defined over the soft mask's graphic.")]
- [SerializeField]
- [Range(0.01f, 1)]
- float m_Softness = 1;
+ [SerializeField, Range(0.01f, 1), Tooltip("The value used by the soft mask to select the area of influence defined over the soft mask's graphic.")]
+ private float m_Softness = 1;
- [Tooltip("The transparency of the whole masked graphic.")] [SerializeField] [Range(0f, 1f)]
- float m_Alpha = 1;
+ [SerializeField, Range(0f, 1f), Tooltip("The transparency of the whole masked graphic.")]
+ private float m_Alpha = 1;
- [Tooltip("Should the soft mask ignore parent soft masks?")] [SerializeField]
- bool m_IgnoreParent = false;
+ [SerializeField, Tooltip("Should the soft mask ignore parent soft masks?")]
+ private bool m_IgnoreParent = false;
- [Tooltip("Is the soft mask a part of parent soft mask?")] [SerializeField]
- bool m_PartOfParent = false;
+ [SerializeField, Tooltip("Is the soft mask a part of parent soft mask?")]
+ private bool m_PartOfParent = false;
+
+ [SerializeField, Tooltip("Self Graphic will not be drawn to soft mask buffer.")]
+ private bool m_IgnoreSelfGraphic;
///
@@ -214,6 +212,19 @@ namespace Coffee.UISoftMask
get { return _parent; }
}
+ public bool ignoreSelfGraphic
+ {
+ get { return m_IgnoreSelfGraphic; }
+ set
+ {
+ if (m_IgnoreSelfGraphic == value) return;
+ m_IgnoreSelfGraphic = value;
+ hasChanged = true;
+ graphic.SetVerticesDirtyEx();
+ }
+ }
+
+
Material material
{
get
@@ -267,7 +278,15 @@ namespace Coffee.UISoftMask
void IMeshModifier.ModifyMesh(VertexHelper verts)
{
if (isActiveAndEnabled)
+ {
+ if (ignoreSelfGraphic)
+ {
+ verts.Clear();
+ }
+
verts.FillMesh(mesh);
+ }
+
hasChanged = true;
}
@@ -336,7 +355,7 @@ namespace Coffee.UISoftMask
_mpb = new MaterialPropertyBlock();
_cb = new CommandBuffer();
- graphic.SetVerticesDirty();
+ graphic.SetVerticesDirtyEx();
base.OnEnable();
_hasStencilStateChanged = false;
@@ -411,7 +430,8 @@ namespace Coffee.UISoftMask
///
protected override void OnValidate()
{
- graphic.SetMaterialDirty();
+ graphic.SetVerticesDirtyEx();
+ graphic.SetMaterialDirtyEx();
OnTransformParentChanged();
base.OnValidate();
_hasStencilStateChanged = false;
@@ -441,8 +461,8 @@ namespace Coffee.UISoftMask
var nowVP = cam.projectionMatrix * cam.worldToCameraMatrix;
var previousVP = default(Matrix4x4);
var id = cam.GetInstanceID();
- s_previousViewProjectionMatrices.TryGetValue(id, out previousVP);
- s_nowViewProjectionMatrices[id] = nowVP;
+ s_PreviousViewProjectionMatrices.TryGetValue(id, out previousVP);
+ s_NowViewProjectionMatrices[id] = nowVP;
if (previousVP != nowVP)
{
@@ -478,13 +498,13 @@ namespace Coffee.UISoftMask
MaskUtilities.NotifyStencilStateChanged(sm);
}
- s_previousViewProjectionMatrices.Clear();
- foreach (var id in s_nowViewProjectionMatrices.Keys)
+ s_PreviousViewProjectionMatrices.Clear();
+ foreach (var id in s_NowViewProjectionMatrices.Keys)
{
- s_previousViewProjectionMatrices[id] = s_nowViewProjectionMatrices[id];
+ s_PreviousViewProjectionMatrices[id] = s_NowViewProjectionMatrices[id];
}
- s_nowViewProjectionMatrices.Clear();
+ s_NowViewProjectionMatrices.Clear();
}
///
diff --git a/Scripts/SoftMaskable.cs b/Scripts/SoftMaskable.cs
index 2be2cbc..4cb0f7b 100755
--- a/Scripts/SoftMaskable.cs
+++ b/Scripts/SoftMaskable.cs
@@ -15,40 +15,37 @@ namespace Coffee.UISoftMask
#else
[ExecuteInEditMode]
# endif
+ [RequireComponent(typeof(Graphic))]
public class SoftMaskable : MonoBehaviour, IMaterialModifier, ICanvasRaycastFilter
#if UNITY_EDITOR
, ISerializationCallbackReceiver
# endif
{
- const int kVisibleInside = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6);
- const int kVisibleOutside = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6);
- static readonly Hash128 k_InvalidHash = new Hash128();
+ private const int kVisibleInside = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6);
+ private const int kVisibleOutside = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6);
+ private static readonly Hash128 k_InvalidHash = new Hash128();
- static int s_SoftMaskTexId;
- static int s_StencilCompId;
- static int s_MaskInteractionId;
- static List s_ActiveSoftMaskables;
- static int[] s_Interactions = new int[4];
+ private static int s_SoftMaskTexId;
+ private static int s_StencilCompId;
+ private static int s_MaskInteractionId;
+ private static List s_ActiveSoftMaskables;
+ private static int[] s_Interactions = new int[4];
- [Tooltip("The graphic will be visible only in areas where no mask is present.")]
- [System.Obsolete]
- [HideInInspector]
- [SerializeField]
- bool m_Inverse = false;
+ [SerializeField, HideInInspector, System.Obsolete]
+ private bool m_Inverse;
- [Tooltip("The interaction for each masks.")] [HideInInspector] [SerializeField]
- int m_MaskInteraction = kVisibleInside;
+ [SerializeField, Tooltip("The interaction for each masks."), HideInInspector]
+ private int m_MaskInteraction = kVisibleInside;
- [Tooltip("Use stencil to mask.")] [SerializeField]
- bool m_UseStencil = false;
+ [SerializeField, Tooltip("Use stencil to mask.")]
+ private bool m_UseStencil;
- [Tooltip("Use soft-masked raycast target.\n\nNote: This option is expensive.")] [SerializeField]
- bool m_RaycastFilter = false;
+ [SerializeField, Tooltip("Use soft-masked raycast target.\n\nNote: This option is expensive.")]
+ private bool m_RaycastFilter;
- Graphic _graphic = null;
- SoftMask _softMask = null;
- Material _maskMaterial = null;
- Hash128 _effectMaterialHash;
+ private Graphic _graphic;
+ private SoftMask _softMask;
+ private Hash128 _effectMaterialHash;
///
/// The graphic will be visible only in areas where no mask is present.
@@ -82,6 +79,11 @@ namespace Coffee.UISoftMask
get { return _graphic ? _graphic : _graphic = GetComponent(); }
}
+ public SoftMask softMask
+ {
+ get { return _softMask ? _softMask : _softMask = this.GetComponentInParentEx(); }
+ }
+
///
/// Perform material modification in this function.
///
@@ -98,27 +100,13 @@ namespace Coffee.UISoftMask
// If this component is disabled, the material is returned as is.
if (!isActiveAndEnabled) return baseMaterial;
- // Find the nearest parent softmask.
- var parentTransform = transform.parent;
- while (parentTransform)
- {
- var sm = parentTransform.GetComponent();
- if (sm && sm.enabled)
- {
- _softMask = sm;
- break;
- }
-
- parentTransform = parentTransform.parent;
- }
-
// If the parents do not have a soft mask component, the material is returned as is.
- if (!_softMask) return baseMaterial;
+ if (!softMask) return baseMaterial;
// Generate soft maskable material.
_effectMaterialHash = new Hash128(
(uint) baseMaterial.GetInstanceID(),
- (uint) _softMask.GetInstanceID(),
+ (uint) softMask.GetInstanceID(),
(uint) m_MaskInteraction,
(uint) (m_UseStencil ? 1 : 0)
);
@@ -130,7 +118,7 @@ namespace Coffee.UISoftMask
#if UNITY_EDITOR
mat.EnableKeyword("SOFTMASK_EDITOR");
#endif
- mat.SetTexture(s_SoftMaskTexId, _softMask.softMaskBuffer);
+ mat.SetTexture(s_SoftMaskTexId, softMask.softMaskBuffer);
mat.SetInt(s_StencilCompId,
m_UseStencil ? (int) CompareFunction.Equal : (int) CompareFunction.Always);
mat.SetVector(s_MaskInteractionId, new Vector4(
@@ -140,7 +128,6 @@ namespace Coffee.UISoftMask
((m_MaskInteraction >> 6) & 0x3)
));
});
- _maskMaterial = modifiedMaterial;
return modifiedMaterial;
}
@@ -153,21 +140,45 @@ namespace Coffee.UISoftMask
/// Raycast camera.
bool ICanvasRaycastFilter.IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
- if (!isActiveAndEnabled || !_softMask)
+ if (!isActiveAndEnabled || !softMask)
return true;
if (!RectTransformUtility.RectangleContainsScreenPoint(transform as RectTransform, sp, eventCamera))
return false;
- if (!m_RaycastFilter)
- return true;
- var sm = _softMask;
- for (var i = 0; i < 4; i++)
+ if (m_RaycastFilter)
{
- s_Interactions[i] = sm ? ((m_MaskInteraction >> i * 2) & 0x3) : 0;
- sm = sm ? sm.parent : null;
- }
+ var sm = _softMask;
+ for (var i = 0; i < 4; i++)
+ {
+ s_Interactions[i] = sm ? ((m_MaskInteraction >> i * 2) & 0x3) : 0;
+ sm = sm ? sm.parent : null;
+ }
- return _softMask.IsRaycastLocationValid(sp, eventCamera, graphic, s_Interactions);
+ return _softMask.IsRaycastLocationValid(sp, eventCamera, graphic, s_Interactions);
+ }
+ else
+ {
+ var sm = _softMask;
+ for (var i = 0; i < 4; i++)
+ {
+ if (!sm) break;
+ s_Interactions[i] = sm ? ((m_MaskInteraction >> i * 2) & 0x3) : 0;
+ var interaction = s_Interactions[i] == 1;
+ var inRect = RectTransformUtility.RectangleContainsScreenPoint(sm.transform as RectTransform, sp, eventCamera);
+ if (!sm.ignoreSelfGraphic && interaction != inRect) return false;
+
+ foreach (var child in sm._children)
+ {
+ if (!child) break;
+ var inRectChild = RectTransformUtility.RectangleContainsScreenPoint(child.transform as RectTransform, sp, eventCamera);
+ if (!child.ignoreSelfGraphic && interaction != inRectChild) return false;
+ }
+
+ sm = sm ? sm.parent : null;
+ }
+
+ return true;
+ }
}
///
@@ -243,7 +254,7 @@ namespace Coffee.UISoftMask
if (m_Inverse)
{
m_Inverse = false;
- m_MaskInteraction = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6);
+ m_MaskInteraction = kVisibleOutside;
}
#pragma warning restore 0612
diff --git a/package.json b/package.json
index 0dde190..4e4cbca 100644
--- a/package.json
+++ b/package.json
@@ -1,29 +1,34 @@
{
- "name": "com.coffee.softmask-for-ugui",
- "displayName": "UI Soft Mask",
- "description": "UI Soft Mask is a smooth masking component for Unity UI (uGUI) elements.\nBy using SoftMask instead of the default Mask component, you can beautifully represent the rounded edges of UI elements.",
- "version": "1.0.0-preview.2",
- "unity": "2017.1",
- "license": "MIT",
- "repository": {
- "type": "git",
- "url": "git+https://github.com/mob-sakai/SoftMaskForUGUI.git"
- },
- "author": {
- "name": "mob-sakai",
- "email": "sakai861104@gmail.com",
- "url": "https://github.com/mob-sakai"
- },
- "dependencies": {},
- "keywords": [
- "ui",
- "softmask"
- ],
- "samples": [
- {
- "displayName": "Demo",
- "description": "UI Soft Mask Demo",
- "path": "Samples~/Demo"
- }
- ]
+ "name": "com.coffee.softmask-for-ugui",
+ "displayName": "UI Soft Mask",
+ "description": "UI Soft Mask is a smooth masking component for Unity UI (uGUI) elements.\nBy using SoftMask instead of the default Mask component, you can beautifully represent the rounded edges of UI elements.",
+ "version": "1.0.0-preview.3",
+ "unity": "2017.1",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/mob-sakai/SoftMaskForUGUI.git"
+ },
+ "author": {
+ "name": "mob-sakai",
+ "email": "sakai861104@gmail.com",
+ "url": "https://github.com/mob-sakai"
+ },
+ "dependencies": {},
+ "keywords": [
+ "ui",
+ "softmask"
+ ],
+ "samples": [
+ {
+ "displayName": "Demo",
+ "description": "UI Soft Mask Demo",
+ "path": "Samples~/Demo"
+ },
+ {
+ "displayName": "TextMeshPro Support",
+ "description": "TextMeshPro Support",
+ "path": "Samples~/TextMeshPro Support"
+ }
+ ]
}