refactor: refactor
parent
0347b04fb7
commit
e65bbb1cef
|
@ -32,27 +32,27 @@ namespace Coffee.UISoftMask.Demos
|
|||
|
||||
public void SetWorldSpase(bool flag)
|
||||
{
|
||||
if(flag)
|
||||
if (flag)
|
||||
{
|
||||
GetComponent<Canvas> ().renderMode = RenderMode.ScreenSpaceCamera;
|
||||
GetComponent<Canvas> ().renderMode = RenderMode.WorldSpace;
|
||||
transform.rotation = Quaternion.Euler (new Vector3 (0, 6, 0));
|
||||
GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceCamera;
|
||||
GetComponent<Canvas>().renderMode = RenderMode.WorldSpace;
|
||||
transform.rotation = Quaternion.Euler(new Vector3(0, 6, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetScreenSpase (bool flag)
|
||||
public void SetScreenSpase(bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
GetComponent<Canvas> ().renderMode = RenderMode.ScreenSpaceCamera;
|
||||
GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceCamera;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetOverlay (bool flag)
|
||||
public void SetOverlay(bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
GetComponent<Canvas> ().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,57 @@
|
|||
#if UNITY_2018_3_OR_NEWER
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
#endif
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Coffee.UISoftMask
|
||||
{
|
||||
public static class EditorUtils
|
||||
internal static class EditorUtils
|
||||
{
|
||||
public static void MarkPrefabDirty ()
|
||||
internal static void MarkPrefabDirty()
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage ();
|
||||
if (prefabStage != null)
|
||||
{
|
||||
EditorSceneManager.MarkSceneDirty (prefabStage.scene);
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
if (prefabStage == null) return;
|
||||
EditorSceneManager.MarkSceneDirty(prefabStage.scene);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Verify whether it can be converted to the specified component.
|
||||
/// </summary>
|
||||
internal static bool CanConvertTo<T>(Object context) where T : MonoBehaviour
|
||||
{
|
||||
return context && context.GetType() != typeof(T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert to the specified component.
|
||||
/// </summary>
|
||||
internal static void ConvertTo<T>(Object context) where T : MonoBehaviour
|
||||
{
|
||||
var target = context as MonoBehaviour;
|
||||
var so = new SerializedObject(target);
|
||||
so.Update();
|
||||
|
||||
bool oldEnable = target.enabled;
|
||||
target.enabled = false;
|
||||
|
||||
// Find MonoScript of the specified component.
|
||||
foreach (var script in Resources.FindObjectsOfTypeAll<MonoScript>())
|
||||
{
|
||||
if (script.GetClass() != typeof(T))
|
||||
continue;
|
||||
|
||||
// Set 'm_Script' to convert.
|
||||
so.FindProperty("m_Script").objectReferenceValue = script;
|
||||
so.ApplyModifiedProperties();
|
||||
break;
|
||||
}
|
||||
|
||||
(so.targetObject as MonoBehaviour).enabled = oldEnable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,58 +15,67 @@ namespace Coffee.UISoftMask
|
|||
public class SoftMaskEditor : Editor
|
||||
{
|
||||
const string k_PrefsPreview = "SoftMaskEditor_Preview";
|
||||
static readonly List<Graphic> s_Graphics = new List<Graphic> ();
|
||||
static readonly List<Graphic> s_Graphics = new List<Graphic>();
|
||||
static bool s_Preview;
|
||||
|
||||
private void OnEnable ()
|
||||
private void OnEnable()
|
||||
{
|
||||
s_Preview = EditorPrefs.GetBool (k_PrefsPreview, false);
|
||||
s_Preview = EditorPrefs.GetBool(k_PrefsPreview, false);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI ()
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI ();
|
||||
base.OnInspectorGUI();
|
||||
|
||||
var current = target as SoftMask;
|
||||
current.GetComponentsInChildren<Graphic> (true, s_Graphics);
|
||||
var fixTargets = s_Graphics.Where (x => x.gameObject != current.gameObject && !x.GetComponent<SoftMaskable> () && (!x.GetComponent<Mask> () || x.GetComponent<Mask> ().showMaskGraphic)).ToList ();
|
||||
current.GetComponentsInChildren<Graphic>(true, s_Graphics);
|
||||
var fixTargets = s_Graphics.Where(x =>
|
||||
x.gameObject != current.gameObject && !x.GetComponent<SoftMaskable>() &&
|
||||
(!x.GetComponent<Mask>() || x.GetComponent<Mask>().showMaskGraphic)).ToList();
|
||||
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);
|
||||
GUILayout.BeginVertical ();
|
||||
if (GUILayout.Button ("Fix"))
|
||||
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<SoftMaskable> ();
|
||||
p.gameObject.AddComponent<SoftMaskable>();
|
||||
}
|
||||
|
||||
EditorUtils.MarkPrefabDirty ();
|
||||
EditorUtils.MarkPrefabDirty();
|
||||
}
|
||||
if (GUILayout.Button ("Ping"))
|
||||
|
||||
if (GUILayout.Button("Ping"))
|
||||
{
|
||||
EditorGUIUtility.PingObject (fixTargets[0]);
|
||||
EditorGUIUtility.PingObject(fixTargets[0]);
|
||||
}
|
||||
GUILayout.EndVertical ();
|
||||
GUILayout.EndHorizontal ();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
// Preview buffer.
|
||||
GUILayout.BeginHorizontal (EditorStyles.helpBox);
|
||||
if (s_Preview != (s_Preview = EditorGUILayout.ToggleLeft ("Preview Buffer", s_Preview, GUILayout.MaxWidth (EditorGUIUtility.labelWidth))))
|
||||
GUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
if (s_Preview != (s_Preview = EditorGUILayout.ToggleLeft("Preview Buffer", s_Preview,
|
||||
GUILayout.MaxWidth(EditorGUIUtility.labelWidth))))
|
||||
{
|
||||
EditorPrefs.SetBool (k_PrefsPreview, s_Preview);
|
||||
EditorPrefs.SetBool(k_PrefsPreview, s_Preview);
|
||||
}
|
||||
|
||||
if (s_Preview)
|
||||
{
|
||||
var tex = current.softMaskBuffer;
|
||||
var width = tex.width * 64 / tex.height;
|
||||
EditorGUI.DrawPreviewTexture (GUILayoutUtility.GetRect (width, 64), tex, null, ScaleMode.ScaleToFit);
|
||||
Repaint ();
|
||||
EditorGUI.DrawPreviewTexture(GUILayoutUtility.GetRect(width, 64), tex, null, ScaleMode.ScaleToFit);
|
||||
Repaint();
|
||||
}
|
||||
GUILayout.FlexibleSpace ();
|
||||
GUILayout.EndHorizontal ();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
|
@ -74,61 +83,25 @@ namespace Coffee.UISoftMask
|
|||
[MenuItem("CONTEXT/Mask/Convert To SoftMask", true)]
|
||||
static bool _ConvertToSoftMask(MenuCommand command)
|
||||
{
|
||||
return CanConvertTo<SoftMask>(command.context);
|
||||
return EditorUtils.CanConvertTo<SoftMask>(command.context);
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/Mask/Convert To SoftMask", false)]
|
||||
static void ConvertToSoftMask(MenuCommand command)
|
||||
{
|
||||
ConvertTo<SoftMask>(command.context);
|
||||
EditorUtils.ConvertTo<SoftMask>(command.context);
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/Mask/Convert To Mask", true)]
|
||||
static bool _ConvertToMask(MenuCommand command)
|
||||
{
|
||||
return CanConvertTo<Mask>(command.context);
|
||||
return EditorUtils.CanConvertTo<Mask>(command.context);
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/Mask/Convert To Mask", false)]
|
||||
static void ConvertToMask(MenuCommand command)
|
||||
{
|
||||
ConvertTo<Mask>(command.context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify whether it can be converted to the specified component.
|
||||
/// </summary>
|
||||
protected static bool CanConvertTo<T>(Object context)
|
||||
where T : MonoBehaviour
|
||||
{
|
||||
return context && context.GetType() != typeof(T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert to the specified component.
|
||||
/// </summary>
|
||||
protected static void ConvertTo<T>(Object context) where T : MonoBehaviour
|
||||
{
|
||||
var target = context as MonoBehaviour;
|
||||
var so = new SerializedObject(target);
|
||||
so.Update();
|
||||
|
||||
bool oldEnable = target.enabled;
|
||||
target.enabled = false;
|
||||
|
||||
// Find MonoScript of the specified component.
|
||||
foreach (var script in Resources.FindObjectsOfTypeAll<MonoScript>())
|
||||
{
|
||||
if (script.GetClass() != typeof(T))
|
||||
continue;
|
||||
|
||||
// Set 'm_Script' to convert.
|
||||
so.FindProperty("m_Script").objectReferenceValue = script;
|
||||
so.ApplyModifiedProperties();
|
||||
break;
|
||||
}
|
||||
|
||||
(so.targetObject as MonoBehaviour).enabled = oldEnable;
|
||||
EditorUtils.ConvertTo<Mask>(command.context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,10 @@ namespace Coffee.UISoftMask
|
|||
/// <summary>
|
||||
/// SoftMaskable editor.
|
||||
/// </summary>
|
||||
[CustomEditor (typeof (SoftMaskable))]
|
||||
[CustomEditor(typeof(SoftMaskable))]
|
||||
[CanEditMultipleObjects]
|
||||
public class SoftMaskableEditor : Editor
|
||||
{
|
||||
//################################
|
||||
// Constant or Static Members.
|
||||
//################################
|
||||
public enum MaskInteraction : int
|
||||
{
|
||||
VisibleInsideMask = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6),
|
||||
|
@ -36,7 +33,7 @@ namespace Coffee.UISoftMask
|
|||
return _custom
|
||||
? MaskInteraction.Custom
|
||||
: System.Enum.IsDefined(typeof(MaskInteraction), value)
|
||||
? (MaskInteraction)value
|
||||
? (MaskInteraction) value
|
||||
: MaskInteraction.Custom;
|
||||
}
|
||||
set
|
||||
|
@ -44,77 +41,40 @@ namespace Coffee.UISoftMask
|
|||
_custom = (value == MaskInteraction.Custom);
|
||||
if (!_custom)
|
||||
{
|
||||
_spMaskInteraction.intValue = (int)value;
|
||||
_spMaskInteraction.intValue = (int) value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _custom = false;
|
||||
|
||||
static readonly Type s_TypeTMPro = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_Text");
|
||||
static readonly Type s_TypeTMP_SpriteAsset = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_SpriteAsset");
|
||||
static readonly Type s_TypeTMProSettings = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_Settings");
|
||||
static readonly Type s_TypeTMP_SubMesh = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_SubMesh");
|
||||
static readonly Type s_TypeTMP_SubMeshUI = AppDomain.CurrentDomain.GetAssemblies ().SelectMany (x => x.GetTypes ()).FirstOrDefault (x => x.Name == "TMP_SubMeshUI");
|
||||
static PropertyInfo s_PiFontSharedMaterial;
|
||||
static PropertyInfo s_PiFontSharedMaterials;
|
||||
static PropertyInfo s_PiSpriteAsset;
|
||||
static PropertyInfo s_PiRichText;
|
||||
static PropertyInfo s_PiText;
|
||||
static PropertyInfo s_PiDefaultFontAssetPath;
|
||||
static PropertyInfo s_PiDefaultSpriteAssetPath;
|
||||
static FieldInfo s_FiMaterial;
|
||||
static MethodInfo s_miGetSpriteAsset;
|
||||
static readonly List<Graphic> s_Graphics = new List<Graphic> ();
|
||||
Shader _shader;
|
||||
Shader _mobileShader;
|
||||
Shader _spriteShader;
|
||||
List<MaterialEditor> _materialEditors = new List<MaterialEditor> ();
|
||||
static readonly List<Graphic> s_Graphics = new List<Graphic>();
|
||||
SerializedProperty _spMaskInteraction;
|
||||
List<Mask> tmpMasks = new List<Mask>();
|
||||
static GUIContent s_MaskWarning;
|
||||
|
||||
void OnEnable ()
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_spMaskInteraction = serializedObject.FindProperty("m_MaskInteraction");
|
||||
_custom = (maskInteraction == MaskInteraction.Custom);
|
||||
|
||||
ClearMaterialEditors ();
|
||||
|
||||
_shader = Shader.Find ("TextMeshPro/Distance Field (SoftMaskable)");
|
||||
_mobileShader = Shader.Find ("TextMeshPro/Mobile/Distance Field (SoftMaskable)");
|
||||
_spriteShader = Shader.Find ("TextMeshPro/Sprite (SoftMaskable)");
|
||||
|
||||
if(s_TypeTMPro != null)
|
||||
{
|
||||
s_PiFontSharedMaterial = s_TypeTMPro.GetProperty ("fontSharedMaterial");
|
||||
s_PiSpriteAsset = s_TypeTMPro.GetProperty ("spriteAsset");
|
||||
s_PiRichText = s_TypeTMPro.GetProperty ("richText");
|
||||
s_PiText = s_TypeTMPro.GetProperty ("text");
|
||||
s_FiMaterial = s_TypeTMP_SpriteAsset.GetField ("material");
|
||||
s_PiFontSharedMaterials = s_TypeTMPro.GetProperty ("fontSharedMaterials");
|
||||
s_miGetSpriteAsset = s_TypeTMProSettings.GetMethod ("GetSpriteAsset", BindingFlags.Static | BindingFlags.Public);
|
||||
|
||||
s_PiDefaultFontAssetPath = s_TypeTMProSettings.GetProperty ("defaultFontAssetPath", BindingFlags.Static | BindingFlags.Public);
|
||||
s_PiDefaultSpriteAssetPath = s_TypeTMProSettings.GetProperty ("defaultSpriteAssetPath", BindingFlags.Static | BindingFlags.Public);
|
||||
s_MaskWarning = new GUIContent(EditorGUIUtility.FindTexture("console.warnicon.sml"),
|
||||
"This is not a SoftMask component.");
|
||||
}
|
||||
|
||||
s_MaskWarning = new GUIContent(EditorGUIUtility.FindTexture("console.warnicon.sml"), "This component is not SoftMask. Use SoftMask instead of Mask.");
|
||||
}
|
||||
|
||||
void OnDisable ()
|
||||
private void DrawMaskInteractions()
|
||||
{
|
||||
ClearMaterialEditors ();
|
||||
}
|
||||
var softMaskable = target as SoftMaskable;
|
||||
if (softMaskable == null) return;
|
||||
|
||||
List<Mask> tmpMasks = new List<Mask>();
|
||||
|
||||
void DrawMaskInteractions()
|
||||
{
|
||||
(target as SoftMaskable).GetComponentsInParent<Mask>(true, tmpMasks);
|
||||
softMaskable.GetComponentsInParent<Mask>(true, tmpMasks);
|
||||
tmpMasks.RemoveAll(x => !x.enabled);
|
||||
tmpMasks.Reverse();
|
||||
|
||||
maskInteraction = (MaskInteraction)EditorGUILayout.EnumPopup("Mask Interaction", maskInteraction);
|
||||
if (_custom)
|
||||
{
|
||||
maskInteraction = (MaskInteraction) EditorGUILayout.EnumPopup("Mask Interaction", maskInteraction);
|
||||
if (!_custom) return;
|
||||
|
||||
var l = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 45;
|
||||
|
||||
|
@ -125,24 +85,23 @@ namespace Coffee.UISoftMask
|
|||
int intr2 = DrawMaskInteraction(2);
|
||||
int intr3 = DrawMaskInteraction(3);
|
||||
|
||||
if (ccs.changed) {
|
||||
if (ccs.changed)
|
||||
{
|
||||
_spMaskInteraction.intValue = (intr0 << 0) + (intr1 << 2) + (intr2 << 4) + (intr3 << 6);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUIUtility.labelWidth = l;
|
||||
}
|
||||
}
|
||||
|
||||
static GUIContent s_MaskWarning = new GUIContent();
|
||||
|
||||
int DrawMaskInteraction(int layer)
|
||||
private int DrawMaskInteraction(int layer)
|
||||
{
|
||||
Mask mask = layer < tmpMasks.Count ? tmpMasks[layer] : null;
|
||||
MaskIntr intr = (MaskIntr)((_spMaskInteraction.intValue >> layer * 2) & 0x3);
|
||||
MaskIntr intr = (MaskIntr) ((_spMaskInteraction.intValue >> layer * 2) & 0x3);
|
||||
if (!mask)
|
||||
{
|
||||
return (int)intr;
|
||||
return (int) intr;
|
||||
}
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
|
@ -151,263 +110,75 @@ namespace Coffee.UISoftMask
|
|||
GUILayout.Space(-5);
|
||||
EditorGUILayout.ObjectField("Mask " + layer, mask, typeof(Mask), false);
|
||||
GUILayout.Space(-15);
|
||||
return (int)(MaskIntr)EditorGUILayout.EnumPopup(intr);
|
||||
return (int) (MaskIntr) EditorGUILayout.EnumPopup(intr);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI ()
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI ();
|
||||
base.OnInspectorGUI();
|
||||
|
||||
serializedObject.Update();
|
||||
DrawMaskInteractions();
|
||||
|
||||
// maskInteraction = (MaskInteraction)EditorGUILayout.EnumPopup("Mask Interaction", maskInteraction);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
/*
|
||||
EditorGUI.indentLevel++;
|
||||
var l = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 60;
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
EditorGUILayout.ObjectField("Mask 0", null, typeof(Mask), false);
|
||||
EditorGUILayout.EnumPopup (MaskIntr.None);
|
||||
}
|
||||
EditorGUIUtility.labelWidth = l;
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
var spMaskInteraction = serializedObject.FindProperty ("m_MaskInteraction");
|
||||
MaskIntr intr0 = (MaskIntr)((spMaskInteraction.intValue >> 0) & 0x3);
|
||||
MaskIntr intr1 = (MaskIntr)((spMaskInteraction.intValue >> 2) & 0x3);
|
||||
MaskIntr intr2 = (MaskIntr)((spMaskInteraction.intValue >> 4) & 0x3);
|
||||
MaskIntr intr3 = (MaskIntr)((spMaskInteraction.intValue >> 6) & 0x3);
|
||||
|
||||
using (var ccs = new EditorGUI.ChangeCheckScope ()) {
|
||||
|
||||
intr0 = (MaskIntr)EditorGUILayout.EnumPopup ("Layer 0", intr0);
|
||||
intr1 = (MaskIntr)EditorGUILayout.EnumPopup ("Layer 1", intr1);
|
||||
intr2 = (MaskIntr)EditorGUILayout.EnumPopup ("Layer 2", intr2);
|
||||
intr3 = (MaskIntr)EditorGUILayout.EnumPopup ("Layer 3", intr3);
|
||||
|
||||
if (ccs.changed) {
|
||||
current.SetMaskInteractions (intr0,intr1,intr2,intr3);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// spMaskInteraction.intValue = (intr0 << 0) | (intr1 << 2) | (intr2 << 4) | (intr3 << 6);
|
||||
//
|
||||
// serializedObject.ApplyModifiedProperties ();
|
||||
|
||||
|
||||
|
||||
var current = target as SoftMaskable;
|
||||
|
||||
current.GetComponentsInChildren<Graphic> (true, s_Graphics);
|
||||
var fixTargets = s_Graphics.Where (x => x.gameObject != current.gameObject && !x.GetComponent<SoftMaskable> () && (!x.GetComponent<Mask> () || x.GetComponent<Mask> ().showMaskGraphic)).ToList ();
|
||||
current.GetComponentsInChildren<Graphic>(true, s_Graphics);
|
||||
var fixTargets = s_Graphics.Where(x =>
|
||||
x.gameObject != current.gameObject && !x.GetComponent<SoftMaskable>() &&
|
||||
(!x.GetComponent<Mask>() || x.GetComponent<Mask>().showMaskGraphic)).ToList();
|
||||
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);
|
||||
GUILayout.BeginVertical ();
|
||||
if (GUILayout.Button ("Fix"))
|
||||
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<SoftMaskable> ();
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button ("Ping"))
|
||||
{
|
||||
EditorGUIUtility.PingObject (fixTargets [0]);
|
||||
}
|
||||
GUILayout.EndVertical ();
|
||||
GUILayout.EndHorizontal ();
|
||||
}
|
||||
|
||||
if(s_TypeTMPro != null)
|
||||
{
|
||||
ShowTMProWarning (_shader, _mobileShader, _spriteShader, m => { });
|
||||
var textMeshPro = current.GetComponent (s_TypeTMPro);
|
||||
if (textMeshPro != null)
|
||||
{
|
||||
Material [] fontSharedMaterials = s_PiFontSharedMaterials.GetValue (textMeshPro, new object [0]) as Material [];
|
||||
ShowMaterialEditors (fontSharedMaterials, 1, fontSharedMaterials.Length - 1);
|
||||
p.gameObject.AddComponent<SoftMaskable>();
|
||||
}
|
||||
}
|
||||
|
||||
if (!DetectMask (current.transform.parent))
|
||||
if (GUILayout.Button("Ping"))
|
||||
{
|
||||
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 ();
|
||||
EditorGUIUtility.PingObject(fixTargets[0]);
|
||||
}
|
||||
GUILayout.EndHorizontal ();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
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)
|
||||
static bool DetectMask(Transform transform)
|
||||
{
|
||||
if (transform == null)
|
||||
while (transform)
|
||||
{
|
||||
if (transform.GetComponent<SoftMask>()) return true;
|
||||
|
||||
transform = transform.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (transform.GetComponent<SoftMask> () != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return DetectMask (transform.parent);
|
||||
}
|
||||
|
||||
void ClearMaterialEditors ()
|
||||
{
|
||||
foreach (var e in _materialEditors)
|
||||
{
|
||||
if (e)
|
||||
{
|
||||
DestroyImmediate (e);
|
||||
}
|
||||
}
|
||||
_materialEditors.Clear ();
|
||||
}
|
||||
|
||||
protected void ShowMaterialEditors (Material [] materials, int startIndex, int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (_materialEditors.Count == i)
|
||||
{
|
||||
_materialEditors.Add (null);
|
||||
}
|
||||
|
||||
var mat = materials [startIndex + i];
|
||||
var editor = _materialEditors [i];
|
||||
if (editor && editor.target != mat)
|
||||
{
|
||||
DestroyImmediate (editor);
|
||||
editor = null;
|
||||
}
|
||||
|
||||
if (!editor)
|
||||
{
|
||||
editor = _materialEditors [i] = Editor.CreateEditor (mat) as MaterialEditor;
|
||||
}
|
||||
|
||||
editor.DrawHeader ();
|
||||
editor.OnInspectorGUI ();
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowTMProWarning (Shader shader, Shader mobileShader, Shader spriteShader, System.Action<Material> onCreatedMaterial)
|
||||
{
|
||||
var current = target as SoftMaskable;
|
||||
var textMeshPro = current.GetComponent (s_TypeTMPro);
|
||||
if (textMeshPro == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Material fontSharedMaterial = s_PiFontSharedMaterial.GetValue (textMeshPro, new object [0]) as Material;
|
||||
if (fontSharedMaterial == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Is the material preset for dissolve?
|
||||
Material m = fontSharedMaterial;
|
||||
if (m.shader != shader && m.shader != mobileShader)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal ();
|
||||
EditorGUILayout.HelpBox (string.Format ("{0} requires '{1}' or '{2}' as a shader for material preset.", current.GetType ().Name, shader.name, mobileShader.name), MessageType.Warning);
|
||||
if (GUILayout.Button ("Fix"))
|
||||
{
|
||||
var correctShader = m.shader.name.Contains ("Mobile") ? mobileShader : shader;
|
||||
m = ModifyTMProMaterialPreset (m, correctShader, onCreatedMaterial);
|
||||
s_PiFontSharedMaterial.SetValue (textMeshPro, m, new object [0]);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal ();
|
||||
return;
|
||||
}
|
||||
|
||||
// Is the sprite asset for dissolve?
|
||||
object spriteAsset = s_PiSpriteAsset.GetValue (textMeshPro, new object [0]) ?? s_miGetSpriteAsset.Invoke (null, new object [0]);
|
||||
//TMP_SpriteAsset spriteAsset = textMeshPro.spriteAsset ?? TMP_Settings.GetSpriteAsset ();
|
||||
m = s_FiMaterial.GetValue (spriteAsset) as Material;
|
||||
bool hasSprite = (bool)s_PiRichText.GetValue (textMeshPro, new object [0]) && (s_PiText.GetValue (textMeshPro, new object [0]) as string).Contains ("<sprite=");
|
||||
if (m && m.shader != spriteShader && hasSprite)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal ();
|
||||
EditorGUILayout.HelpBox (string.Format ("{0} requires '{1}' as a shader for sprite asset.", GetType ().Name, spriteShader.name), MessageType.Warning);
|
||||
if (GUILayout.Button ("Fix"))
|
||||
{
|
||||
current.GetComponentsInChildren (s_TypeTMP_SubMesh).Select (x => x.gameObject).ToList ().ForEach (DestroyImmediate);
|
||||
current.GetComponentsInChildren (s_TypeTMP_SubMeshUI).Select (x => x.gameObject).ToList ().ForEach (DestroyImmediate);
|
||||
spriteAsset = ModifyTMProSpriteAsset (m, _spriteShader, mat => { });
|
||||
s_PiSpriteAsset.SetValue (textMeshPro, spriteAsset, new object [0]);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Material ModifyTMProMaterialPreset (Material baseMaterial, Shader shader, System.Action<Material> onCreatedMaterial)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath (baseMaterial);
|
||||
string filename = Path.GetFileNameWithoutExtension (path) + " (" + typeof (SoftMaskable).Name + ")";
|
||||
string defaultAssetPath = s_PiDefaultFontAssetPath.GetValue (null, new object [0]) as string;
|
||||
Material mat = Resources.Load<Material> (defaultAssetPath + filename);
|
||||
if (!mat)
|
||||
{
|
||||
mat = new Material (baseMaterial)
|
||||
{
|
||||
shaderKeywords = baseMaterial.shaderKeywords,
|
||||
shader = shader,
|
||||
};
|
||||
onCreatedMaterial (mat);
|
||||
AssetDatabase.CreateAsset (mat, Path.GetDirectoryName (path) + "/" + filename + ".mat");
|
||||
|
||||
EditorUtility.FocusProjectWindow ();
|
||||
EditorGUIUtility.PingObject (mat);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.shader = shader;
|
||||
}
|
||||
EditorUtility.SetDirty (mat);
|
||||
return mat;
|
||||
}
|
||||
|
||||
object ModifyTMProSpriteAsset (Material baseMaterial, Shader shader, System.Action<Material> onCreatedMaterial)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath (baseMaterial);
|
||||
string filename = Path.GetFileNameWithoutExtension (path) + " (" + typeof (SoftMaskable).Name + ")";
|
||||
string defaultAssetPath = s_PiDefaultSpriteAssetPath.GetValue (null, new object [0]) as string;
|
||||
Object spriteAsset = Resources.Load (defaultAssetPath + filename, s_TypeTMP_SpriteAsset);
|
||||
if (spriteAsset == null)
|
||||
{
|
||||
AssetDatabase.CopyAsset (path, Path.GetDirectoryName (path) + "/" + filename + ".mat");
|
||||
spriteAsset = Resources.Load (defaultAssetPath + filename, s_TypeTMP_SpriteAsset);
|
||||
Material m = s_FiMaterial.GetValue (spriteAsset) as Material;
|
||||
m.shader = shader;
|
||||
m.name = shader.name;
|
||||
onCreatedMaterial (m);
|
||||
|
||||
EditorUtility.FocusProjectWindow ();
|
||||
EditorGUIUtility.PingObject (spriteAsset);
|
||||
}
|
||||
else
|
||||
{
|
||||
Material m = s_FiMaterial.GetValue (spriteAsset) as Material;
|
||||
m.shader = shader;
|
||||
}
|
||||
EditorUtility.SetDirty (spriteAsset);
|
||||
return spriteAsset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,11 @@ namespace Coffee.UISoftMask
|
|||
|
||||
public class GraphicConnector
|
||||
{
|
||||
|
||||
private static readonly List<GraphicConnector> s_Connectors = new List<GraphicConnector>();
|
||||
private static readonly Dictionary<Type, GraphicConnector> s_ConnectorMap = new Dictionary<Type, GraphicConnector>();
|
||||
|
||||
private static readonly Dictionary<Type, GraphicConnector> s_ConnectorMap =
|
||||
new Dictionary<Type, GraphicConnector>();
|
||||
|
||||
private static readonly GraphicConnector s_EmptyConnector = new GraphicConnector();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
@ -74,7 +76,6 @@ namespace Coffee.UISoftMask
|
|||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Find effect shader.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UI;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Coffee.UISoftMask
|
||||
{
|
||||
|
@ -11,9 +13,6 @@ namespace Coffee.UISoftMask
|
|||
/// </summary>
|
||||
public class SoftMask : Mask, IMeshModifier
|
||||
{
|
||||
//################################
|
||||
// Constant or Static Members.
|
||||
//################################
|
||||
/// <summary>
|
||||
/// Desampling rate.
|
||||
/// </summary>
|
||||
|
@ -44,25 +43,50 @@ namespace Coffee.UISoftMask
|
|||
|
||||
static bool s_UVStartsAtTop;
|
||||
|
||||
|
||||
//################################
|
||||
// Serialize Members.
|
||||
//################################
|
||||
[Tooltip("The desampling rate for soft mask buffer.")]
|
||||
[SerializeField] 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;
|
||||
[Tooltip("The transparency of the whole masked graphic.")]
|
||||
[SerializeField][Range(0f, 1f)] float m_Alpha = 1;
|
||||
[Tooltip("Should the soft mask ignore parent soft masks?")]
|
||||
[SerializeField] bool m_IgnoreParent = false;
|
||||
[Tooltip("Is the soft mask a part of parent soft mask?")]
|
||||
[SerializeField] bool m_PartOfParent = false;
|
||||
static Shader s_SoftMaskShader;
|
||||
static Texture2D s_ReadTexture;
|
||||
static readonly List<SoftMask> s_ActiveSoftMasks = new List<SoftMask>();
|
||||
static readonly List<SoftMask> s_TempRelatables = new List<SoftMask>();
|
||||
static readonly Dictionary<int, Matrix4x4> s_previousViewProjectionMatrices = new Dictionary<int, Matrix4x4>();
|
||||
static readonly Dictionary<int, Matrix4x4> s_nowViewProjectionMatrices = new Dictionary<int, Matrix4x4>();
|
||||
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<SoftMask> _children = new List<SoftMask>();
|
||||
bool _hasChanged = false;
|
||||
bool _hasStencilStateChanged = false;
|
||||
|
||||
|
||||
[Tooltip("The desampling rate for soft mask buffer.")] [SerializeField]
|
||||
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;
|
||||
|
||||
[Tooltip("The transparency of the whole masked graphic.")] [SerializeField] [Range(0f, 1f)]
|
||||
float m_Alpha = 1;
|
||||
|
||||
[Tooltip("Should the soft mask ignore parent soft masks?")] [SerializeField]
|
||||
bool m_IgnoreParent = false;
|
||||
|
||||
[Tooltip("Is the soft mask a part of parent soft mask?")] [SerializeField]
|
||||
bool m_PartOfParent = false;
|
||||
|
||||
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
/// <summary>
|
||||
/// The desampling rate for soft mask buffer.
|
||||
/// </summary>
|
||||
|
@ -71,13 +95,11 @@ namespace Coffee.UISoftMask
|
|||
get { return m_DesamplingRate; }
|
||||
set
|
||||
{
|
||||
if (m_DesamplingRate != value)
|
||||
{
|
||||
if (m_DesamplingRate == value) return;
|
||||
m_DesamplingRate = value;
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value used by the soft mask to select the area of influence defined over the soft mask's graphic.
|
||||
|
@ -88,13 +110,11 @@ namespace Coffee.UISoftMask
|
|||
set
|
||||
{
|
||||
value = Mathf.Clamp01(value);
|
||||
if (m_Softness != value)
|
||||
{
|
||||
if (Mathf.Approximately(m_Softness, value)) return;
|
||||
m_Softness = value;
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The transparency of the whole masked graphic.
|
||||
|
@ -105,13 +125,11 @@ namespace Coffee.UISoftMask
|
|||
set
|
||||
{
|
||||
value = Mathf.Clamp01(value);
|
||||
if (m_Alpha != value)
|
||||
{
|
||||
if (Mathf.Approximately(m_Alpha, value)) return;
|
||||
m_Alpha = value;
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should the soft mask ignore parent soft masks?
|
||||
|
@ -122,14 +140,12 @@ namespace Coffee.UISoftMask
|
|||
get { return m_IgnoreParent; }
|
||||
set
|
||||
{
|
||||
if (m_IgnoreParent != value)
|
||||
{
|
||||
if (m_IgnoreParent == value) return;
|
||||
m_IgnoreParent = value;
|
||||
hasChanged = true;
|
||||
OnTransformParentChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the soft mask a part of parent soft mask?
|
||||
|
@ -139,14 +155,12 @@ namespace Coffee.UISoftMask
|
|||
get { return m_PartOfParent; }
|
||||
set
|
||||
{
|
||||
if (m_PartOfParent != value)
|
||||
{
|
||||
if (m_PartOfParent == value) return;
|
||||
m_PartOfParent = value;
|
||||
hasChanged = true;
|
||||
OnTransformParentChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The soft mask buffer.
|
||||
|
@ -157,7 +171,7 @@ namespace Coffee.UISoftMask
|
|||
{
|
||||
if (_parent)
|
||||
{
|
||||
ReleaseRT(ref _softMaskBuffer);
|
||||
ReleaseRt(ref _softMaskBuffer);
|
||||
return _parent.softMaskBuffer;
|
||||
}
|
||||
|
||||
|
@ -166,12 +180,13 @@ namespace Coffee.UISoftMask
|
|||
GetDesamplingSize(m_DesamplingRate, out w, out h);
|
||||
if (_softMaskBuffer && (_softMaskBuffer.width != w || _softMaskBuffer.height != h))
|
||||
{
|
||||
ReleaseRT(ref _softMaskBuffer);
|
||||
ReleaseRt(ref _softMaskBuffer);
|
||||
}
|
||||
|
||||
if (!_softMaskBuffer)
|
||||
{
|
||||
_softMaskBuffer = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
|
||||
_softMaskBuffer = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32,
|
||||
RenderTextureReadWrite.Default);
|
||||
hasChanged = true;
|
||||
_hasStencilStateChanged = true;
|
||||
}
|
||||
|
@ -182,28 +197,42 @@ namespace Coffee.UISoftMask
|
|||
|
||||
public bool hasChanged
|
||||
{
|
||||
get
|
||||
{
|
||||
return _parent ? _parent.hasChanged : _hasChanged;
|
||||
}
|
||||
get { return _parent ? _parent.hasChanged : _hasChanged; }
|
||||
private set
|
||||
{
|
||||
if (_parent)
|
||||
{
|
||||
_parent.hasChanged = value;
|
||||
}
|
||||
|
||||
_hasChanged = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SoftMask parent
|
||||
{
|
||||
get { return _parent; }
|
||||
}
|
||||
|
||||
Material material
|
||||
{
|
||||
get
|
||||
{
|
||||
return _parent;
|
||||
return _material
|
||||
? _material
|
||||
: _material =
|
||||
new Material(s_SoftMaskShader
|
||||
? s_SoftMaskShader
|
||||
: s_SoftMaskShader = Resources.Load<Shader>("SoftMask"))
|
||||
{hideFlags = HideFlags.HideAndDontSave};
|
||||
}
|
||||
}
|
||||
|
||||
Mesh mesh
|
||||
{
|
||||
get { return _mesh ? _mesh : _mesh = new Mesh() {hideFlags = HideFlags.HideAndDontSave}; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Perform material modification in this function.
|
||||
|
@ -216,8 +245,9 @@ namespace Coffee.UISoftMask
|
|||
var result = base.GetModifiedMaterial(baseMaterial);
|
||||
if (m_IgnoreParent && result != baseMaterial)
|
||||
{
|
||||
result.SetInt(s_StencilCompId, (int)CompareFunction.Always);
|
||||
result.SetInt(s_StencilCompId, (int) CompareFunction.Always);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -237,9 +267,7 @@ namespace Coffee.UISoftMask
|
|||
void IMeshModifier.ModifyMesh(VertexHelper verts)
|
||||
{
|
||||
if (isActiveAndEnabled)
|
||||
{
|
||||
verts.FillMesh(mesh);
|
||||
}
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
|
@ -252,15 +280,12 @@ namespace Coffee.UISoftMask
|
|||
/// <param name="g">Target graphic.</param>
|
||||
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera, Graphic g, int[] interactions)
|
||||
{
|
||||
if (!isActiveAndEnabled || (g == graphic && !g.raycastTarget))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!isActiveAndEnabled || (g == graphic && !g.raycastTarget)) return true;
|
||||
|
||||
int x = (int)((softMaskBuffer.width - 1) * Mathf.Clamp01(sp.x / Screen.width));
|
||||
int x = (int) ((softMaskBuffer.width - 1) * Mathf.Clamp01(sp.x / Screen.width));
|
||||
int y = s_UVStartsAtTop
|
||||
? (int)((softMaskBuffer.height - 1) * (1 - Mathf.Clamp01(sp.y / Screen.height)))
|
||||
: (int)((softMaskBuffer.height - 1) * Mathf.Clamp01(sp.y / Screen.height));
|
||||
? (int) ((softMaskBuffer.height - 1) * (1 - Mathf.Clamp01(sp.y / Screen.height)))
|
||||
: (int) ((softMaskBuffer.height - 1) * Mathf.Clamp01(sp.y / Screen.height));
|
||||
return 0.5f < GetPixelValue(x, y, interactions);
|
||||
}
|
||||
|
||||
|
@ -269,10 +294,6 @@ namespace Coffee.UISoftMask
|
|||
return true;
|
||||
}
|
||||
|
||||
//################################
|
||||
// Protected Members.
|
||||
//################################
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the object becomes enabled and active.
|
||||
/// </summary>
|
||||
|
@ -299,6 +320,7 @@ namespace Coffee.UISoftMask
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
s_ActiveSoftMasks.Add(this);
|
||||
|
||||
// Reset the parent-child relation.
|
||||
|
@ -307,6 +329,7 @@ namespace Coffee.UISoftMask
|
|||
{
|
||||
s_TempRelatables[i].OnTransformParentChanged();
|
||||
}
|
||||
|
||||
s_TempRelatables.Clear();
|
||||
|
||||
// Create objects.
|
||||
|
@ -336,6 +359,7 @@ namespace Coffee.UISoftMask
|
|||
{
|
||||
_children[i].SetParent(_parent);
|
||||
}
|
||||
|
||||
_children.Clear();
|
||||
SetParent(null);
|
||||
|
||||
|
@ -349,7 +373,7 @@ namespace Coffee.UISoftMask
|
|||
_mesh = null;
|
||||
ReleaseObject(_material);
|
||||
_material = null;
|
||||
ReleaseRT(ref _softMaskBuffer);
|
||||
ReleaseRt(ref _softMaskBuffer);
|
||||
|
||||
base.OnDisable();
|
||||
_hasStencilStateChanged = false;
|
||||
|
@ -371,6 +395,7 @@ namespace Coffee.UISoftMask
|
|||
parentTransform = parentTransform.parent;
|
||||
}
|
||||
}
|
||||
|
||||
SetParent(newParent);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
@ -381,10 +406,6 @@ namespace Coffee.UISoftMask
|
|||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Update the scene view matrix for shader.
|
||||
/// </summary>
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
|
||||
/// </summary>
|
||||
|
@ -397,37 +418,6 @@ namespace Coffee.UISoftMask
|
|||
}
|
||||
#endif
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
static Shader s_SoftMaskShader;
|
||||
static Texture2D s_ReadTexture;
|
||||
static List<SoftMask> s_ActiveSoftMasks = new List<SoftMask>();
|
||||
static List<SoftMask> s_TempRelatables = new List<SoftMask>();
|
||||
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;
|
||||
List<SoftMask> _children = new List<SoftMask>();
|
||||
bool _hasChanged = false;
|
||||
bool _hasStencilStateChanged = false;
|
||||
static readonly Dictionary<int, Matrix4x4> s_previousViewProjectionMatrices = new Dictionary<int, Matrix4x4> ();
|
||||
static readonly Dictionary<int, Matrix4x4> s_nowViewProjectionMatrices = new Dictionary<int, Matrix4x4> ();
|
||||
|
||||
Material material { get { return _material ? _material : _material = new Material(s_SoftMaskShader ? s_SoftMaskShader : s_SoftMaskShader = Resources.Load<Shader>("SoftMask")){ hideFlags = HideFlags.HideAndDontSave }; } }
|
||||
|
||||
Mesh mesh { get { return _mesh ? _mesh : _mesh = new Mesh(){ hideFlags = HideFlags.HideAndDontSave }; } }
|
||||
|
||||
/// <summary>
|
||||
/// Update all soft mask textures.
|
||||
/// </summary>
|
||||
|
@ -439,20 +429,19 @@ namespace Coffee.UISoftMask
|
|||
continue;
|
||||
|
||||
var canvas = sm.graphic.canvas;
|
||||
if(!canvas)
|
||||
if (!canvas)
|
||||
continue;
|
||||
|
||||
if (canvas.renderMode == RenderMode.WorldSpace)
|
||||
{
|
||||
var cam = canvas.worldCamera;
|
||||
if(!cam)
|
||||
if (!cam)
|
||||
continue;
|
||||
|
||||
Matrix4x4 nowVP = cam.projectionMatrix * cam.worldToCameraMatrix;
|
||||
|
||||
Matrix4x4 previousVP = default(Matrix4x4);
|
||||
int id = cam.GetInstanceID ();
|
||||
s_previousViewProjectionMatrices.TryGetValue (id, out previousVP);
|
||||
var nowVP = cam.projectionMatrix * cam.worldToCameraMatrix;
|
||||
var previousVP = default(Matrix4x4);
|
||||
var id = cam.GetInstanceID();
|
||||
s_previousViewProjectionMatrices.TryGetValue(id, out previousVP);
|
||||
s_nowViewProjectionMatrices[id] = nowVP;
|
||||
|
||||
if (previousVP != nowVP)
|
||||
|
@ -481,55 +470,51 @@ namespace Coffee.UISoftMask
|
|||
continue;
|
||||
|
||||
sm._hasChanged = false;
|
||||
if (!sm._parent)
|
||||
{
|
||||
if (sm._parent) continue;
|
||||
sm.UpdateMaskTexture();
|
||||
if (sm._hasStencilStateChanged)
|
||||
{
|
||||
|
||||
if (!sm._hasStencilStateChanged) continue;
|
||||
sm._hasStencilStateChanged = false;
|
||||
MaskUtilities.NotifyStencilStateChanged (sm);
|
||||
}
|
||||
}
|
||||
MaskUtilities.NotifyStencilStateChanged(sm);
|
||||
}
|
||||
|
||||
s_previousViewProjectionMatrices.Clear ();
|
||||
foreach (int 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the mask texture.
|
||||
/// </summary>
|
||||
void UpdateMaskTexture()
|
||||
private void UpdateMaskTexture()
|
||||
{
|
||||
if (!graphic || !graphic.canvas)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!graphic || !graphic.canvas) return;
|
||||
|
||||
_stencilDepth = MaskUtilities.GetStencilDepth(transform, MaskUtilities.FindRootSortOverrideCanvas(transform));
|
||||
_stencilDepth =
|
||||
MaskUtilities.GetStencilDepth(transform, MaskUtilities.FindRootSortOverrideCanvas(transform));
|
||||
|
||||
// Collect children soft masks.
|
||||
int depth = 0;
|
||||
var depth = 0;
|
||||
s_TmpSoftMasks[0].Add(this);
|
||||
while (_stencilDepth + depth < 3)
|
||||
{
|
||||
int count = s_TmpSoftMasks[depth].Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
var count = s_TmpSoftMasks[depth].Count;
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
List<SoftMask> children = s_TmpSoftMasks[depth][i]._children;
|
||||
int childCount = children.Count;
|
||||
for (int j = 0; j < childCount; j++)
|
||||
var childCount = children.Count;
|
||||
for (var j = 0; j < childCount; j++)
|
||||
{
|
||||
var child = children[j];
|
||||
var childDepth = child.m_PartOfParent ? depth : depth + 1;
|
||||
s_TmpSoftMasks[childDepth].Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
depth++;
|
||||
}
|
||||
|
||||
|
@ -543,7 +528,8 @@ namespace Coffee.UISoftMask
|
|||
var cam = c.worldCamera ?? Camera.main;
|
||||
if (c && c.renderMode != RenderMode.ScreenSpaceOverlay && cam)
|
||||
{
|
||||
_cb.SetViewProjectionMatrices(cam.worldToCameraMatrix, GL.GetGPUProjectionMatrix(cam.projectionMatrix, false));
|
||||
_cb.SetViewProjectionMatrices(cam.worldToCameraMatrix,
|
||||
GL.GetGPUProjectionMatrix(cam.projectionMatrix, false));
|
||||
|
||||
#if UNITY_EDITOR
|
||||
var pv = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false) * cam.worldToCameraMatrix;
|
||||
|
@ -555,32 +541,38 @@ namespace Coffee.UISoftMask
|
|||
{
|
||||
var pos = c.transform.position;
|
||||
var vm = Matrix4x4.TRS(new Vector3(-pos.x, -pos.y, -1000), Quaternion.identity, new Vector3(1, 1, -1f));
|
||||
var pm = Matrix4x4.TRS(new Vector3(0, 0, -1), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 10000f));
|
||||
var pm = Matrix4x4.TRS(new Vector3(0, 0, -1), Quaternion.identity,
|
||||
new Vector3(1 / pos.x, 1 / pos.y, -2 / 10000f));
|
||||
_cb.SetViewProjectionMatrices(vm, pm);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
var scale = c.transform.localScale.x;
|
||||
var size = (c.transform as RectTransform).sizeDelta;
|
||||
_cb.SetGlobalMatrix(s_GameVPId, Matrix4x4.TRS(new Vector3(0, 0, 0.5f), Quaternion.identity, new Vector3(2 / size.x, 2 / size.y, 0.0005f * scale)));
|
||||
_cb.SetGlobalMatrix(s_GameTVPId, Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, new Vector3(1 / pos.x, 1 / pos.y, -2 / 2000f)) * Matrix4x4.Translate(-pos));
|
||||
_cb.SetGlobalMatrix(s_GameVPId,
|
||||
Matrix4x4.TRS(new Vector3(0, 0, 0.5f), Quaternion.identity,
|
||||
new Vector3(2 / size.x, 2 / size.y, 0.0005f * scale)));
|
||||
_cb.SetGlobalMatrix(s_GameTVPId,
|
||||
Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity,
|
||||
new Vector3(1 / pos.x, 1 / pos.y, -2 / 2000f)) * Matrix4x4.Translate(-pos));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw soft masks.
|
||||
for (int i = 0; i < s_TmpSoftMasks.Length; i++)
|
||||
for (var i = 0; i < s_TmpSoftMasks.Length; i++)
|
||||
{
|
||||
int count = s_TmpSoftMasks[i].Count;
|
||||
for (int j = 0; j < count; j++)
|
||||
var count = s_TmpSoftMasks[i].Count;
|
||||
for (var j = 0; j < count; j++)
|
||||
{
|
||||
var sm = s_TmpSoftMasks[i][j];
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
sm._stencilDepth = MaskUtilities.GetStencilDepth(sm.transform, MaskUtilities.FindRootSortOverrideCanvas(sm.transform));
|
||||
sm._stencilDepth = MaskUtilities.GetStencilDepth(sm.transform,
|
||||
MaskUtilities.FindRootSortOverrideCanvas(sm.transform));
|
||||
}
|
||||
|
||||
// Set material property.
|
||||
sm.material.SetInt(s_ColorMaskId, (int)1 << (3 - _stencilDepth - i));
|
||||
sm.material.SetInt(s_ColorMaskId, (int) 1 << (3 - _stencilDepth - i));
|
||||
sm._mpb.SetTexture(s_MainTexId, sm.graphic.mainTexture);
|
||||
sm._mpb.SetFloat(s_SoftnessId, sm.m_Softness);
|
||||
sm._mpb.SetFloat(s_Alpha, sm.m_Alpha);
|
||||
|
@ -588,6 +580,7 @@ namespace Coffee.UISoftMask
|
|||
// Draw mesh.
|
||||
_cb.DrawMesh(sm.mesh, sm.transform.localToWorldMatrix, sm.material, 0, 0, sm._mpb);
|
||||
}
|
||||
|
||||
s_TmpSoftMasks[i].Clear();
|
||||
}
|
||||
|
||||
|
@ -597,7 +590,7 @@ namespace Coffee.UISoftMask
|
|||
/// <summary>
|
||||
/// Gets the size of the desampling.
|
||||
/// </summary>
|
||||
void GetDesamplingSize(DesamplingRate rate, out int w, out int h)
|
||||
private static void GetDesamplingSize(DesamplingRate rate, out int w, out int h)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var res = UnityEditor.UnityStats.screenRes.Split('x');
|
||||
|
@ -611,15 +604,15 @@ namespace Coffee.UISoftMask
|
|||
if (rate == DesamplingRate.None)
|
||||
return;
|
||||
|
||||
float aspect = (float)w / h;
|
||||
var aspect = (float) w / h;
|
||||
if (w < h)
|
||||
{
|
||||
h = Mathf.ClosestPowerOfTwo(h / (int)rate);
|
||||
h = Mathf.ClosestPowerOfTwo(h / (int) rate);
|
||||
w = Mathf.CeilToInt(h * aspect);
|
||||
}
|
||||
else
|
||||
{
|
||||
w = Mathf.ClosestPowerOfTwo(w / (int)rate);
|
||||
w = Mathf.ClosestPowerOfTwo(w / (int) rate);
|
||||
h = Mathf.CeilToInt(w / aspect);
|
||||
}
|
||||
}
|
||||
|
@ -628,40 +621,36 @@ namespace Coffee.UISoftMask
|
|||
/// Release the specified obj.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object.</param>
|
||||
void ReleaseRT(ref RenderTexture tmpRT)
|
||||
{
|
||||
if (tmpRT)
|
||||
private static void ReleaseRt(ref RenderTexture tmpRT)
|
||||
{
|
||||
if (!tmpRT) return;
|
||||
tmpRT.Release();
|
||||
RenderTexture.ReleaseTemporary(tmpRT);
|
||||
tmpRT = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Release the specified obj.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object.</param>
|
||||
void ReleaseObject(Object obj)
|
||||
private static void ReleaseObject(Object obj)
|
||||
{
|
||||
if (obj)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!obj) return;
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
DestroyImmediate(obj);
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
Destroy(obj);
|
||||
obj = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set the parent of the soft mask.
|
||||
/// </summary>
|
||||
/// <param name="newParent">The parent soft mask to use.</param>
|
||||
void SetParent(SoftMask newParent)
|
||||
private void SetParent(SoftMask newParent)
|
||||
{
|
||||
if (_parent != newParent && this != newParent)
|
||||
{
|
||||
|
@ -670,6 +659,7 @@ namespace Coffee.UISoftMask
|
|||
_parent._children.Remove(this);
|
||||
_parent._children.RemoveAll(x => x == null);
|
||||
}
|
||||
|
||||
_parent = newParent;
|
||||
}
|
||||
|
||||
|
@ -682,27 +672,32 @@ namespace Coffee.UISoftMask
|
|||
/// <summary>
|
||||
/// Gets the pixel value.
|
||||
/// </summary>
|
||||
float GetPixelValue(int x, int y, int[] interactions)
|
||||
private float GetPixelValue(int x, int y, int[] interactions)
|
||||
{
|
||||
if (!s_ReadTexture)
|
||||
{
|
||||
s_ReadTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false);
|
||||
}
|
||||
var currentRT = RenderTexture.active;
|
||||
|
||||
var currentRt = RenderTexture.active;
|
||||
|
||||
RenderTexture.active = softMaskBuffer;
|
||||
s_ReadTexture.ReadPixels(new Rect(x, y, 1, 1), 0, 0);
|
||||
s_ReadTexture.Apply(false, false);
|
||||
RenderTexture.active = currentRT;
|
||||
RenderTexture.active = currentRt;
|
||||
|
||||
var colors = s_ReadTexture.GetRawTextureData();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
switch (interactions[(i + 3)%4])
|
||||
switch (interactions[(i + 3) % 4])
|
||||
{
|
||||
case 0: colors[i] = 255; break;
|
||||
case 2: colors[i] = (byte)(255 - colors[i]); break;
|
||||
case 0:
|
||||
colors[i] = 255;
|
||||
break;
|
||||
case 2:
|
||||
colors[i] = (byte) (255 - colors[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,34 +24,70 @@ namespace Coffee.UISoftMask
|
|||
const int kVisibleOutside = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6);
|
||||
static readonly Hash128 k_InvalidHash = new Hash128();
|
||||
|
||||
[Tooltip("The graphic will be visible only in areas where no mask is present.")]
|
||||
[System.Obsolete]
|
||||
[HideInInspector]
|
||||
[SerializeField] bool m_Inverse = false;
|
||||
[Tooltip("The interaction for each masks.")]
|
||||
[HideInInspector]
|
||||
[SerializeField] int m_MaskInteraction = kVisibleInside;
|
||||
[Tooltip("Use stencil to mask.")]
|
||||
[SerializeField] bool m_UseStencil = false;
|
||||
[Tooltip("Use soft-masked raycast target.\n\nNote: This option is expensive.")]
|
||||
[SerializeField] bool m_RaycastFilter = false;
|
||||
|
||||
Graphic _graphic = null;
|
||||
SoftMask _softMask = null;
|
||||
Material _maskMaterial = null;
|
||||
static int s_SoftMaskTexId;
|
||||
static int s_StencilCompId;
|
||||
static int s_MaskInteractionId;
|
||||
static List<SoftMaskable> s_ActiveSoftMaskables;
|
||||
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;
|
||||
|
||||
[Tooltip("The interaction for each masks.")] [HideInInspector] [SerializeField]
|
||||
int m_MaskInteraction = kVisibleInside;
|
||||
|
||||
[Tooltip("Use stencil to mask.")] [SerializeField]
|
||||
bool m_UseStencil = false;
|
||||
|
||||
[Tooltip("Use soft-masked raycast target.\n\nNote: This option is expensive.")] [SerializeField]
|
||||
bool m_RaycastFilter = false;
|
||||
|
||||
Graphic _graphic = null;
|
||||
SoftMask _softMask = null;
|
||||
Material _maskMaterial = null;
|
||||
Hash128 _effectMaterialHash;
|
||||
|
||||
/// <summary>
|
||||
/// The graphic will be visible only in areas where no mask is present.
|
||||
/// </summary>
|
||||
public bool inverse
|
||||
{
|
||||
get { return m_MaskInteraction == kVisibleOutside; }
|
||||
set
|
||||
{
|
||||
var intValue = value ? kVisibleOutside : kVisibleInside;
|
||||
if (m_MaskInteraction == intValue) return;
|
||||
m_MaskInteraction = intValue;
|
||||
graphic.SetMaterialDirtyEx();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use soft-masked raycast target. This option is expensive.
|
||||
/// </summary>
|
||||
public bool raycastFilter
|
||||
{
|
||||
get { return m_RaycastFilter; }
|
||||
set { m_RaycastFilter = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The graphic associated with the soft mask.
|
||||
/// </summary>
|
||||
public Graphic graphic
|
||||
{
|
||||
get { return _graphic ? _graphic : _graphic = GetComponent<Graphic>(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform material modification in this function.
|
||||
/// </summary>
|
||||
/// <returns>Modified material.</returns>
|
||||
/// <param name="baseMaterial">Configured Material.</param>
|
||||
public Material GetModifiedMaterial(Material baseMaterial)
|
||||
Material IMaterialModifier.GetModifiedMaterial(Material baseMaterial)
|
||||
{
|
||||
_softMask = null;
|
||||
if (!isActiveAndEnabled)
|
||||
|
@ -69,6 +105,7 @@ namespace Coffee.UISoftMask
|
|||
_softMask = sm;
|
||||
break;
|
||||
}
|
||||
|
||||
parentTransform = parentTransform.parent;
|
||||
}
|
||||
|
||||
|
@ -79,13 +116,13 @@ namespace Coffee.UISoftMask
|
|||
_effectMaterialHash = GetMaterialHash(baseMaterial);
|
||||
modifiedMaterial = MaterialCache.Register(baseMaterial, _effectMaterialHash, mat =>
|
||||
{
|
||||
Debug.Log(mat.shader.name);
|
||||
mat.shader = Shader.Find(string.Format("Hidden/{0} (SoftMaskable)", mat.shader.name));
|
||||
#if UNITY_EDITOR
|
||||
mat.EnableKeyword("SOFTMASK_EDITOR");
|
||||
#endif
|
||||
mat.SetTexture(s_SoftMaskTexId, _softMask.softMaskBuffer);
|
||||
mat.SetInt(s_StencilCompId, m_UseStencil ? (int)CompareFunction.Equal : (int)CompareFunction.Always);
|
||||
mat.SetInt(s_StencilCompId,
|
||||
m_UseStencil ? (int) CompareFunction.Equal : (int) CompareFunction.Always);
|
||||
mat.SetVector(s_MaskInteractionId, new Vector4(
|
||||
(m_MaskInteraction & 0x3),
|
||||
((m_MaskInteraction >> 2) & 0x3),
|
||||
|
@ -120,7 +157,7 @@ namespace Coffee.UISoftMask
|
|||
/// <returns>Valid.</returns>
|
||||
/// <param name="sp">Screen position.</param>
|
||||
/// <param name="eventCamera">Raycast camera.</param>
|
||||
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
|
||||
bool ICanvasRaycastFilter.IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
|
||||
{
|
||||
if (!isActiveAndEnabled || !_softMask)
|
||||
return true;
|
||||
|
@ -130,7 +167,7 @@ namespace Coffee.UISoftMask
|
|||
return true;
|
||||
|
||||
var sm = _softMask;
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
s_Interactions[i] = sm ? ((m_MaskInteraction >> i * 2) & 0x3) : 0;
|
||||
sm = sm ? sm.parent : null;
|
||||
|
@ -139,38 +176,6 @@ namespace Coffee.UISoftMask
|
|||
return _softMask.IsRaycastLocationValid(sp, eventCamera, graphic, s_Interactions);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The graphic will be visible only in areas where no mask is present.
|
||||
/// </summary>
|
||||
public bool inverse
|
||||
{
|
||||
get { return m_MaskInteraction == kVisibleOutside; }
|
||||
set
|
||||
{
|
||||
int intValue = value ? kVisibleOutside : kVisibleInside;
|
||||
if (m_MaskInteraction != intValue)
|
||||
{
|
||||
m_MaskInteraction = intValue;
|
||||
graphic.SetMaterialDirtyEx();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use soft-masked raycast target. This option is expensive.
|
||||
/// </summary>
|
||||
public bool raycastFilter
|
||||
{
|
||||
get { return m_RaycastFilter; }
|
||||
set { m_RaycastFilter = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The graphic associated with the soft mask.
|
||||
/// </summary>
|
||||
public Graphic graphic{ get { return _graphic ? _graphic : _graphic = GetComponent<Graphic>(); } }
|
||||
|
||||
/// <summary>
|
||||
/// Set the interaction for each mask.
|
||||
/// </summary>
|
||||
|
@ -182,9 +187,10 @@ namespace Coffee.UISoftMask
|
|||
/// <summary>
|
||||
/// Set the interaction for each mask.
|
||||
/// </summary>
|
||||
public void SetMaskInteraction(SpriteMaskInteraction layer0, SpriteMaskInteraction layer1, SpriteMaskInteraction layer2, SpriteMaskInteraction layer3)
|
||||
public void SetMaskInteraction(SpriteMaskInteraction layer0, SpriteMaskInteraction layer1,
|
||||
SpriteMaskInteraction layer2, SpriteMaskInteraction layer3)
|
||||
{
|
||||
m_MaskInteraction = (int)layer0 + ((int)layer1 << 2) + ((int)layer2 << 4) + ((int)layer3 << 6);
|
||||
m_MaskInteraction = (int) layer0 + ((int) layer1 << 2) + ((int) layer2 << 4) + ((int) layer3 << 6);
|
||||
graphic.SetMaterialDirtyEx();
|
||||
}
|
||||
|
||||
|
@ -192,7 +198,7 @@ namespace Coffee.UISoftMask
|
|||
/// <summary>
|
||||
/// This function is called when the object becomes enabled and active.
|
||||
/// </summary>
|
||||
void OnEnable()
|
||||
private void OnEnable()
|
||||
{
|
||||
// Register.
|
||||
if (s_ActiveSoftMaskables == null)
|
||||
|
@ -203,32 +209,23 @@ namespace Coffee.UISoftMask
|
|||
s_StencilCompId = Shader.PropertyToID("_StencilComp");
|
||||
s_MaskInteractionId = Shader.PropertyToID("_MaskInteraction");
|
||||
}
|
||||
|
||||
s_ActiveSoftMaskables.Add(this);
|
||||
|
||||
|
||||
var g = graphic;
|
||||
if (g)
|
||||
{
|
||||
g.SetMaterialDirty();
|
||||
}
|
||||
graphic.SetMaterialDirtyEx();
|
||||
_softMask = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the behaviour becomes disabled.
|
||||
/// </summary>
|
||||
void OnDisable()
|
||||
private void OnDisable()
|
||||
{
|
||||
s_ActiveSoftMaskables.Remove(this);
|
||||
|
||||
var g = graphic;
|
||||
if (g)
|
||||
{
|
||||
g.SetMaterialDirty();
|
||||
}
|
||||
ReleaseMaterial(ref _maskMaterial);
|
||||
|
||||
graphic.SetMaterialDirtyEx();
|
||||
_softMask = null;
|
||||
ReleaseMaterial(ref _maskMaterial);
|
||||
|
||||
MaterialCache.Unregister(_effectMaterialHash);
|
||||
_effectMaterialHash = k_InvalidHash;
|
||||
|
@ -237,23 +234,19 @@ namespace Coffee.UISoftMask
|
|||
/// <summary>
|
||||
/// Release the material.
|
||||
/// </summary>
|
||||
void ReleaseMaterial(ref Material mat)
|
||||
static void ReleaseMaterial(ref Material mat)
|
||||
{
|
||||
if (mat)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!mat) return;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
DestroyImmediate(mat);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#endif
|
||||
Destroy(mat);
|
||||
}
|
||||
|
||||
mat = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
@ -271,20 +264,20 @@ namespace Coffee.UISoftMask
|
|||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
#pragma warning disable 0612
|
||||
#pragma warning disable 0612
|
||||
if (m_Inverse)
|
||||
{
|
||||
m_Inverse = false;
|
||||
m_MaskInteraction = (2 << 0) + (2 << 2) + (2 << 4) + (2 << 6);
|
||||
}
|
||||
#pragma warning restore 0612
|
||||
#pragma warning restore 0612
|
||||
|
||||
var current = this;
|
||||
UnityEditor.EditorApplication.delayCall += () =>
|
||||
{
|
||||
if (current && graphic && graphic.material && graphic.material.shader && graphic.material.shader.name == "Hidden/UI/Default (SoftMaskable)")
|
||||
if (current && graphic && graphic.material && graphic.material.shader &&
|
||||
graphic.material.shader.name == "Hidden/UI/Default (SoftMaskable)")
|
||||
{
|
||||
Debug.LogFormat("OnAfterDeserialize: reset material {0}",current);
|
||||
graphic.material = null;
|
||||
graphic.SetMaterialDirtyEx();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue