summaryrefslogtreecommitdiff
path: root/Assets/Scripts
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/Scripts')
-rw-r--r--Assets/Scripts/Common.meta9
-rw-r--r--Assets/Scripts/Common/BaseMaterialEffect.cs193
-rw-r--r--Assets/Scripts/Common/BaseMaterialEffect.cs.meta12
-rw-r--r--Assets/Scripts/Common/BaseMeshEffect.cs229
-rw-r--r--Assets/Scripts/Common/BaseMeshEffect.cs.meta11
-rw-r--r--Assets/Scripts/Common/EffectPlayer.cs154
-rw-r--r--Assets/Scripts/Common/EffectPlayer.cs.meta12
-rw-r--r--Assets/Scripts/Common/GraphicConnector.cs151
-rw-r--r--Assets/Scripts/Common/GraphicConnector.cs.meta11
-rw-r--r--Assets/Scripts/Common/MaterialCache.cs77
-rw-r--r--Assets/Scripts/Common/MaterialCache.cs.meta12
-rw-r--r--Assets/Scripts/Common/Matrix2x3.cs33
-rw-r--r--Assets/Scripts/Common/Matrix2x3.cs.meta12
-rw-r--r--Assets/Scripts/Common/Packer.cs61
-rw-r--r--Assets/Scripts/Common/Packer.cs.meta12
-rw-r--r--Assets/Scripts/Common/ParameterTexture.cs190
-rw-r--r--Assets/Scripts/Common/ParameterTexture.cs.meta12
-rw-r--r--Assets/Scripts/Editor.meta8
-rw-r--r--Assets/Scripts/Editor/ImportSampleMenu.cs75
-rw-r--r--Assets/Scripts/Editor/ImportSampleMenu.cs.meta11
-rw-r--r--Assets/Scripts/Editor/MaterialDirtyScope.cs33
-rw-r--r--Assets/Scripts/Editor/MaterialDirtyScope.cs.meta11
-rw-r--r--Assets/Scripts/Editor/UIDissolveEditor.cs121
-rw-r--r--Assets/Scripts/Editor/UIDissolveEditor.cs.meta12
-rw-r--r--Assets/Scripts/Editor/UIEffect-Editor.asmdef16
-rw-r--r--Assets/Scripts/Editor/UIEffect-Editor.asmdef.meta7
-rw-r--r--Assets/Scripts/Editor/UIEffectEditor.cs114
-rw-r--r--Assets/Scripts/Editor/UIEffectEditor.cs.meta12
-rw-r--r--Assets/Scripts/Editor/UIGradientEditor.cs140
-rw-r--r--Assets/Scripts/Editor/UIGradientEditor.cs.meta12
-rw-r--r--Assets/Scripts/Editor/UIHsvModifierEditor.cs53
-rw-r--r--Assets/Scripts/Editor/UIHsvModifierEditor.cs.meta12
-rw-r--r--Assets/Scripts/Editor/UIShadowEditor.cs62
-rw-r--r--Assets/Scripts/Editor/UIShadowEditor.cs.meta12
-rw-r--r--Assets/Scripts/Editor/UIShinyEditor.cs102
-rw-r--r--Assets/Scripts/Editor/UIShinyEditor.cs.meta12
-rw-r--r--Assets/Scripts/Editor/UITransitionEffectEditor.cs115
-rw-r--r--Assets/Scripts/Editor/UITransitionEffectEditor.cs.meta12
-rw-r--r--Assets/Scripts/Enums.meta8
-rw-r--r--Assets/Scripts/Enums/BlurMode.cs13
-rw-r--r--Assets/Scripts/Enums/BlurMode.cs.meta12
-rw-r--r--Assets/Scripts/Enums/ColorMode.cs13
-rw-r--r--Assets/Scripts/Enums/ColorMode.cs.meta12
-rw-r--r--Assets/Scripts/Enums/EffectArea.cs116
-rw-r--r--Assets/Scripts/Enums/EffectArea.cs.meta12
-rw-r--r--Assets/Scripts/Enums/EffectMode.cs14
-rw-r--r--Assets/Scripts/Enums/EffectMode.cs.meta12
-rw-r--r--Assets/Scripts/Enums/ShadowStyle.cs14
-rw-r--r--Assets/Scripts/Enums/ShadowStyle.cs.meta12
-rw-r--r--Assets/Scripts/UIDissolve.cs319
-rw-r--r--Assets/Scripts/UIDissolve.cs.meta13
-rw-r--r--Assets/Scripts/UIEffect.asmdef3
-rw-r--r--Assets/Scripts/UIEffect.asmdef.meta7
-rw-r--r--Assets/Scripts/UIEffect.cs368
-rw-r--r--Assets/Scripts/UIEffect.cs.meta12
-rw-r--r--Assets/Scripts/UIFlip.cs69
-rw-r--r--Assets/Scripts/UIFlip.cs.meta12
-rw-r--r--Assets/Scripts/UIGradient.cs319
-rw-r--r--Assets/Scripts/UIGradient.cs.meta12
-rw-r--r--Assets/Scripts/UIHsvModifier.cs170
-rw-r--r--Assets/Scripts/UIHsvModifier.cs.meta12
-rw-r--r--Assets/Scripts/UIShadow.cs383
-rw-r--r--Assets/Scripts/UIShadow.cs.meta12
-rw-r--r--Assets/Scripts/UIShiny.cs278
-rw-r--r--Assets/Scripts/UIShiny.cs.meta12
-rw-r--r--Assets/Scripts/UISyncEffect.cs83
-rw-r--r--Assets/Scripts/UISyncEffect.cs.meta11
-rw-r--r--Assets/Scripts/UITransitionEffect.cs332
-rw-r--r--Assets/Scripts/UITransitionEffect.cs.meta16
69 files changed, 4824 insertions, 0 deletions
diff --git a/Assets/Scripts/Common.meta b/Assets/Scripts/Common.meta
new file mode 100644
index 0000000..36580c4
--- /dev/null
+++ b/Assets/Scripts/Common.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 04feaefc7cdee4c13abcd553a1a6e3a9
+folderAsset: yes
+timeCreated: 1528368324
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Common/BaseMaterialEffect.cs b/Assets/Scripts/Common/BaseMaterialEffect.cs
new file mode 100644
index 0000000..0cf2d7a
--- /dev/null
+++ b/Assets/Scripts/Common/BaseMaterialEffect.cs
@@ -0,0 +1,193 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Abstract effect base for UI.
+ /// </summary>
+ [DisallowMultipleComponent]
+ public abstract class BaseMaterialEffect : BaseMeshEffect, IParameterTexture, IMaterialModifier
+ {
+ protected static readonly Hash128 k_InvalidHash = new Hash128();
+ protected static readonly List<UIVertex> s_TempVerts = new List<UIVertex>();
+ private static readonly StringBuilder s_StringBuilder = new StringBuilder();
+
+ Hash128 _effectMaterialHash;
+
+ /// <summary>
+ /// Gets or sets the parameter index.
+ /// </summary>
+ public int parameterIndex { get; set; }
+
+ /// <summary>
+ /// Gets the parameter texture.
+ /// </summary>
+ public virtual ParameterTexture paramTex
+ {
+ get { return null; }
+ }
+
+ /// <summary>
+ /// Mark the vertices as dirty.
+ /// </summary>
+ public void SetMaterialDirty()
+ {
+ connector.SetMaterialDirty(graphic);
+
+ foreach (var effect in syncEffects)
+ {
+ effect.SetMaterialDirty();
+ }
+ }
+
+ public virtual Hash128 GetMaterialHash(Material baseMaterial)
+ {
+ return k_InvalidHash;
+ }
+
+ public Material GetModifiedMaterial(Material baseMaterial)
+ {
+ return GetModifiedMaterial(baseMaterial, graphic);
+ }
+
+ public virtual Material GetModifiedMaterial(Material baseMaterial, Graphic graphic)
+ {
+ if (!isActiveAndEnabled) return baseMaterial;
+
+ var oldHash = _effectMaterialHash;
+ _effectMaterialHash = GetMaterialHash(baseMaterial);
+ var modifiedMaterial = baseMaterial;
+ if (_effectMaterialHash.isValid)
+ {
+ modifiedMaterial = MaterialCache.Register(baseMaterial, _effectMaterialHash, ModifyMaterial, graphic);
+ }
+
+ MaterialCache.Unregister(oldHash);
+
+ return modifiedMaterial;
+ }
+
+ // protected bool isTMProMobile (Material material)
+ // {
+ // return material && material.shader && material.shader.name.StartsWith ("TextMeshPro/Mobile/", StringComparison.Ordinal);
+ // }
+
+ public virtual void ModifyMaterial(Material newMaterial, Graphic graphic)
+ {
+ if (isActiveAndEnabled && paramTex != null)
+ paramTex.RegisterMaterial(newMaterial);
+ }
+
+ protected void SetShaderVariants(Material newMaterial, params object[] variants)
+ {
+ // Set shader keywords as variants
+ var keywords = variants.Where(x => 0 < (int) x)
+ .Select(x => x.ToString().ToUpper())
+ .Concat(newMaterial.shaderKeywords)
+ .Distinct()
+ .ToArray();
+ newMaterial.shaderKeywords = keywords;
+
+ // Add variant name
+ s_StringBuilder.Length = 0;
+ s_StringBuilder.Append(Path.GetFileName(newMaterial.shader.name));
+ foreach (var keyword in keywords)
+ {
+ s_StringBuilder.Append("-");
+ s_StringBuilder.Append(keyword);
+ }
+
+ newMaterial.name = s_StringBuilder.ToString();
+ }
+
+#if UNITY_EDITOR
+ protected override void Reset()
+ {
+ if (!isActiveAndEnabled) return;
+ SetMaterialDirty();
+ SetVerticesDirty();
+ SetEffectParamsDirty();
+ }
+
+ protected override void OnValidate()
+ {
+ if (!isActiveAndEnabled) return;
+ SetVerticesDirty();
+ SetEffectParamsDirty();
+ }
+#endif
+
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+
+ if (paramTex != null)
+ {
+ paramTex.Register(this);
+ }
+
+ SetMaterialDirty();
+ SetEffectParamsDirty();
+
+ // foreach (var mr in GetComponentsInChildren<UIEffectMaterialResolver> ())
+ // {
+ // mr.GetComponent<Graphic> ().SetMaterialDirty ();
+ // mr.GetComponent<Graphic> ().SetVerticesDirty ();
+ // }
+ }
+
+ /// <summary>
+ /// This function is called when the behaviour becomes disabled () or inactive.
+ /// </summary>
+ protected override void OnDisable()
+ {
+ base.OnDisable();
+
+ SetMaterialDirty();
+
+ if (paramTex != null)
+ {
+ paramTex.Unregister(this);
+ }
+
+ MaterialCache.Unregister(_effectMaterialHash);
+ _effectMaterialHash = k_InvalidHash;
+ }
+
+ // protected override void OnDidApplyAnimationProperties()
+ // {
+ // SetEffectParamsDirty();
+ // }
+
+ // protected override void OnTextChanged (UnityEngine.Object obj)
+ // {
+ // base.OnTextChanged (obj);
+ //
+ //
+ // foreach (var sm in GetComponentsInChildren<TMPro.TMP_SubMeshUI> ())
+ // {
+ // if(!sm.GetComponent<UIEffectMaterialResolver>())
+ // {
+ // var mr = sm.gameObject.AddComponent<UIEffectMaterialResolver> ();
+ //
+ // targetGraphic.SetAllDirty ();
+ // //targetGraphic.SetVerticesDirty ();
+ //
+ // //mr.GetComponent<Graphic> ().SetMaterialDirty ();
+ // //mr.GetComponent<Graphic> ().SetVerticesDirty ();
+ //
+ //
+ // }
+ // }
+ // }
+ }
+}
diff --git a/Assets/Scripts/Common/BaseMaterialEffect.cs.meta b/Assets/Scripts/Common/BaseMaterialEffect.cs.meta
new file mode 100644
index 0000000..7b7e351
--- /dev/null
+++ b/Assets/Scripts/Common/BaseMaterialEffect.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: e8b7ed62cf1444b4ebfc5e5338bc6682
+timeCreated: 1485321967
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Common/BaseMeshEffect.cs b/Assets/Scripts/Common/BaseMeshEffect.cs
new file mode 100644
index 0000000..40d4e66
--- /dev/null
+++ b/Assets/Scripts/Common/BaseMeshEffect.cs
@@ -0,0 +1,229 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.EventSystems;
+using UnityEngine.UI;
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Base class for effects that modify the generated Mesh.
+ /// It works well not only for standard Graphic components (Image, RawImage, Text, etc.) but also for TextMeshPro and TextMeshProUGUI.
+ /// </summary>
+ [RequireComponent(typeof(Graphic))]
+ [RequireComponent(typeof(RectTransform))]
+ [ExecuteInEditMode]
+ public abstract class BaseMeshEffect : UIBehaviour, IMeshModifier
+ {
+ RectTransform _rectTransform;
+ Graphic _graphic;
+ GraphicConnector _connector;
+
+ /// <summary>
+ /// The Graphic attached to this GameObject.
+ /// </summary>
+ protected GraphicConnector connector
+ {
+ get { return _connector ?? (_connector = GraphicConnector.FindConnector(graphic)); }
+ }
+
+ /// <summary>
+ /// The Graphic attached to this GameObject.
+ /// </summary>
+ public Graphic graphic
+ {
+ get { return _graphic ? _graphic : _graphic = GetComponent<Graphic>(); }
+ }
+
+ /// <summary>
+ /// The RectTransform attached to this GameObject.
+ /// </summary>
+ protected RectTransform rectTransform
+ {
+ get { return _rectTransform ? _rectTransform : _rectTransform = GetComponent<RectTransform>(); }
+ }
+
+ internal readonly List<UISyncEffect> syncEffects = new List<UISyncEffect>(0);
+
+ /// <summary>
+ /// Call used to modify mesh. (legacy)
+ /// </summary>
+ /// <param name="mesh">Mesh.</param>
+ public virtual void ModifyMesh(Mesh mesh)
+ {
+ }
+
+ /// <summary>
+ /// Call used to modify mesh.
+ /// </summary>
+ /// <param name="vh">VertexHelper.</param>
+ public virtual void ModifyMesh(VertexHelper vh)
+ {
+ ModifyMesh(vh, graphic);
+ }
+
+ public virtual void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ }
+
+ /// <summary>
+ /// Mark the vertices as dirty.
+ /// </summary>
+ protected virtual void SetVerticesDirty()
+ {
+ connector.SetVerticesDirty(graphic);
+
+ foreach (var effect in syncEffects)
+ {
+ effect.SetVerticesDirty();
+ }
+
+// #if TMP_PRESENT
+// if (textMeshPro)
+// {
+// foreach (var info in textMeshPro.textInfo.meshInfo)
+// {
+// var mesh = info.mesh;
+// if (mesh)
+// {
+// mesh.Clear();
+// mesh.vertices = info.vertices;
+// mesh.uv = info.uvs0;
+// mesh.uv2 = info.uvs2;
+// mesh.colors32 = info.colors32;
+// mesh.normals = info.normals;
+// mesh.tangents = info.tangents;
+// mesh.triangles = info.triangles;
+// }
+// }
+//
+// if (canvasRenderer)
+// {
+// canvasRenderer.SetMesh(textMeshPro.mesh);
+//
+// GetComponentsInChildren(false, s_SubMeshUIs);
+// foreach (var sm in s_SubMeshUIs)
+// {
+// sm.canvasRenderer.SetMesh(sm.mesh);
+// }
+//
+// s_SubMeshUIs.Clear();
+// }
+//
+// textMeshPro.havePropertiesChanged = true;
+// }
+// else
+// #endif
+// if (graphic)
+// {
+// graphic.SetVerticesDirty();
+// }
+ }
+
+
+ //################################
+ // Protected Members.
+ //################################
+ /// <summary>
+ /// Should the effect modify the mesh directly for TMPro?
+ /// </summary>
+ // protected virtual bool isLegacyMeshModifier
+ // {
+ // get { return false; }
+ // }
+// protected virtual void Initialize()
+// {
+// if (_initialized) return;
+//
+// _initialized = true;
+// _graphic = _graphic ? _graphic : GetComponent<Graphic>();
+//
+// _connector = GraphicConnector.FindConnector(_graphic);
+//
+// // _canvasRenderer = _canvasRenderer ?? GetComponent<CanvasRenderer> ();
+// _rectTransform = _rectTransform ? _rectTransform : GetComponent<RectTransform>();
+// // #if TMP_PRESENT
+// // _textMeshPro = _textMeshPro ?? GetComponent<TMP_Text> ();
+// // #endif
+// }
+
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ protected override void OnEnable()
+ {
+ connector.OnEnable(graphic);
+ SetVerticesDirty();
+
+ // SetVerticesDirty();
+// #if TMP_PRESENT
+ // if (textMeshPro)
+ // {
+ // TMPro_EventManager.TEXT_CHANGED_EVENT.Add (OnTextChanged);
+ // }
+ // #endif
+ //
+ // #if UNITY_EDITOR && TMP_PRESENT
+ // if (graphic && textMeshPro)
+ // {
+ // GraphicRebuildTracker.TrackGraphic (graphic);
+ // }
+ // #endif
+ //
+ // #if UNITY_5_6_OR_NEWER
+ // if (graphic)
+ // {
+ // AdditionalCanvasShaderChannels channels = requiredChannels;
+ // var canvas = graphic.canvas;
+ // if (canvas && (canvas.additionalShaderChannels & channels) != channels)
+ // {
+ // Debug.LogWarningFormat (this, "Enable {1} of Canvas.additionalShaderChannels to use {0}.", GetType ().Name, channels);
+ // }
+ // }
+ // #endif
+ }
+
+ /// <summary>
+ /// This function is called when the behaviour becomes disabled () or inactive.
+ /// </summary>
+ protected override void OnDisable()
+ {
+ connector.OnDisable(graphic);
+ SetVerticesDirty();
+ }
+
+ /// <summary>
+ /// Mark the effect parameters as dirty.
+ /// </summary>
+ protected virtual void SetEffectParamsDirty()
+ {
+ if (!isActiveAndEnabled) return;
+ SetVerticesDirty();
+ }
+
+ /// <summary>
+ /// Callback for when properties have been changed by animation.
+ /// </summary>
+ protected override void OnDidApplyAnimationProperties()
+ {
+ if (!isActiveAndEnabled) return;
+ SetEffectParamsDirty();
+ }
+
+#if UNITY_EDITOR
+ protected override void Reset()
+ {
+ if (!isActiveAndEnabled) return;
+ SetVerticesDirty();
+ }
+
+ /// <summary>
+ /// This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
+ /// </summary>
+ protected override void OnValidate()
+ {
+ if (!isActiveAndEnabled) return;
+ SetEffectParamsDirty();
+ }
+#endif
+ }
+}
diff --git a/Assets/Scripts/Common/BaseMeshEffect.cs.meta b/Assets/Scripts/Common/BaseMeshEffect.cs.meta
new file mode 100644
index 0000000..1d3c8d1
--- /dev/null
+++ b/Assets/Scripts/Common/BaseMeshEffect.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 229ee7044e2514b0e9bd9fd40a2baa3a
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Common/EffectPlayer.cs b/Assets/Scripts/Common/EffectPlayer.cs
new file mode 100644
index 0000000..f60165a
--- /dev/null
+++ b/Assets/Scripts/Common/EffectPlayer.cs
@@ -0,0 +1,154 @@
+using UnityEngine;
+using System;
+using System.Collections.Generic;
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Effect player.
+ /// </summary>
+ [Serializable]
+ public class EffectPlayer
+ {
+ //################################
+ // Public Members.
+ //################################
+ /// <summary>
+ /// Gets or sets a value indicating whether is playing.
+ /// </summary>
+ [Header("Effect Player")] [Tooltip("Playing.")]
+ public bool play = false;
+
+ /// <summary>
+ /// Gets or sets the delay before looping.
+ /// </summary>
+ [Tooltip("Initial play delay.")] [Range(0f, 10f)]
+ public float initialPlayDelay = 0;
+
+ /// <summary>
+ /// Gets or sets the duration.
+ /// </summary>
+ [Tooltip("Duration.")] [Range(0.01f, 10f)]
+ public float duration = 1;
+
+ /// <summary>
+ /// Gets or sets a value indicating whether can loop.
+ /// </summary>
+ [Tooltip("Loop.")] public bool loop = false;
+
+ /// <summary>
+ /// Gets or sets the delay before looping.
+ /// </summary>
+ [Tooltip("Delay before looping.")] [Range(0f, 10f)]
+ public float loopDelay = 0;
+
+ /// <summary>
+ /// Gets or sets the update mode.
+ /// </summary>
+ [Tooltip("Update mode")] public AnimatorUpdateMode updateMode = AnimatorUpdateMode.Normal;
+
+ static List<Action> s_UpdateActions;
+
+ /// <summary>
+ /// Register player.
+ /// </summary>
+ public void OnEnable(Action<float> callback = null)
+ {
+ if (s_UpdateActions == null)
+ {
+ s_UpdateActions = new List<Action>();
+ Canvas.willRenderCanvases += () =>
+ {
+ var count = s_UpdateActions.Count;
+ for (int i = 0; i < count; i++)
+ {
+ s_UpdateActions[i].Invoke();
+ }
+ };
+ }
+
+ s_UpdateActions.Add(OnWillRenderCanvases);
+
+ if (play)
+ {
+ _time = -initialPlayDelay;
+ }
+ else
+ {
+ _time = 0;
+ }
+
+ _callback = callback;
+ }
+
+ /// <summary>
+ /// Unregister player.
+ /// </summary>
+ public void OnDisable()
+ {
+ _callback = null;
+ s_UpdateActions.Remove(OnWillRenderCanvases);
+ }
+
+ /// <summary>
+ /// Start playing.
+ /// </summary>
+ public void Play(bool reset, Action<float> callback = null)
+ {
+ if (reset)
+ {
+ _time = 0;
+ }
+
+ play = true;
+ if (callback != null)
+ {
+ _callback = callback;
+ }
+ }
+
+ /// <summary>
+ /// Stop playing.
+ /// </summary>
+ public void Stop(bool reset)
+ {
+ if (reset)
+ {
+ _time = 0;
+ if (_callback != null)
+ {
+ _callback(_time);
+ }
+ }
+
+ play = false;
+ }
+
+ //################################
+ // Private Members.
+ //################################
+ float _time = 0;
+ Action<float> _callback;
+
+ void OnWillRenderCanvases()
+ {
+ if (!play || !Application.isPlaying || _callback == null)
+ {
+ return;
+ }
+
+ _time += updateMode == AnimatorUpdateMode.UnscaledTime
+ ? Time.unscaledDeltaTime
+ : Time.deltaTime;
+ var current = _time / duration;
+
+ if (duration <= _time)
+ {
+ play = loop;
+ _time = loop ? -loopDelay : 0;
+ }
+
+ _callback(current);
+ }
+ }
+}
diff --git a/Assets/Scripts/Common/EffectPlayer.cs.meta b/Assets/Scripts/Common/EffectPlayer.cs.meta
new file mode 100644
index 0000000..661e073
--- /dev/null
+++ b/Assets/Scripts/Common/EffectPlayer.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 1656fb67110cd44298010d95c324e87a
+timeCreated: 1528296875
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Common/GraphicConnector.cs b/Assets/Scripts/Common/GraphicConnector.cs
new file mode 100644
index 0000000..3046297
--- /dev/null
+++ b/Assets/Scripts/Common/GraphicConnector.cs
@@ -0,0 +1,151 @@
+using UnityEngine;
+using UnityEngine.UI;
+using System;
+using System.Collections.Generic;
+
+namespace Coffee.UIEffects
+{
+ 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 GraphicConnector s_EmptyConnector = new GraphicConnector();
+
+#if UNITY_EDITOR
+ [UnityEditor.InitializeOnLoadMethod]
+#endif
+ [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+ private static void Init()
+ {
+ AddConnector(new GraphicConnector());
+ }
+
+ protected static void AddConnector(GraphicConnector connector)
+ {
+ s_Connectors.Add(connector);
+ s_Connectors.Sort((x, y) => y.priority - x.priority);
+ }
+
+ public static GraphicConnector FindConnector(Graphic graphic)
+ {
+ if (!graphic) return s_EmptyConnector;
+
+ var type = graphic.GetType();
+ GraphicConnector connector = null;
+ if (s_ConnectorMap.TryGetValue(type, out connector)) return connector;
+
+ foreach (var c in s_Connectors)
+ {
+ if (!c.IsValid(graphic)) continue;
+
+ s_ConnectorMap.Add(type, c);
+ return c;
+ }
+
+ return s_EmptyConnector;
+ }
+
+ /// <summary>
+ /// Connector priority.
+ /// </summary>
+ protected virtual int priority
+ {
+ get { return -1; }
+ }
+
+ /// <summary>
+ /// Extra channel.
+ /// </summary>
+ public virtual AdditionalCanvasShaderChannels extraChannel
+ {
+ get { return AdditionalCanvasShaderChannels.TexCoord1; }
+ }
+
+ /// <summary>
+ /// The connector is valid for the component.
+ /// </summary>
+ protected virtual bool IsValid(Graphic graphic)
+ {
+ return true;
+ }
+
+ /// <summary>
+ /// Find effect shader.
+ /// </summary>
+ public virtual Shader FindShader(string shaderName)
+ {
+ return Shader.Find("Hidden/" + shaderName);
+ }
+
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ public virtual void OnEnable(Graphic graphic)
+ {
+ }
+
+ /// <summary>
+ /// This function is called when the behaviour becomes disabled () or inactive.
+ /// </summary>
+ public virtual void OnDisable(Graphic graphic)
+ {
+ }
+
+ /// <summary>
+ /// Mark the vertices as dirty.
+ /// </summary>
+ public virtual void SetVerticesDirty(Graphic graphic)
+ {
+ if (graphic)
+ graphic.SetVerticesDirty();
+ }
+
+ /// <summary>
+ /// Mark the material as dirty.
+ /// </summary>
+ public virtual void SetMaterialDirty(Graphic graphic)
+ {
+ if (graphic)
+ graphic.SetMaterialDirty();
+ }
+
+ /// <summary>
+ /// Gets position factor for area.
+ /// </summary>
+ public virtual void GetPositionFactor(EffectArea area, int index, Rect rect, Vector2 position, out float x, out float y)
+ {
+ if (area == EffectArea.Fit)
+ {
+ x = Mathf.Clamp01((position.x - rect.xMin) / rect.width);
+ y = Mathf.Clamp01((position.y - rect.yMin) / rect.height);
+ }
+ else
+ {
+ x = Mathf.Clamp01(position.x / rect.width + 0.5f);
+ y = Mathf.Clamp01(position.y / rect.height + 0.5f);
+ }
+ }
+
+ public virtual bool IsText(Graphic graphic)
+ {
+ return graphic && graphic is Text;
+ }
+
+ public virtual void SetExtraChannel(ref UIVertex vertex, Vector2 value)
+ {
+ vertex.uv1 = value;
+ }
+
+ /// <summary>
+ /// Normalize vertex position by local matrix.
+ /// </summary>
+ public virtual void GetNormalizedFactor(EffectArea area, int index, Matrix2x3 matrix, Vector2 position,
+ out Vector2 normalizedPos)
+ {
+ normalizedPos = matrix * position;
+ }
+ }
+}
diff --git a/Assets/Scripts/Common/GraphicConnector.cs.meta b/Assets/Scripts/Common/GraphicConnector.cs.meta
new file mode 100644
index 0000000..5652017
--- /dev/null
+++ b/Assets/Scripts/Common/GraphicConnector.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 66636f82e05e6453781a33c8b7da8b93
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Common/MaterialCache.cs b/Assets/Scripts/Common/MaterialCache.cs
new file mode 100644
index 0000000..8d8ed93
--- /dev/null
+++ b/Assets/Scripts/Common/MaterialCache.cs
@@ -0,0 +1,77 @@
+using System.Collections.Generic;
+using System.Linq;
+using System;
+using UnityEngine;
+using System.Text;
+using UnityEngine.UI;
+
+namespace Coffee.UIEffects
+{
+ public class MaterialCache
+ {
+ static Dictionary<Hash128, MaterialEntry> materialMap = new Dictionary<Hash128, MaterialEntry>();
+
+ private class MaterialEntry
+ {
+ public Material material;
+ public int referenceCount;
+
+ public void Release()
+ {
+ if (material)
+ {
+ UnityEngine.Object.DestroyImmediate(material, false);
+ }
+
+ material = null;
+ }
+ }
+
+#if UNITY_EDITOR
+ [UnityEditor.InitializeOnLoadMethod]
+ private static void ClearCache()
+ {
+ foreach (var entry in materialMap.Values)
+ {
+ entry.Release();
+ }
+
+ materialMap.Clear();
+ }
+#endif
+
+ public static Material Register(Material baseMaterial, Hash128 hash,
+ System.Action<Material, Graphic> onModifyMaterial, Graphic graphic)
+ {
+ if (!hash.isValid) return null;
+
+ MaterialEntry entry;
+ if (!materialMap.TryGetValue(hash, out entry))
+ {
+ entry = new MaterialEntry()
+ {
+ material = new Material(baseMaterial)
+ {
+ hideFlags = HideFlags.HideAndDontSave,
+ },
+ };
+
+ onModifyMaterial(entry.material, graphic);
+ materialMap.Add(hash, entry);
+ }
+
+ entry.referenceCount++;
+ return entry.material;
+ }
+
+ public static void Unregister(Hash128 hash)
+ {
+ MaterialEntry entry;
+ if (!hash.isValid || !materialMap.TryGetValue(hash, out entry)) return;
+ if (--entry.referenceCount > 0) return;
+
+ entry.Release();
+ materialMap.Remove(hash);
+ }
+ }
+}
diff --git a/Assets/Scripts/Common/MaterialCache.cs.meta b/Assets/Scripts/Common/MaterialCache.cs.meta
new file mode 100644
index 0000000..434e1ff
--- /dev/null
+++ b/Assets/Scripts/Common/MaterialCache.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 2160d2c55a6100642b6c7ba09df935da
+timeCreated: 1528509206
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Common/Matrix2x3.cs b/Assets/Scripts/Common/Matrix2x3.cs
new file mode 100644
index 0000000..ec2cb69
--- /dev/null
+++ b/Assets/Scripts/Common/Matrix2x3.cs
@@ -0,0 +1,33 @@
+using UnityEngine;
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Matrix2x3.
+ /// </summary>
+ public struct Matrix2x3
+ {
+ public float m00, m01, m02, m10, m11, m12;
+
+ public Matrix2x3(Rect rect, float cos, float sin)
+ {
+ const float center = 0.5f;
+ float dx = -rect.xMin / rect.width - center;
+ float dy = -rect.yMin / rect.height - center;
+ m00 = cos / rect.width;
+ m01 = -sin / rect.height;
+ m02 = dx * cos - dy * sin + center;
+ m10 = sin / rect.width;
+ m11 = cos / rect.height;
+ m12 = dx * sin + dy * cos + center;
+ }
+
+ public static Vector2 operator *(Matrix2x3 m, Vector2 v)
+ {
+ return new Vector2(
+ (m.m00 * v.x) + (m.m01 * v.y) + m.m02,
+ (m.m10 * v.x) + (m.m11 * v.y) + m.m12
+ );
+ }
+ }
+}
diff --git a/Assets/Scripts/Common/Matrix2x3.cs.meta b/Assets/Scripts/Common/Matrix2x3.cs.meta
new file mode 100644
index 0000000..70ee757
--- /dev/null
+++ b/Assets/Scripts/Common/Matrix2x3.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5a9b962044ca64867b713425f7e5daab
+timeCreated: 1527590245
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Common/Packer.cs b/Assets/Scripts/Common/Packer.cs
new file mode 100644
index 0000000..ffdb64f
--- /dev/null
+++ b/Assets/Scripts/Common/Packer.cs
@@ -0,0 +1,61 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public static class Packer
+{
+ /// <summary>
+ /// Pack 4 low-precision [0-1] floats values to a float.
+ /// Each value [0-1] has 64 steps(6 bits).
+ /// </summary>
+ public static float ToFloat(float x, float y, float z, float w)
+ {
+ x = x < 0 ? 0 : 1 < x ? 1 : x;
+ y = y < 0 ? 0 : 1 < y ? 1 : y;
+ z = z < 0 ? 0 : 1 < z ? 1 : z;
+ w = w < 0 ? 0 : 1 < w ? 1 : w;
+ const int PRECISION = (1 << 6) - 1;
+ return (Mathf.FloorToInt(w * PRECISION) << 18)
+ + (Mathf.FloorToInt(z * PRECISION) << 12)
+ + (Mathf.FloorToInt(y * PRECISION) << 6)
+ + Mathf.FloorToInt(x * PRECISION);
+ }
+
+ /// <summary>
+ /// Pack 4 low-precision [0-1] floats values to a float.
+ /// Each value [0-1] has 64 steps(6 bits).
+ /// </summary>
+ public static float ToFloat(Vector4 factor)
+ {
+ return ToFloat(Mathf.Clamp01(factor.x), Mathf.Clamp01(factor.y), Mathf.Clamp01(factor.z),
+ Mathf.Clamp01(factor.w));
+ }
+
+ /// <summary>
+ /// Pack 1 middle-precision & 2 low-precision [0-1] floats values to a float.
+ /// z value [0-1] has 4096 steps(12 bits) and xy value [0-1] has 64 steps(6 bits).
+ /// </summary>
+ public static float ToFloat(float x, float y, float z)
+ {
+ x = x < 0 ? 0 : 1 < x ? 1 : x;
+ y = y < 0 ? 0 : 1 < y ? 1 : y;
+ z = z < 0 ? 0 : 1 < z ? 1 : z;
+ const int PRECISION = (1 << 8) - 1;
+ return (Mathf.FloorToInt(z * PRECISION) << 16)
+ + (Mathf.FloorToInt(y * PRECISION) << 8)
+ + Mathf.FloorToInt(x * PRECISION);
+ }
+
+ /// <summary>
+ /// Pack 2 low-precision [0-1] floats values to a float.
+ /// Each value [0-1] has 4096 steps(12 bits).
+ /// </summary>
+ public static float ToFloat(float x, float y)
+ {
+ x = x < 0 ? 0 : 1 < x ? 1 : x;
+ y = y < 0 ? 0 : 1 < y ? 1 : y;
+ const int PRECISION = (1 << 12) - 1;
+ return (Mathf.FloorToInt(y * PRECISION) << 12)
+ + Mathf.FloorToInt(x * PRECISION);
+ }
+}
diff --git a/Assets/Scripts/Common/Packer.cs.meta b/Assets/Scripts/Common/Packer.cs.meta
new file mode 100644
index 0000000..4105720
--- /dev/null
+++ b/Assets/Scripts/Common/Packer.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: b4970b3a69d3b472b8d66c1d92ec7bad
+timeCreated: 1527590285
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Common/ParameterTexture.cs b/Assets/Scripts/Common/ParameterTexture.cs
new file mode 100644
index 0000000..3249828
--- /dev/null
+++ b/Assets/Scripts/Common/ParameterTexture.cs
@@ -0,0 +1,190 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Rendering;
+using System;
+
+namespace Coffee.UIEffects
+{
+ public interface IParameterTexture
+ {
+ int parameterIndex { get; set; }
+
+ ParameterTexture paramTex { get; }
+ }
+
+ /// <summary>
+ /// Parameter texture.
+ /// </summary>
+ [System.Serializable]
+ public class ParameterTexture
+ {
+ //################################
+ // Public Members.
+ //################################
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Coffee.UIEffects.ParameterTexture"/> class.
+ /// </summary>
+ /// <param name="channels">Channels.</param>
+ /// <param name="instanceLimit">Instance limit.</param>
+ /// <param name="propertyName">Property name.</param>
+ public ParameterTexture(int channels, int instanceLimit, string propertyName)
+ {
+ _propertyName = propertyName;
+ _channels = ((channels - 1) / 4 + 1) * 4;
+ _instanceLimit = ((instanceLimit - 1) / 2 + 1) * 2;
+ _data = new byte[_channels * _instanceLimit];
+
+ _stack = new Stack<int>(_instanceLimit);
+ for (int i = 1; i < _instanceLimit + 1; i++)
+ {
+ _stack.Push(i);
+ }
+ }
+
+
+ /// <summary>
+ /// Register the specified target.
+ /// </summary>
+ /// <param name="target">Target.</param>
+ public void Register(IParameterTexture target)
+ {
+ Initialize();
+ if (target.parameterIndex <= 0 && 0 < _stack.Count)
+ {
+ target.parameterIndex = _stack.Pop();
+// Debug.LogFormat("<color=green>@@@ Register {0} : {1}</color>", target, target.parameterIndex);
+ }
+ }
+
+ /// <summary>
+ /// Unregister the specified target.
+ /// </summary>
+ /// <param name="target">Target.</param>
+ public void Unregister(IParameterTexture target)
+ {
+ if (0 < target.parameterIndex)
+ {
+// Debug.LogFormat("<color=red>@@@ Unregister {0} : {1}</color>", target, target.parameterIndex);
+ _stack.Push(target.parameterIndex);
+ target.parameterIndex = 0;
+ }
+ }
+
+ /// <summary>
+ /// Sets the data.
+ /// </summary>
+ /// <param name="target">Target.</param>
+ /// <param name="channelId">Channel identifier.</param>
+ /// <param name="value">Value.</param>
+ public void SetData(IParameterTexture target, int channelId, byte value)
+ {
+ int index = (target.parameterIndex - 1) * _channels + channelId;
+ if (0 < target.parameterIndex && _data[index] != value)
+ {
+ _data[index] = value;
+ _needUpload = true;
+ }
+ }
+
+ /// <summary>
+ /// Sets the data.
+ /// </summary>
+ /// <param name="target">Target.</param>
+ /// <param name="channelId">Channel identifier.</param>
+ /// <param name="value">Value.</param>
+ public void SetData(IParameterTexture target, int channelId, float value)
+ {
+ SetData(target, channelId, (byte) (Mathf.Clamp01(value) * 255));
+ }
+
+ /// <summary>
+ /// Registers the material.
+ /// </summary>
+ /// <param name="mat">Mat.</param>
+ public void RegisterMaterial(Material mat)
+ {
+ if (_propertyId == 0)
+ {
+ _propertyId = Shader.PropertyToID(_propertyName);
+ }
+
+ if (mat)
+ {
+ mat.SetTexture(_propertyId, _texture);
+ }
+ }
+
+ /// <summary>
+ /// Gets the index of the normalized.
+ /// </summary>
+ /// <returns>The normalized index.</returns>
+ /// <param name="target">Target.</param>
+ public float GetNormalizedIndex(IParameterTexture target)
+ {
+ return ((float) target.parameterIndex - 0.5f) / _instanceLimit;
+ }
+
+
+ //################################
+ // Private Members.
+ //################################
+
+ Texture2D _texture;
+ bool _needUpload;
+ int _propertyId;
+ readonly string _propertyName;
+ readonly int _channels;
+ readonly int _instanceLimit;
+ readonly byte[] _data;
+ readonly Stack<int> _stack;
+ static List<Action> updates;
+
+ /// <summary>
+ /// Initialize this instance.
+ /// </summary>
+ void Initialize()
+ {
+#if UNITY_EDITOR
+ if (!UnityEditor.EditorApplication.isPlaying && UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
+ {
+ return;
+ }
+#endif
+ if (updates == null)
+ {
+ updates = new List<Action>();
+ Canvas.willRenderCanvases += () =>
+ {
+ var count = updates.Count;
+ for (int i = 0; i < count; i++)
+ {
+ updates[i].Invoke();
+ }
+ };
+ }
+
+ if (!_texture)
+ {
+ bool isLinear = QualitySettings.activeColorSpace == ColorSpace.Linear;
+ _texture = new Texture2D(_channels / 4, _instanceLimit, TextureFormat.RGBA32, false, isLinear);
+ _texture.filterMode = FilterMode.Point;
+ _texture.wrapMode = TextureWrapMode.Clamp;
+
+ updates.Add(UpdateParameterTexture);
+ _needUpload = true;
+ }
+ }
+
+ void UpdateParameterTexture()
+ {
+ if (_needUpload && _texture)
+ {
+ _needUpload = false;
+ _texture.LoadRawTextureData(_data);
+ _texture.Apply(false, false);
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/Common/ParameterTexture.cs.meta b/Assets/Scripts/Common/ParameterTexture.cs.meta
new file mode 100644
index 0000000..8b718d0
--- /dev/null
+++ b/Assets/Scripts/Common/ParameterTexture.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 65eafa89b3a3a494a99e185423ba6cad
+timeCreated: 1533006319
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor.meta b/Assets/Scripts/Editor.meta
new file mode 100644
index 0000000..1e9742d
--- /dev/null
+++ b/Assets/Scripts/Editor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ee1bfc8c299e6482cb7175ba2f94495a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/ImportSampleMenu.cs b/Assets/Scripts/Editor/ImportSampleMenu.cs
new file mode 100644
index 0000000..c53fc9b
--- /dev/null
+++ b/Assets/Scripts/Editor/ImportSampleMenu.cs
@@ -0,0 +1,75 @@
+#if !UNITY_2019_1_OR_NEWER
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using UnityEditor;
+
+namespace Coffee.UIEffects
+{
+ public static class ImportSampleMenu
+ {
+ private const string jsonGuid = "546af75b6221c4768be79d67c9cea1fb";
+
+ [MenuItem("Assets/Samples/UIEffect/Import Demo")]
+ private static void ImportDemo()
+ {
+ ImportSample(jsonGuid, "Demo");
+ }
+
+ private static void ImportSample(string jsonGuid, string sampleName)
+ {
+ var jsonPath = AssetDatabase.GUIDToAssetPath(jsonGuid);
+ var json = File.ReadAllText(jsonPath);
+ var version = Regex.Match(json, "\"version\"\\s*:\\s*\"([^\"]+)\"").Groups[1].Value;
+ var displayName = Regex.Match(json, "\"displayName\"\\s*:\\s*\"([^\"]+)\"").Groups[1].Value;
+ var src = string.Format("{0}/Samples~/{1}", Path.GetDirectoryName(jsonPath), sampleName);
+ var srcAlt = string.Format("{0}/Samples/{1}", Path.GetDirectoryName(jsonPath), sampleName);
+ var dst = string.Format("Assets/Samples/{0}/{1}/{2}", displayName, version, sampleName);
+ var previousPath = GetPreviousSamplePath(displayName, sampleName);
+
+ // Remove the previous sample directory.
+ if (!string.IsNullOrEmpty(previousPath))
+ {
+ var msg = "A different version of the sample is already imported at\n\n"
+ + previousPath
+ + "\n\nIt will be deleted when you update. Are you sure you want to continue?";
+ if (!EditorUtility.DisplayDialog("Sample Importer", msg, "OK", "Cancel"))
+ return;
+
+ FileUtil.DeleteFileOrDirectory(previousPath);
+
+ var metaFile = previousPath + ".meta";
+ if (File.Exists(metaFile))
+ FileUtil.DeleteFileOrDirectory(metaFile);
+ }
+
+ if (!Directory.Exists(dst))
+ FileUtil.DeleteFileOrDirectory(dst);
+
+ var dstDir = Path.GetDirectoryName(dst);
+ if (!Directory.Exists(dstDir))
+ Directory.CreateDirectory(dstDir);
+
+ if (Directory.Exists(src))
+ FileUtil.CopyFileOrDirectory(src, dst);
+ else if (Directory.Exists(srcAlt))
+ FileUtil.CopyFileOrDirectory(srcAlt, dst);
+ else
+ throw new DirectoryNotFoundException(src);
+
+ AssetDatabase.Refresh(ImportAssetOptions.ImportRecursive);
+ }
+
+ private static string GetPreviousSamplePath(string displayName, string sampleName)
+ {
+ var sampleRoot = string.Format("Assets/Samples/{0}", displayName);
+ var sampleRootInfo = new DirectoryInfo(sampleRoot);
+ if (!sampleRootInfo.Exists) return null;
+
+ return sampleRootInfo.GetDirectories()
+ .Select(versionDir => Path.Combine(versionDir.ToString(), sampleName))
+ .FirstOrDefault(Directory.Exists);
+ }
+ }
+}
+#endif
diff --git a/Assets/Scripts/Editor/ImportSampleMenu.cs.meta b/Assets/Scripts/Editor/ImportSampleMenu.cs.meta
new file mode 100644
index 0000000..5057915
--- /dev/null
+++ b/Assets/Scripts/Editor/ImportSampleMenu.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f1d002a431e7c4b1ca5db78469cb0d1c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/MaterialDirtyScope.cs b/Assets/Scripts/Editor/MaterialDirtyScope.cs
new file mode 100644
index 0000000..435e66e
--- /dev/null
+++ b/Assets/Scripts/Editor/MaterialDirtyScope.cs
@@ -0,0 +1,33 @@
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+
+namespace Coffee.UIEffects.Editors
+{
+ /// <summary>
+ /// Changes in this scope cause the graphic's material to be dirty.
+ /// When you change a property, it marks the material as dirty.
+ /// </summary>
+ internal class MaterialDirtyScope : EditorGUI.ChangeCheckScope
+ {
+ readonly Object[] targets;
+
+ public MaterialDirtyScope(Object[] targets)
+ {
+ this.targets = targets;
+ }
+
+ protected override void CloseScope()
+ {
+ if (changed)
+ {
+ foreach (var effect in targets.OfType<BaseMaterialEffect>())
+ {
+ effect.SetMaterialDirty();
+ }
+ }
+
+ base.CloseScope();
+ }
+ }
+}
diff --git a/Assets/Scripts/Editor/MaterialDirtyScope.cs.meta b/Assets/Scripts/Editor/MaterialDirtyScope.cs.meta
new file mode 100644
index 0000000..c0c5053
--- /dev/null
+++ b/Assets/Scripts/Editor/MaterialDirtyScope.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 16857cac7da564347876420ef55a734a
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/UIDissolveEditor.cs b/Assets/Scripts/Editor/UIDissolveEditor.cs
new file mode 100644
index 0000000..29c2782
--- /dev/null
+++ b/Assets/Scripts/Editor/UIDissolveEditor.cs
@@ -0,0 +1,121 @@
+using UnityEditor;
+using UnityEditorInternal;
+using UnityEngine;
+using System.Linq;
+using System.Collections.Generic;
+using UnityEngine.UI;
+
+namespace Coffee.UIEffects.Editors
+{
+ /// <summary>
+ /// UIEffect editor.
+ /// </summary>
+ [CustomEditor(typeof(UIDissolve))]
+ [CanEditMultipleObjects]
+ public class UIDissolveEditor : Editor
+ {
+ SerializedProperty _spEffectFactor;
+ SerializedProperty _spWidth;
+ SerializedProperty _spColor;
+ SerializedProperty _spSoftness;
+ SerializedProperty _spColorMode;
+ SerializedProperty _spTransitionTexture;
+ SerializedProperty _spEffectArea;
+ SerializedProperty _spKeepAspectRatio;
+ SerializedProperty _spReverse;
+ SerializedProperty _spPlay;
+ SerializedProperty _spLoop;
+ SerializedProperty _spLoopDelay;
+ SerializedProperty _spDuration;
+ SerializedProperty _spInitialPlayDelay;
+ SerializedProperty _spUpdateMode;
+
+ //################################
+ // Public/Protected Members.
+ //################################
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ protected void OnEnable()
+ {
+ _spEffectFactor = serializedObject.FindProperty("m_EffectFactor");
+ _spEffectArea = serializedObject.FindProperty("m_EffectArea");
+ _spKeepAspectRatio = serializedObject.FindProperty("m_KeepAspectRatio");
+ _spWidth = serializedObject.FindProperty("m_Width");
+ _spColor = serializedObject.FindProperty("m_Color");
+ _spSoftness = serializedObject.FindProperty("m_Softness");
+ _spColorMode = serializedObject.FindProperty("m_ColorMode");
+ _spTransitionTexture = serializedObject.FindProperty("m_TransitionTexture");
+ _spKeepAspectRatio = serializedObject.FindProperty("m_KeepAspectRatio");
+ _spReverse = serializedObject.FindProperty("m_Reverse");
+ var player = serializedObject.FindProperty("m_Player");
+ _spPlay = player.FindPropertyRelative("play");
+ _spDuration = player.FindPropertyRelative("duration");
+ _spInitialPlayDelay = player.FindPropertyRelative("initialPlayDelay");
+ _spLoop = player.FindPropertyRelative("loop");
+ _spLoopDelay = player.FindPropertyRelative("loopDelay");
+ _spUpdateMode = player.FindPropertyRelative("updateMode");
+ }
+
+ /// <summary>
+ /// Implement this function to make a custom inspector.
+ /// </summary>
+ public override void OnInspectorGUI()
+ {
+ serializedObject.Update();
+
+ //================
+ // Effect setting.
+ //================
+ EditorGUILayout.PropertyField(_spEffectFactor);
+ EditorGUILayout.PropertyField(_spWidth);
+ EditorGUILayout.PropertyField(_spSoftness);
+ EditorGUILayout.PropertyField(_spColor);
+
+ using (new MaterialDirtyScope(targets))
+ {
+ EditorGUILayout.PropertyField(_spColorMode);
+ EditorGUILayout.PropertyField(_spTransitionTexture);
+ }
+
+
+ //================
+ // Advanced option.
+ //================
+ EditorGUILayout.PropertyField(_spEffectArea);
+ EditorGUILayout.PropertyField(_spKeepAspectRatio);
+
+
+ //================
+ // Effect player.
+ //================
+ EditorGUILayout.PropertyField(_spPlay);
+ EditorGUILayout.PropertyField(_spDuration);
+ EditorGUILayout.PropertyField(_spInitialPlayDelay);
+ EditorGUILayout.PropertyField(_spLoop);
+ EditorGUILayout.PropertyField(_spLoopDelay);
+ EditorGUILayout.PropertyField(_spUpdateMode);
+ EditorGUILayout.PropertyField(_spReverse);
+
+
+ // Debug.
+ using (new EditorGUI.DisabledGroupScope(!Application.isPlaying))
+ using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox))
+ {
+ GUILayout.Label("Debug");
+
+ if (GUILayout.Button("Play", "ButtonLeft"))
+ {
+ (target as UIDissolve).Play();
+ }
+
+ if (GUILayout.Button("Stop", "ButtonRight"))
+ {
+ (target as UIDissolve).Stop();
+ }
+ }
+
+ serializedObject.ApplyModifiedProperties();
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Editor/UIDissolveEditor.cs.meta b/Assets/Scripts/Editor/UIDissolveEditor.cs.meta
new file mode 100644
index 0000000..edf071c
--- /dev/null
+++ b/Assets/Scripts/Editor/UIDissolveEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f7f7349a5d61649b69946853317db047
+timeCreated: 1538806040
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/UIEffect-Editor.asmdef b/Assets/Scripts/Editor/UIEffect-Editor.asmdef
new file mode 100644
index 0000000..56826a0
--- /dev/null
+++ b/Assets/Scripts/Editor/UIEffect-Editor.asmdef
@@ -0,0 +1,16 @@
+{
+ "name": "UIEffect-Editor",
+ "references": [
+ "UIEffect"
+ ],
+ "optionalUnityReferences": [],
+ "includePlatforms": [
+ "Editor"
+ ],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": false,
+ "precompiledReferences": [],
+ "autoReferenced": false,
+ "defineConstraints": []
+} \ No newline at end of file
diff --git a/Assets/Scripts/Editor/UIEffect-Editor.asmdef.meta b/Assets/Scripts/Editor/UIEffect-Editor.asmdef.meta
new file mode 100644
index 0000000..a459a69
--- /dev/null
+++ b/Assets/Scripts/Editor/UIEffect-Editor.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 4a03bd468489b4da08c028255886b30d
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/UIEffectEditor.cs b/Assets/Scripts/Editor/UIEffectEditor.cs
new file mode 100644
index 0000000..028ee73
--- /dev/null
+++ b/Assets/Scripts/Editor/UIEffectEditor.cs
@@ -0,0 +1,114 @@
+using UnityEditor;
+using UnityEditorInternal;
+using UnityEngine;
+using System.Linq;
+using System;
+
+namespace Coffee.UIEffects.Editors
+{
+ /// <summary>
+ /// UIEffect editor.
+ /// </summary>
+ [CustomEditor(typeof(UIEffect))]
+ [CanEditMultipleObjects]
+ public class UIEffectEditor : Editor
+ {
+ SerializedProperty _spEffectMode;
+ SerializedProperty _spEffectFactor;
+ SerializedProperty _spColorMode;
+ SerializedProperty _spColorFactor;
+ SerializedProperty _spBlurMode;
+ SerializedProperty _spBlurFactor;
+ SerializedProperty _spAdvancedBlur;
+
+ protected void OnEnable()
+ {
+ _spEffectMode = serializedObject.FindProperty("m_EffectMode");
+ _spEffectFactor = serializedObject.FindProperty("m_EffectFactor");
+ _spColorMode = serializedObject.FindProperty("m_ColorMode");
+ _spColorFactor = serializedObject.FindProperty("m_ColorFactor");
+ _spBlurMode = serializedObject.FindProperty("m_BlurMode");
+ _spBlurFactor = serializedObject.FindProperty("m_BlurFactor");
+ _spAdvancedBlur = serializedObject.FindProperty("m_AdvancedBlur");
+ }
+
+ public override void OnInspectorGUI()
+ {
+ //================
+ // Effect setting.
+ //================
+ using (new MaterialDirtyScope(targets))
+ EditorGUILayout.PropertyField(_spEffectMode);
+
+ // When effect is enable, show parameters.
+ if (_spEffectMode.intValue != (int) EffectMode.None)
+ {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(_spEffectFactor);
+ EditorGUI.indentLevel--;
+ }
+
+
+ //================
+ // Color setting.
+ //================
+ using (new MaterialDirtyScope(targets))
+ EditorGUILayout.PropertyField(_spColorMode);
+
+ // When color is enable, show parameters.
+ {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(_spColorFactor);
+ EditorGUI.indentLevel--;
+ }
+
+
+ //================
+ // Blur setting.
+ //================
+ using (new MaterialDirtyScope(targets))
+ EditorGUILayout.PropertyField(_spBlurMode);
+
+ // When blur is enable, show parameters.
+ if (_spBlurMode.intValue != (int) BlurMode.None)
+ {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(_spBlurFactor);
+
+ // When you change a property, it marks the material as dirty.
+ using (new MaterialDirtyScope(targets))
+ EditorGUILayout.PropertyField(_spAdvancedBlur);
+ EditorGUI.indentLevel--;
+
+ // Advanced blur requires uv2 channel.
+ if (_spAdvancedBlur.boolValue)
+ {
+ ShowCanvasChannelsWarning();
+ }
+ }
+
+ serializedObject.ApplyModifiedProperties();
+ }
+
+ void ShowCanvasChannelsWarning()
+ {
+ var effect = target as UIEffect;
+ if (effect == null || !effect.graphic) return;
+
+ var channel = effect.uvMaskChannel;
+ var canvas = effect.graphic.canvas;
+ if (canvas == null || (canvas.additionalShaderChannels & channel) == channel) return;
+
+ EditorGUILayout.BeginHorizontal();
+ {
+ var msg = string.Format("Enable '{0}' of Canvas.additionalShaderChannels to use 'UIEffect'.", channel);
+ EditorGUILayout.HelpBox(msg, MessageType.Warning);
+ if (GUILayout.Button("Fix"))
+ {
+ canvas.additionalShaderChannels |= channel;
+ }
+ }
+ EditorGUILayout.EndHorizontal();
+ }
+ }
+}
diff --git a/Assets/Scripts/Editor/UIEffectEditor.cs.meta b/Assets/Scripts/Editor/UIEffectEditor.cs.meta
new file mode 100644
index 0000000..02aa24f
--- /dev/null
+++ b/Assets/Scripts/Editor/UIEffectEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 4f7e9f2ce1cb543ca88606769affbe24
+timeCreated: 1487152293
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/UIGradientEditor.cs b/Assets/Scripts/Editor/UIGradientEditor.cs
new file mode 100644
index 0000000..493c51d
--- /dev/null
+++ b/Assets/Scripts/Editor/UIGradientEditor.cs
@@ -0,0 +1,140 @@
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Coffee.UIEffects.Editors
+{
+ /// <summary>
+ /// UIEffect editor.
+ /// </summary>
+ [CustomEditor(typeof(UIGradient))]
+ [CanEditMultipleObjects]
+ public class UIGradientEditor : Editor
+ {
+ private static readonly GUIContent k_TextVerticalOffset = new GUIContent("Vertical Offset");
+ private static readonly GUIContent k_TextHorizontalOffset = new GUIContent("Horizontal Offset");
+ private static readonly GUIContent k_TextOffset = new GUIContent("Offset");
+ private static readonly GUIContent k_TextLeft = new GUIContent("Left");
+ private static readonly GUIContent k_TextRight = new GUIContent("Right");
+ private static readonly GUIContent k_TextTop = new GUIContent("Top");
+ private static readonly GUIContent k_TextBottom = new GUIContent("Bottom");
+ private static readonly GUIContent k_TextColor1 = new GUIContent("Color 1");
+ private static readonly GUIContent k_TextColor2 = new GUIContent("Color 2");
+ private static readonly GUIContent k_TextDiagonalColor = new GUIContent("Diagonal Color");
+
+ SerializedProperty _spDirection;
+ SerializedProperty _spColor1;
+ SerializedProperty _spColor2;
+ SerializedProperty _spColor3;
+ SerializedProperty _spColor4;
+ SerializedProperty _spRotation;
+ SerializedProperty _spOffset1;
+ SerializedProperty _spOffset2;
+ SerializedProperty _spIgnoreAspectRatio;
+ SerializedProperty _spGradientStyle;
+ SerializedProperty _spColorSpace;
+
+ //################################
+ // Public/Protected Members.
+ //################################
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ protected void OnEnable()
+ {
+ _spIgnoreAspectRatio = serializedObject.FindProperty("m_IgnoreAspectRatio");
+ _spDirection = serializedObject.FindProperty("m_Direction");
+ _spColor1 = serializedObject.FindProperty("m_Color1");
+ _spColor2 = serializedObject.FindProperty("m_Color2");
+ _spColor3 = serializedObject.FindProperty("m_Color3");
+ _spColor4 = serializedObject.FindProperty("m_Color4");
+ _spRotation = serializedObject.FindProperty("m_Rotation");
+ _spOffset1 = serializedObject.FindProperty("m_Offset1");
+ _spOffset2 = serializedObject.FindProperty("m_Offset2");
+ _spGradientStyle = serializedObject.FindProperty("m_GradientStyle");
+ _spColorSpace = serializedObject.FindProperty("m_ColorSpace");
+ }
+
+ public override void OnInspectorGUI()
+ {
+ serializedObject.Update();
+
+ //================
+ // Direction.
+ //================
+ EditorGUILayout.PropertyField(_spDirection);
+
+
+ //================
+ // Color.
+ //================
+ switch ((UIGradient.Direction) _spDirection.intValue)
+ {
+ case UIGradient.Direction.Horizontal:
+ EditorGUILayout.PropertyField(_spColor1, k_TextLeft);
+ EditorGUILayout.PropertyField(_spColor2, k_TextRight);
+ break;
+ case UIGradient.Direction.Vertical:
+ EditorGUILayout.PropertyField(_spColor1, k_TextTop);
+ EditorGUILayout.PropertyField(_spColor2, k_TextBottom);
+ break;
+ case UIGradient.Direction.Angle:
+ EditorGUILayout.PropertyField(_spColor1, k_TextColor1);
+ EditorGUILayout.PropertyField(_spColor2, k_TextColor2);
+ break;
+ case UIGradient.Direction.Diagonal:
+ Rect r = EditorGUILayout.GetControlRect(false, 34);
+
+ r = EditorGUI.PrefixLabel(r, k_TextDiagonalColor);
+ float w = r.width / 2;
+
+ EditorGUI.PropertyField(new Rect(r.x, r.y, w, 16), _spColor3, GUIContent.none);
+ EditorGUI.PropertyField(new Rect(r.x + w, r.y, w, 16), _spColor4, GUIContent.none);
+ EditorGUI.PropertyField(new Rect(r.x, r.y + 18, w, 16), _spColor1, GUIContent.none);
+ EditorGUI.PropertyField(new Rect(r.x + w, r.y + 18, w, 16), _spColor2, GUIContent.none);
+ break;
+ }
+
+
+ //================
+ // Angle.
+ //================
+ if ((int) UIGradient.Direction.Angle <= _spDirection.intValue)
+ {
+ EditorGUILayout.PropertyField(_spRotation);
+ }
+
+
+ //================
+ // Offset.
+ //================
+ if ((int) UIGradient.Direction.Diagonal == _spDirection.intValue)
+ {
+ EditorGUILayout.PropertyField(_spOffset1, k_TextVerticalOffset);
+ EditorGUILayout.PropertyField(_spOffset2, k_TextHorizontalOffset);
+ }
+ else
+ {
+ EditorGUILayout.PropertyField(_spOffset1, k_TextOffset);
+ }
+
+
+ //================
+ // Advanced options.
+ //================
+ EditorGUILayout.Space();
+ EditorGUILayout.LabelField("Advanced Options", EditorStyles.boldLabel);
+ EditorGUI.indentLevel++;
+ {
+ //if ((target as UIGradient).targetGraphic is Text)
+ EditorGUILayout.PropertyField(_spGradientStyle);
+
+ EditorGUILayout.PropertyField(_spColorSpace);
+ EditorGUILayout.PropertyField(_spIgnoreAspectRatio);
+ }
+ EditorGUI.indentLevel--;
+
+ serializedObject.ApplyModifiedProperties();
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Editor/UIGradientEditor.cs.meta b/Assets/Scripts/Editor/UIGradientEditor.cs.meta
new file mode 100644
index 0000000..5070c14
--- /dev/null
+++ b/Assets/Scripts/Editor/UIGradientEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: c28dcc885fbba4a5187a6a1aa5fb1b3b
+timeCreated: 1515895646
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/UIHsvModifierEditor.cs b/Assets/Scripts/Editor/UIHsvModifierEditor.cs
new file mode 100644
index 0000000..6d54a55
--- /dev/null
+++ b/Assets/Scripts/Editor/UIHsvModifierEditor.cs
@@ -0,0 +1,53 @@
+using UnityEditor;
+using UnityEditorInternal;
+using UnityEngine;
+using System.Linq;
+
+namespace Coffee.UIEffects.Editors
+{
+ /// <summary>
+ /// UIEffect editor.
+ /// </summary>
+ [CustomEditor(typeof(UIHsvModifier))]
+ [CanEditMultipleObjects]
+ public class UIHsvModifierEditor : Editor
+ {
+ SerializedProperty _spTargetColor;
+ SerializedProperty _spRange;
+ SerializedProperty _spHue;
+ SerializedProperty _spSaturation;
+ SerializedProperty _spValue;
+
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ protected void OnEnable()
+ {
+ _spTargetColor = serializedObject.FindProperty("m_TargetColor");
+ _spRange = serializedObject.FindProperty("m_Range");
+ _spHue = serializedObject.FindProperty("m_Hue");
+ _spSaturation = serializedObject.FindProperty("m_Saturation");
+ _spValue = serializedObject.FindProperty("m_Value");
+ }
+
+
+ /// <summary>
+ /// Implement this function to make a custom inspector.
+ /// </summary>
+ public override void OnInspectorGUI()
+ {
+ serializedObject.Update();
+
+ //================
+ // Effect setting.
+ //================
+ EditorGUILayout.PropertyField(_spTargetColor);
+ EditorGUILayout.PropertyField(_spRange);
+ EditorGUILayout.PropertyField(_spHue);
+ EditorGUILayout.PropertyField(_spSaturation);
+ EditorGUILayout.PropertyField(_spValue);
+
+ serializedObject.ApplyModifiedProperties();
+ }
+ }
+}
diff --git a/Assets/Scripts/Editor/UIHsvModifierEditor.cs.meta b/Assets/Scripts/Editor/UIHsvModifierEditor.cs.meta
new file mode 100644
index 0000000..87f1694
--- /dev/null
+++ b/Assets/Scripts/Editor/UIHsvModifierEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f002ba0ac474d487b936bc046dda56b4
+timeCreated: 1538806052
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/UIShadowEditor.cs b/Assets/Scripts/Editor/UIShadowEditor.cs
new file mode 100644
index 0000000..64f01d6
--- /dev/null
+++ b/Assets/Scripts/Editor/UIShadowEditor.cs
@@ -0,0 +1,62 @@
+using UnityEditor;
+using UnityEditorInternal;
+using UnityEngine;
+
+namespace Coffee.UIEffects.Editors
+{
+ /// <summary>
+ /// UIShadow editor.
+ /// </summary>
+ [CustomEditor(typeof(UIShadow))]
+ [CanEditMultipleObjects]
+ public class UIShadowEditor : Editor
+ {
+ UIEffect uiEffect;
+ SerializedProperty _spStyle;
+ SerializedProperty _spEffectDistance;
+ SerializedProperty _spEffectColor;
+ SerializedProperty _spUseGraphicAlpha;
+ SerializedProperty _spBlurFactor;
+
+ void OnEnable()
+ {
+ uiEffect = (target as UIShadow).GetComponent<UIEffect>();
+ _spStyle = serializedObject.FindProperty("m_Style");
+ _spEffectDistance = serializedObject.FindProperty("m_EffectDistance");
+ _spEffectColor = serializedObject.FindProperty("m_EffectColor");
+ _spUseGraphicAlpha = serializedObject.FindProperty("m_UseGraphicAlpha");
+ _spBlurFactor = serializedObject.FindProperty("m_BlurFactor");
+ }
+
+ /// <summary>
+ /// Implement this function to make a custom inspector.
+ /// </summary>
+ public override void OnInspectorGUI()
+ {
+ serializedObject.Update();
+
+ //================
+ // Shadow setting.
+ //================
+ EditorGUILayout.PropertyField(_spStyle);
+
+ // When shadow is enable, show parameters.
+ if (_spStyle.intValue != (int) ShadowStyle.None)
+ {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(_spEffectDistance);
+ EditorGUILayout.PropertyField(_spEffectColor);
+ EditorGUILayout.PropertyField(_spUseGraphicAlpha);
+
+ if (uiEffect && uiEffect.blurMode != BlurMode.None)
+ {
+ EditorGUILayout.PropertyField(_spBlurFactor);
+ }
+
+ EditorGUI.indentLevel--;
+ }
+
+ serializedObject.ApplyModifiedProperties();
+ }
+ }
+}
diff --git a/Assets/Scripts/Editor/UIShadowEditor.cs.meta b/Assets/Scripts/Editor/UIShadowEditor.cs.meta
new file mode 100644
index 0000000..bc6a832
--- /dev/null
+++ b/Assets/Scripts/Editor/UIShadowEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6e76e7f628f09af449321b4776123f13
+timeCreated: 1487152293
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/UIShinyEditor.cs b/Assets/Scripts/Editor/UIShinyEditor.cs
new file mode 100644
index 0000000..e77432a
--- /dev/null
+++ b/Assets/Scripts/Editor/UIShinyEditor.cs
@@ -0,0 +1,102 @@
+using UnityEditor;
+using UnityEditorInternal;
+using UnityEngine;
+using System.Linq;
+
+namespace Coffee.UIEffects.Editors
+{
+ /// <summary>
+ /// UIEffect editor.
+ /// </summary>
+ [CustomEditor(typeof(UIShiny))]
+ [CanEditMultipleObjects]
+ public class UIShinyEditor : Editor
+ {
+ SerializedProperty _spEffectFactor;
+ SerializedProperty _spWidth;
+ SerializedProperty _spRotation;
+ SerializedProperty _spSoftness;
+ SerializedProperty _spBrightness;
+ SerializedProperty _spGloss;
+ SerializedProperty _spEffectArea;
+ SerializedProperty _spPlay;
+ SerializedProperty _spLoop;
+ SerializedProperty _spLoopDelay;
+ SerializedProperty _spDuration;
+ SerializedProperty _spInitialPlayDelay;
+ SerializedProperty _spUpdateMode;
+
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ protected void OnEnable()
+ {
+ _spEffectFactor = serializedObject.FindProperty("m_EffectFactor");
+ _spEffectArea = serializedObject.FindProperty("m_EffectArea");
+ _spWidth = serializedObject.FindProperty("m_Width");
+ _spRotation = serializedObject.FindProperty("m_Rotation");
+ _spSoftness = serializedObject.FindProperty("m_Softness");
+ _spBrightness = serializedObject.FindProperty("m_Brightness");
+ _spGloss = serializedObject.FindProperty("m_Gloss");
+ var player = serializedObject.FindProperty("m_Player");
+ _spPlay = player.FindPropertyRelative("play");
+ _spDuration = player.FindPropertyRelative("duration");
+ _spInitialPlayDelay = player.FindPropertyRelative("initialPlayDelay");
+ _spLoop = player.FindPropertyRelative("loop");
+ _spLoopDelay = player.FindPropertyRelative("loopDelay");
+ _spUpdateMode = player.FindPropertyRelative("updateMode");
+ }
+
+ /// <summary>
+ /// Implement this function to make a custom inspector.
+ /// </summary>
+ public override void OnInspectorGUI()
+ {
+ serializedObject.Update();
+
+ //================
+ // Effect setting.
+ //================
+ EditorGUILayout.PropertyField(_spEffectFactor);
+ EditorGUILayout.PropertyField(_spWidth);
+ EditorGUILayout.PropertyField(_spRotation);
+ EditorGUILayout.PropertyField(_spSoftness);
+ EditorGUILayout.PropertyField(_spBrightness);
+ EditorGUILayout.PropertyField(_spGloss);
+
+ //================
+ // Advanced option.
+ //================
+ EditorGUILayout.PropertyField(_spEffectArea);
+
+ //================
+ // Effect player.
+ //================
+ EditorGUILayout.PropertyField(_spPlay);
+ EditorGUILayout.PropertyField(_spDuration);
+ EditorGUILayout.PropertyField(_spInitialPlayDelay);
+ EditorGUILayout.PropertyField(_spLoop);
+ EditorGUILayout.PropertyField(_spLoopDelay);
+ EditorGUILayout.PropertyField(_spUpdateMode);
+
+ // Debug.
+ using (new EditorGUI.DisabledGroupScope(!Application.isPlaying))
+ using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox))
+ {
+ GUILayout.Label("Debug");
+
+ if (GUILayout.Button("Play", "ButtonLeft"))
+ {
+ (target as UIShiny).Play();
+ }
+
+ if (GUILayout.Button("Stop", "ButtonRight"))
+ {
+ (target as UIShiny).Stop();
+ }
+ }
+
+ serializedObject.ApplyModifiedProperties();
+ }
+ }
+}
diff --git a/Assets/Scripts/Editor/UIShinyEditor.cs.meta b/Assets/Scripts/Editor/UIShinyEditor.cs.meta
new file mode 100644
index 0000000..7dd653a
--- /dev/null
+++ b/Assets/Scripts/Editor/UIShinyEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0080e984bad7545cd957d9121e99f988
+timeCreated: 1538806052
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Editor/UITransitionEffectEditor.cs b/Assets/Scripts/Editor/UITransitionEffectEditor.cs
new file mode 100644
index 0000000..803c9bf
--- /dev/null
+++ b/Assets/Scripts/Editor/UITransitionEffectEditor.cs
@@ -0,0 +1,115 @@
+using UnityEditor;
+using UnityEditorInternal;
+using UnityEngine;
+using System.Linq;
+
+namespace Coffee.UIEffects.Editors
+{
+ /// <summary>
+ /// UIEffect editor.
+ /// </summary>
+ [CustomEditor(typeof(UITransitionEffect))]
+ [CanEditMultipleObjects]
+ public class UITransitionEffectEditor : Editor
+ {
+ SerializedProperty _spEffectMode;
+ SerializedProperty _spEffectFactor;
+ SerializedProperty _spEffectArea;
+ SerializedProperty _spKeepAspectRatio;
+ SerializedProperty _spDissolveWidth;
+ SerializedProperty _spDissolveSoftness;
+ SerializedProperty _spDissolveColor;
+ SerializedProperty _spTransitionTexture;
+ SerializedProperty _spPlay;
+ SerializedProperty _spLoop;
+ SerializedProperty _spLoopDelay;
+ SerializedProperty _spDuration;
+ SerializedProperty _spInitialPlayDelay;
+ SerializedProperty _spUpdateMode;
+ SerializedProperty _spPassRayOnHidden;
+
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ protected void OnEnable()
+ {
+ _spEffectMode = serializedObject.FindProperty("m_EffectMode");
+ _spEffectFactor = serializedObject.FindProperty("m_EffectFactor");
+ _spEffectArea = serializedObject.FindProperty("m_EffectArea");
+ _spKeepAspectRatio = serializedObject.FindProperty("m_KeepAspectRatio");
+ _spDissolveWidth = serializedObject.FindProperty("m_DissolveWidth");
+ _spDissolveSoftness = serializedObject.FindProperty("m_DissolveSoftness");
+ _spDissolveColor = serializedObject.FindProperty("m_DissolveColor");
+ _spTransitionTexture = serializedObject.FindProperty("m_TransitionTexture");
+ var player = serializedObject.FindProperty("m_Player");
+ _spPlay = player.FindPropertyRelative("play");
+ _spDuration = player.FindPropertyRelative("duration");
+ _spInitialPlayDelay = player.FindPropertyRelative("initialPlayDelay");
+ _spLoop = player.FindPropertyRelative("loop");
+ _spLoopDelay = player.FindPropertyRelative("loopDelay");
+ _spUpdateMode = player.FindPropertyRelative("updateMode");
+ _spPassRayOnHidden = serializedObject.FindProperty("m_PassRayOnHidden");
+ }
+
+ /// <summary>
+ /// Implement this function to make a custom inspector.
+ /// </summary>
+ public override void OnInspectorGUI()
+ {
+ //================
+ // Effect setting.
+ //================
+ using (new MaterialDirtyScope(targets))
+ EditorGUILayout.PropertyField(_spEffectMode);
+
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(_spEffectFactor);
+ if (_spEffectMode.intValue == (int) UITransitionEffect.EffectMode.Dissolve)
+ {
+ EditorGUILayout.PropertyField(_spDissolveWidth);
+ EditorGUILayout.PropertyField(_spDissolveSoftness);
+ EditorGUILayout.PropertyField(_spDissolveColor);
+ }
+
+ EditorGUI.indentLevel--;
+
+ //================
+ // Advanced option.
+ //================
+ EditorGUILayout.PropertyField(_spEffectArea);
+ using (new MaterialDirtyScope(targets))
+ EditorGUILayout.PropertyField(_spTransitionTexture);
+ EditorGUILayout.PropertyField(_spKeepAspectRatio);
+ EditorGUILayout.PropertyField(_spPassRayOnHidden);
+
+ //================
+ // Effect player.
+ //================
+ EditorGUILayout.PropertyField(_spPlay);
+ EditorGUILayout.PropertyField(_spDuration);
+ EditorGUILayout.PropertyField(_spInitialPlayDelay);
+ EditorGUILayout.PropertyField(_spLoop);
+ EditorGUILayout.PropertyField(_spLoopDelay);
+ EditorGUILayout.PropertyField(_spUpdateMode);
+
+ // Debug.
+ using (new EditorGUI.DisabledGroupScope(!Application.isPlaying))
+ using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox))
+ {
+ GUILayout.Label("Debug");
+
+ if (GUILayout.Button("Show", "ButtonLeft"))
+ {
+ (target as UITransitionEffect).Show();
+ }
+
+ if (GUILayout.Button("Hide", "ButtonRight"))
+ {
+ (target as UITransitionEffect).Hide();
+ }
+ }
+
+ serializedObject.ApplyModifiedProperties();
+ }
+ }
+}
diff --git a/Assets/Scripts/Editor/UITransitionEffectEditor.cs.meta b/Assets/Scripts/Editor/UITransitionEffectEditor.cs.meta
new file mode 100644
index 0000000..14054f8
--- /dev/null
+++ b/Assets/Scripts/Editor/UITransitionEffectEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 631f363a54c834f1f846f823b31bd321
+timeCreated: 1538806067
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enums.meta b/Assets/Scripts/Enums.meta
new file mode 100644
index 0000000..d1a3a2a
--- /dev/null
+++ b/Assets/Scripts/Enums.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 78cc1478fd16a484ba11857d5c4f4912
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enums/BlurMode.cs b/Assets/Scripts/Enums/BlurMode.cs
new file mode 100644
index 0000000..e3ef417
--- /dev/null
+++ b/Assets/Scripts/Enums/BlurMode.cs
@@ -0,0 +1,13 @@
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Blur effect mode.
+ /// </summary>
+ public enum BlurMode
+ {
+ None = 0,
+ FastBlur = 1,
+ MediumBlur = 2,
+ DetailBlur = 3,
+ }
+}
diff --git a/Assets/Scripts/Enums/BlurMode.cs.meta b/Assets/Scripts/Enums/BlurMode.cs.meta
new file mode 100644
index 0000000..504b62a
--- /dev/null
+++ b/Assets/Scripts/Enums/BlurMode.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5645838b01af8764d8f381f04b62b9a2
+timeCreated: 1528296875
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enums/ColorMode.cs b/Assets/Scripts/Enums/ColorMode.cs
new file mode 100644
index 0000000..567624b
--- /dev/null
+++ b/Assets/Scripts/Enums/ColorMode.cs
@@ -0,0 +1,13 @@
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Color effect mode.
+ /// </summary>
+ public enum ColorMode
+ {
+ Multiply = 0,
+ Fill = 1,
+ Add = 2,
+ Subtract = 3,
+ }
+}
diff --git a/Assets/Scripts/Enums/ColorMode.cs.meta b/Assets/Scripts/Enums/ColorMode.cs.meta
new file mode 100644
index 0000000..ba60cab
--- /dev/null
+++ b/Assets/Scripts/Enums/ColorMode.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: e6ba1e487e0a19644afde2bd5531bd04
+timeCreated: 1528296875
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enums/EffectArea.cs b/Assets/Scripts/Enums/EffectArea.cs
new file mode 100644
index 0000000..4e5fa28
--- /dev/null
+++ b/Assets/Scripts/Enums/EffectArea.cs
@@ -0,0 +1,116 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Area for effect.
+ /// </summary>
+ public enum EffectArea
+ {
+ RectTransform,
+ Fit,
+ Character,
+ }
+
+ public static class EffectAreaExtensions
+ {
+ static readonly Rect rectForCharacter = new Rect(0, 0, 1, 1);
+ static readonly Vector2[] splitedCharacterPosition = {Vector2.up, Vector2.one, Vector2.right, Vector2.zero};
+
+ /// <summary>
+ /// Gets effect for area.
+ /// </summary>
+ public static Rect GetEffectArea(this EffectArea area, VertexHelper vh, Rect rectangle, float aspectRatio = -1)
+ {
+ Rect rect = default(Rect);
+ switch (area)
+ {
+ case EffectArea.RectTransform:
+ rect = rectangle;
+ break;
+ case EffectArea.Character:
+ rect = rectForCharacter;
+ break;
+ case EffectArea.Fit:
+ // Fit to contents.
+ UIVertex vertex = default(UIVertex);
+ float xMin = float.MaxValue;
+ float yMin = float.MaxValue;
+ float xMax = float.MinValue;
+ float yMax = float.MinValue;
+ for (int i = 0; i < vh.currentVertCount; i++)
+ {
+ vh.PopulateUIVertex(ref vertex, i);
+ float x = vertex.position.x;
+ float y = vertex.position.y;
+ xMin = Mathf.Min(xMin, x);
+ yMin = Mathf.Min(yMin, y);
+ xMax = Mathf.Max(xMax, x);
+ yMax = Mathf.Max(yMax, y);
+ }
+
+ rect.Set(xMin, yMin, xMax - xMin, yMax - yMin);
+ break;
+ default:
+ rect = rectangle;
+ break;
+ }
+
+
+ if (0 < aspectRatio)
+ {
+ if (rect.width < rect.height)
+ {
+ rect.width = rect.height * aspectRatio;
+ }
+ else
+ {
+ rect.height = rect.width / aspectRatio;
+ }
+ }
+
+ return rect;
+ }
+
+ /// <summary>
+ /// Gets position factor for area.
+ /// </summary>
+ public static void GetPositionFactor(this EffectArea area, int index, Rect rect, Vector2 position, bool isText,
+ bool isTMPro, out float x, out float y)
+ {
+ if (isText && area == EffectArea.Character)
+ {
+ index = isTMPro ? (index + 3) % 4 : index % 4;
+ x = splitedCharacterPosition[index].x;
+ y = splitedCharacterPosition[index].y;
+ }
+ else if (area == EffectArea.Fit)
+ {
+ x = Mathf.Clamp01((position.x - rect.xMin) / rect.width);
+ y = Mathf.Clamp01((position.y - rect.yMin) / rect.height);
+ }
+ else
+ {
+ x = Mathf.Clamp01(position.x / rect.width + 0.5f);
+ y = Mathf.Clamp01(position.y / rect.height + 0.5f);
+ }
+ }
+
+ /// <summary>
+ /// Normalize vertex position by local matrix.
+ /// </summary>
+ public static void GetNormalizedFactor(this EffectArea area, int index, Matrix2x3 matrix, Vector2 position,
+ bool isText, out Vector2 nomalizedPos)
+ {
+ if (isText && area == EffectArea.Character)
+ {
+ nomalizedPos = matrix * splitedCharacterPosition[(index + 3) % 4];
+ }
+ else
+ {
+ nomalizedPos = matrix * position;
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/Enums/EffectArea.cs.meta b/Assets/Scripts/Enums/EffectArea.cs.meta
new file mode 100644
index 0000000..4bc2fa4
--- /dev/null
+++ b/Assets/Scripts/Enums/EffectArea.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: a78f43d1382a048a99411472ca714e1b
+timeCreated: 1528636556
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enums/EffectMode.cs b/Assets/Scripts/Enums/EffectMode.cs
new file mode 100644
index 0000000..84f3eb4
--- /dev/null
+++ b/Assets/Scripts/Enums/EffectMode.cs
@@ -0,0 +1,14 @@
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Effect mode.
+ /// </summary>
+ public enum EffectMode
+ {
+ None = 0,
+ Grayscale = 1,
+ Sepia = 2,
+ Nega = 3,
+ Pixel = 4,
+ }
+}
diff --git a/Assets/Scripts/Enums/EffectMode.cs.meta b/Assets/Scripts/Enums/EffectMode.cs.meta
new file mode 100644
index 0000000..76773db
--- /dev/null
+++ b/Assets/Scripts/Enums/EffectMode.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 092769547c242d74cbad96631a00963f
+timeCreated: 1528296875
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Enums/ShadowStyle.cs b/Assets/Scripts/Enums/ShadowStyle.cs
new file mode 100644
index 0000000..1cfe058
--- /dev/null
+++ b/Assets/Scripts/Enums/ShadowStyle.cs
@@ -0,0 +1,14 @@
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Shadow effect style.
+ /// </summary>
+ public enum ShadowStyle
+ {
+ None = 0,
+ Shadow,
+ Outline,
+ Outline8,
+ Shadow3,
+ }
+}
diff --git a/Assets/Scripts/Enums/ShadowStyle.cs.meta b/Assets/Scripts/Enums/ShadowStyle.cs.meta
new file mode 100644
index 0000000..337e823
--- /dev/null
+++ b/Assets/Scripts/Enums/ShadowStyle.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: b0eda5bf10146491c9cfe6a31c66f9a7
+timeCreated: 1528296875
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UIDissolve.cs b/Assets/Scripts/UIDissolve.cs
new file mode 100644
index 0000000..de49ef2
--- /dev/null
+++ b/Assets/Scripts/UIDissolve.cs
@@ -0,0 +1,319 @@
+using System;
+using UnityEngine;
+using UnityEditor;
+using UnityEngine.UI;
+using UnityEngine.Serialization;
+using System.Text;
+using System.Linq;
+using System.IO;
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Dissolve effect for uGUI.
+ /// </summary>
+ [AddComponentMenu("UI/UIEffects/UIDissolve", 3)]
+ public class UIDissolve : BaseMaterialEffect, IMaterialModifier
+ {
+ private const uint k_ShaderId = 0 << 3;
+ private static readonly ParameterTexture s_ParamTex = new ParameterTexture(8, 128, "_ParamTex");
+ private static readonly int k_TransitionTexId = Shader.PropertyToID("_TransitionTex");
+
+ private bool _lastKeepAspectRatio;
+ private EffectArea _lastEffectArea;
+ private static Texture _defaultTransitionTexture;
+
+ [Tooltip("Current location[0-1] for dissolve effect. 0 is not dissolved, 1 is completely dissolved.")]
+ [FormerlySerializedAs("m_Location")]
+ [SerializeField]
+ [Range(0, 1)]
+ float m_EffectFactor = 0.5f;
+
+ [Tooltip("Edge width.")] [SerializeField] [Range(0, 1)]
+ float m_Width = 0.5f;
+
+ [Tooltip("Edge softness.")] [SerializeField] [Range(0, 1)]
+ float m_Softness = 0.5f;
+
+ [Tooltip("Edge color.")] [SerializeField] [ColorUsage(false)]
+ Color m_Color = new Color(0.0f, 0.25f, 1.0f);
+
+ [Tooltip("Edge color effect mode.")] [SerializeField]
+ ColorMode m_ColorMode = ColorMode.Add;
+
+ [Tooltip("Noise texture for dissolving (single channel texture).")]
+ [SerializeField]
+ [FormerlySerializedAs("m_NoiseTexture")]
+ Texture m_TransitionTexture;
+
+ [Header("Advanced Option")] [Tooltip("The area for effect.")] [SerializeField]
+ protected EffectArea m_EffectArea;
+
+ [Tooltip("Keep effect aspect ratio.")] [SerializeField]
+ bool m_KeepAspectRatio;
+
+ [Header("Effect Player")] [SerializeField]
+ EffectPlayer m_Player;
+
+ [Tooltip("Reverse the dissolve effect.")] [FormerlySerializedAs("m_ReverseAnimation")] [SerializeField]
+ bool m_Reverse = false;
+
+ /// <summary>
+ /// Effect factor between 0(start) and 1(end).
+ /// </summary>
+ public float effectFactor
+ {
+ get { return m_EffectFactor; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_EffectFactor, value)) return;
+ m_EffectFactor = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Edge width.
+ /// </summary>
+ public float width
+ {
+ get { return m_Width; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_Width, value)) return;
+ m_Width = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Edge softness.
+ /// </summary>
+ public float softness
+ {
+ get { return m_Softness; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_Softness, value)) return;
+ m_Softness = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Edge color.
+ /// </summary>
+ public Color color
+ {
+ get { return m_Color; }
+ set
+ {
+ if (m_Color == value) return;
+ m_Color = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Noise texture.
+ /// </summary>
+ public Texture transitionTexture
+ {
+ get
+ {
+ return m_TransitionTexture
+ ? m_TransitionTexture
+ : defaultTransitionTexture;
+ }
+ set
+ {
+ if (m_TransitionTexture == value) return;
+ m_TransitionTexture = value;
+ SetMaterialDirty();
+ }
+ }
+
+ private static Texture defaultTransitionTexture
+ {
+ get
+ {
+ return _defaultTransitionTexture
+ ? _defaultTransitionTexture
+ : (_defaultTransitionTexture = Resources.Load<Texture>("Default-Transition"));
+ }
+ }
+
+ /// <summary>
+ /// The area for effect.
+ /// </summary>
+ public EffectArea effectArea
+ {
+ get { return m_EffectArea; }
+ set
+ {
+ if (m_EffectArea == value) return;
+ m_EffectArea = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Keep aspect ratio.
+ /// </summary>
+ public bool keepAspectRatio
+ {
+ get { return m_KeepAspectRatio; }
+ set
+ {
+ if (m_KeepAspectRatio == value) return;
+ m_KeepAspectRatio = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Color effect mode.
+ /// </summary>
+ public ColorMode colorMode
+ {
+ get { return m_ColorMode; }
+ set
+ {
+ if (m_ColorMode == value) return;
+ m_ColorMode = value;
+ SetMaterialDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gets the parameter texture.
+ /// </summary>
+ public override ParameterTexture paramTex
+ {
+ get { return s_ParamTex; }
+ }
+
+ public EffectPlayer effectPlayer
+ {
+ get { return m_Player ?? (m_Player = new EffectPlayer()); }
+ }
+
+ public override Hash128 GetMaterialHash(Material material)
+ {
+ if (!isActiveAndEnabled || !material || !material.shader)
+ return k_InvalidHash;
+
+ var shaderVariantId = (uint) ((int) m_ColorMode << 6);
+ var resourceId = (uint) transitionTexture.GetInstanceID();
+ return new Hash128(
+ (uint) material.GetInstanceID(),
+ k_ShaderId + shaderVariantId,
+ resourceId,
+ 0
+ );
+ }
+
+ public override void ModifyMaterial(Material newMaterial, Graphic graphic)
+ {
+ var connector = GraphicConnector.FindConnector(graphic);
+ newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIDissolve)", newMaterial.shader.name));
+ SetShaderVariants(newMaterial, m_ColorMode);
+
+ newMaterial.SetTexture(k_TransitionTexId, transitionTexture);
+ paramTex.RegisterMaterial(newMaterial);
+ }
+
+ /// <summary>
+ /// Modifies the mesh.
+ /// </summary>
+ public override void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ if (!isActiveAndEnabled)
+ return;
+
+ // bool isText = isTMPro || graphic is Text;
+ var normalizedIndex = paramTex.GetNormalizedIndex(this);
+
+ // rect.
+ var tex = transitionTexture;
+ var aspectRatio = m_KeepAspectRatio && tex ? ((float) tex.width) / tex.height : -1;
+ var rect = m_EffectArea.GetEffectArea(vh, rectTransform.rect, aspectRatio);
+
+ // Calculate vertex position.
+ var vertex = default(UIVertex);
+ var count = vh.currentVertCount;
+ for (var i = 0; i < count; i++)
+ {
+ vh.PopulateUIVertex(ref vertex, i);
+ float x;
+ float y;
+ connector.GetPositionFactor(m_EffectArea, i, rect, vertex.position, out x, out y);
+
+ vertex.uv0 = new Vector2(
+ Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
+ Packer.ToFloat(x, y, normalizedIndex)
+ );
+
+ vh.SetUIVertex(vertex, i);
+ }
+ }
+
+ protected override void SetEffectParamsDirty()
+ {
+ paramTex.SetData(this, 0, m_EffectFactor); // param1.x : location
+ paramTex.SetData(this, 1, m_Width); // param1.y : width
+ paramTex.SetData(this, 2, m_Softness); // param1.z : softness
+ paramTex.SetData(this, 4, m_Color.r); // param2.x : red
+ paramTex.SetData(this, 5, m_Color.g); // param2.y : green
+ paramTex.SetData(this, 6, m_Color.b); // param2.z : blue
+ }
+
+ protected override void SetVerticesDirty()
+ {
+ base.SetVerticesDirty();
+
+ _lastKeepAspectRatio = m_KeepAspectRatio;
+ _lastEffectArea = m_EffectArea;
+ }
+
+ protected override void OnDidApplyAnimationProperties()
+ {
+ base.OnDidApplyAnimationProperties();
+
+ if (_lastKeepAspectRatio != m_KeepAspectRatio
+ || _lastEffectArea != m_EffectArea)
+ SetVerticesDirty();
+ }
+
+ /// <summary>
+ /// Play effect.
+ /// </summary>
+ public void Play(bool reset = true)
+ {
+ effectPlayer.Play(reset);
+ }
+
+ /// <summary>
+ /// Stop effect.
+ /// </summary>
+ public void Stop(bool reset = true)
+ {
+ effectPlayer.Stop(reset);
+ }
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ effectPlayer.OnEnable((f) => effectFactor = m_Reverse ? 1f - f : f);
+ }
+
+ protected override void OnDisable()
+ {
+ base.OnDisable();
+ effectPlayer.OnDisable();
+ }
+ }
+}
diff --git a/Assets/Scripts/UIDissolve.cs.meta b/Assets/Scripts/UIDissolve.cs.meta
new file mode 100644
index 0000000..80d3101
--- /dev/null
+++ b/Assets/Scripts/UIDissolve.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: ce76b7a490bd74f34a2f2752641aea24
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences:
+ - m_TransitionTexture: {fileID: 2800000, guid: 3e04c247fb2604af186173fce0bc62de,
+ type: 3}
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UIEffect.asmdef b/Assets/Scripts/UIEffect.asmdef
new file mode 100644
index 0000000..2b24b63
--- /dev/null
+++ b/Assets/Scripts/UIEffect.asmdef
@@ -0,0 +1,3 @@
+{
+ "name": "UIEffect"
+}
diff --git a/Assets/Scripts/UIEffect.asmdef.meta b/Assets/Scripts/UIEffect.asmdef.meta
new file mode 100644
index 0000000..e73ac6b
--- /dev/null
+++ b/Assets/Scripts/UIEffect.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 735c8f008d0ad4caa9cdc4306f1c3042
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UIEffect.cs b/Assets/Scripts/UIEffect.cs
new file mode 100644
index 0000000..63a8ccc
--- /dev/null
+++ b/Assets/Scripts/UIEffect.cs
@@ -0,0 +1,368 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using UnityEngine.Serialization;
+#if UNITY_EDITOR
+using System.IO;
+using System.Linq;
+using UnityEditor;
+
+#endif
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// UIEffect.
+ /// </summary>
+ [ExecuteInEditMode]
+ [RequireComponent(typeof(Graphic))]
+ [DisallowMultipleComponent]
+ [AddComponentMenu("UI/UIEffects/UIEffect", 1)]
+ public class UIEffect : BaseMaterialEffect, IMaterialModifier
+ {
+ private const uint k_ShaderId = 2 << 3;
+ private static readonly ParameterTexture s_ParamTex = new ParameterTexture(4, 1024, "_ParamTex");
+
+ [FormerlySerializedAs("m_ToneLevel")]
+ [Tooltip("Effect factor between 0(no effect) and 1(complete effect).")]
+ [SerializeField]
+ [Range(0, 1)]
+ float m_EffectFactor = 1;
+
+ [Tooltip("Color effect factor between 0(no effect) and 1(complete effect).")] [SerializeField] [Range(0, 1)]
+ float m_ColorFactor = 1;
+
+ [FormerlySerializedAs("m_Blur")]
+ [Tooltip("How far is the blurring from the graphic.")]
+ [SerializeField]
+ [Range(0, 1)]
+ float m_BlurFactor = 1;
+
+ [FormerlySerializedAs("m_ToneMode")] [Tooltip("Effect mode")] [SerializeField]
+ EffectMode m_EffectMode = EffectMode.None;
+
+ [Tooltip("Color effect mode")] [SerializeField]
+ ColorMode m_ColorMode = ColorMode.Multiply;
+
+ [Tooltip("Blur effect mode")] [SerializeField]
+ BlurMode m_BlurMode = BlurMode.None;
+
+ [Tooltip("Advanced blurring remove common artifacts in the blur effect for uGUI.")] [SerializeField]
+ bool m_AdvancedBlur = false;
+
+ private enum BlurEx
+ {
+ None = 0,
+ Ex = 1,
+ }
+
+ /// <summary>
+ /// Additional canvas shader channels to use this component.
+ /// </summary>
+ public AdditionalCanvasShaderChannels uvMaskChannel
+ {
+ get { return connector.extraChannel; }
+ }
+
+ /// <summary>
+ /// Effect factor between 0(no effect) and 1(complete effect).
+ /// </summary>
+ public float effectFactor
+ {
+ get { return m_EffectFactor; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_EffectFactor, value)) return;
+ m_EffectFactor = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Color effect factor between 0(no effect) and 1(complete effect).
+ /// </summary>
+ public float colorFactor
+ {
+ get { return m_ColorFactor; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_ColorFactor, value)) return;
+ m_ColorFactor = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// How far is the blurring from the graphic.
+ /// </summary>
+ public float blurFactor
+ {
+ get { return m_BlurFactor; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_BlurFactor, value)) return;
+ m_BlurFactor = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Effect mode.
+ /// </summary>
+ public EffectMode effectMode
+ {
+ get { return m_EffectMode; }
+ set
+ {
+ if (m_EffectMode == value) return;
+ m_EffectMode = value;
+ SetMaterialDirty();
+ }
+ }
+
+ /// <summary>
+ /// Color effect mode.
+ /// </summary>
+ public ColorMode colorMode
+ {
+ get { return m_ColorMode; }
+ set
+ {
+ if (m_ColorMode == value) return;
+ m_ColorMode = value;
+ SetMaterialDirty();
+ }
+ }
+
+ /// <summary>
+ /// Blur effect mode(readonly).
+ /// </summary>
+ public BlurMode blurMode
+ {
+ get { return m_BlurMode; }
+ set
+ {
+ if (m_BlurMode == value) return;
+ m_BlurMode = value;
+ SetMaterialDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gets the parameter texture.
+ /// </summary>
+ public override ParameterTexture paramTex
+ {
+ get { return s_ParamTex; }
+ }
+
+ /// <summary>
+ /// Advanced blurring remove common artifacts in the blur effect for uGUI.
+ /// </summary>
+ public bool advancedBlur
+ {
+ get { return m_AdvancedBlur; }
+ set
+ {
+ if (m_AdvancedBlur == value) return;
+ m_AdvancedBlur = value;
+ SetVerticesDirty();
+ SetMaterialDirty();
+ }
+ }
+
+ public override Hash128 GetMaterialHash(Material material)
+ {
+ if (!isActiveAndEnabled || !material || !material.shader)
+ return k_InvalidHash;
+
+ var shaderVariantId = (uint) (((int) m_EffectMode << 6) + ((int) m_ColorMode << 9) +
+ ((int) m_BlurMode << 11) + ((m_AdvancedBlur ? 1 : 0) << 13));
+ return new Hash128(
+ (uint) material.GetInstanceID(),
+ k_ShaderId + shaderVariantId,
+ 0,
+ 0
+ );
+ }
+
+ public override void ModifyMaterial(Material newMaterial, Graphic graphic)
+ {
+ var connector = GraphicConnector.FindConnector(graphic);
+
+ newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIEffect)", newMaterial.shader.name));
+ SetShaderVariants(newMaterial, m_EffectMode, m_ColorMode, m_BlurMode,
+ m_AdvancedBlur ? BlurEx.Ex : BlurEx.None);
+
+ paramTex.RegisterMaterial(newMaterial);
+ }
+
+ /// <summary>
+ /// Modifies the mesh.
+ /// </summary>
+ public override void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ if (!isActiveAndEnabled)
+ {
+ return;
+ }
+
+ var normalizedIndex = paramTex.GetNormalizedIndex(this);
+
+ if (m_BlurMode != BlurMode.None && advancedBlur)
+ {
+ vh.GetUIVertexStream(s_TempVerts);
+ vh.Clear();
+ var count = s_TempVerts.Count;
+
+ // Bundle
+ int bundleSize = connector.IsText(graphic) ? 6 : count;
+ Rect posBounds = default(Rect);
+ Rect uvBounds = default(Rect);
+ Vector3 size = default(Vector3);
+ Vector3 tPos = default(Vector3);
+ Vector3 tUV = default(Vector3);
+ float expand = (float) blurMode * 6 * 2;
+
+ for (int i = 0; i < count; i += bundleSize)
+ {
+ // min/max for bundled-quad
+ GetBounds(s_TempVerts, i, bundleSize, ref posBounds, ref uvBounds, true);
+
+ // Pack uv mask.
+ Vector2 uvMask = new Vector2(Packer.ToFloat(uvBounds.xMin, uvBounds.yMin),
+ Packer.ToFloat(uvBounds.xMax, uvBounds.yMax));
+
+ // Quad
+ for (int j = 0; j < bundleSize; j += 6)
+ {
+ Vector3 cornerPos1 = s_TempVerts[i + j + 1].position;
+ Vector3 cornerPos2 = s_TempVerts[i + j + 4].position;
+
+ // Is outer quad?
+ bool hasOuterEdge = (bundleSize == 6)
+ || !posBounds.Contains(cornerPos1)
+ || !posBounds.Contains(cornerPos2);
+ if (hasOuterEdge)
+ {
+ Vector3 cornerUv1 = s_TempVerts[i + j + 1].uv0;
+ Vector3 cornerUv2 = s_TempVerts[i + j + 4].uv0;
+
+ Vector3 centerPos = (cornerPos1 + cornerPos2) / 2;
+ Vector3 centerUV = (cornerUv1 + cornerUv2) / 2;
+ size = (cornerPos1 - cornerPos2);
+
+ size.x = 1 + expand / Mathf.Abs(size.x);
+ size.y = 1 + expand / Mathf.Abs(size.y);
+ size.z = 1 + expand / Mathf.Abs(size.z);
+
+ tPos = centerPos - Vector3.Scale(size, centerPos);
+ tUV = centerUV - Vector3.Scale(size, centerUV);
+ }
+
+ // Vertex
+ for (int k = 0; k < 6; k++)
+ {
+ UIVertex vt = s_TempVerts[i + j + k];
+
+ Vector3 pos = vt.position;
+ Vector2 uv0 = vt.uv0;
+
+ if (hasOuterEdge && (pos.x < posBounds.xMin || posBounds.xMax < pos.x))
+ {
+ pos.x = pos.x * size.x + tPos.x;
+ uv0.x = uv0.x * size.x + tUV.x;
+ }
+
+ if (hasOuterEdge && (pos.y < posBounds.yMin || posBounds.yMax < pos.y))
+ {
+ pos.y = pos.y * size.y + tPos.y;
+ uv0.y = uv0.y * size.y + tUV.y;
+ }
+
+ vt.uv0 = new Vector2(Packer.ToFloat((uv0.x + 0.5f) / 2f, (uv0.y + 0.5f) / 2f),
+ normalizedIndex);
+ vt.position = pos;
+
+ connector.SetExtraChannel(ref vt, uvMask);
+
+ s_TempVerts[i + j + k] = vt;
+ }
+ }
+ }
+
+ vh.AddUIVertexTriangleStream(s_TempVerts);
+ s_TempVerts.Clear();
+ }
+ else
+ {
+ int count = vh.currentVertCount;
+ UIVertex vt = default(UIVertex);
+ for (int i = 0; i < count; i++)
+ {
+ vh.PopulateUIVertex(ref vt, i);
+ Vector2 uv0 = vt.uv0;
+ vt.uv0 = new Vector2(
+ Packer.ToFloat((uv0.x + 0.5f) / 2f, (uv0.y + 0.5f) / 2f),
+ normalizedIndex
+ );
+ vh.SetUIVertex(vt, i);
+ }
+ }
+ }
+
+ protected override void SetEffectParamsDirty()
+ {
+ paramTex.SetData(this, 0, m_EffectFactor); // param.x : effect factor
+ paramTex.SetData(this, 1, m_ColorFactor); // param.y : color factor
+ paramTex.SetData(this, 2, m_BlurFactor); // param.z : blur factor
+ }
+
+ static void GetBounds(List<UIVertex> verts, int start, int count, ref Rect posBounds, ref Rect uvBounds,
+ bool global)
+ {
+ Vector2 minPos = new Vector2(float.MaxValue, float.MaxValue);
+ Vector2 maxPos = new Vector2(float.MinValue, float.MinValue);
+ Vector2 minUV = new Vector2(float.MaxValue, float.MaxValue);
+ Vector2 maxUV = new Vector2(float.MinValue, float.MinValue);
+ for (int i = start; i < start + count; i++)
+ {
+ UIVertex vt = verts[i];
+
+ Vector2 uv = vt.uv0;
+ Vector3 pos = vt.position;
+
+ // Left-Bottom
+ if (minPos.x >= pos.x && minPos.y >= pos.y)
+ {
+ minPos = pos;
+ }
+ // Right-Top
+ else if (maxPos.x <= pos.x && maxPos.y <= pos.y)
+ {
+ maxPos = pos;
+ }
+
+ // Left-Bottom
+ if (minUV.x >= uv.x && minUV.y >= uv.y)
+ {
+ minUV = uv;
+ }
+ // Right-Top
+ else if (maxUV.x <= uv.x && maxUV.y <= uv.y)
+ {
+ maxUV = uv;
+ }
+ }
+
+ // Shrink coordinate for detect edge
+ posBounds.Set(minPos.x + 0.001f, minPos.y + 0.001f, maxPos.x - minPos.x - 0.002f,
+ maxPos.y - minPos.y - 0.002f);
+ uvBounds.Set(minUV.x, minUV.y, maxUV.x - minUV.x, maxUV.y - minUV.y);
+ }
+ }
+}
diff --git a/Assets/Scripts/UIEffect.cs.meta b/Assets/Scripts/UIEffect.cs.meta
new file mode 100644
index 0000000..1155fe8
--- /dev/null
+++ b/Assets/Scripts/UIEffect.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f8b2ed11d675446c5a49da1ea296d490
+timeCreated: 1485321967
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UIFlip.cs b/Assets/Scripts/UIFlip.cs
new file mode 100644
index 0000000..2cb7055
--- /dev/null
+++ b/Assets/Scripts/UIFlip.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Coffee.UIEffects
+{
+ [DisallowMultipleComponent]
+ [AddComponentMenu("UI/UIEffects/UIFlip", 102)]
+ public class UIFlip : BaseMeshEffect
+ {
+ [Tooltip("Flip horizontally.")] [SerializeField]
+ private bool m_Horizontal = false;
+
+ [Tooltip("Flip vertically.")] [SerializeField]
+ private bool m_Veritical = false;
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="Coffee.UIEffects.UIFlip"/> should be flipped horizontally.
+ /// </summary>
+ /// <value><c>true</c> if be flipped horizontally; otherwise, <c>false</c>.</value>
+ public bool horizontal
+ {
+ get { return m_Horizontal; }
+ set
+ {
+ if (m_Horizontal == value) return;
+ m_Horizontal = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="Coffee.UIEffects.UIFlip"/> should be flipped vertically.
+ /// </summary>
+ /// <value><c>true</c> if be flipped horizontally; otherwise, <c>false</c>.</value>
+ public bool vertical
+ {
+ get { return m_Veritical; }
+ set
+ {
+ if (m_Veritical == value) return;
+ m_Veritical = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Call used to modify mesh.
+ /// </summary>
+ /// <param name="vh">VertexHelper.</param>
+ public override void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ if (!isActiveAndEnabled) return;
+
+ var vt = default(UIVertex);
+ for (var i = 0; i < vh.currentVertCount; i++)
+ {
+ vh.PopulateUIVertex(ref vt, i);
+ var pos = vt.position;
+ vt.position = new Vector3(
+ m_Horizontal ? -pos.x : pos.x,
+ m_Veritical ? -pos.y : pos.y
+ );
+ vh.SetUIVertex(vt, i);
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/UIFlip.cs.meta b/Assets/Scripts/UIFlip.cs.meta
new file mode 100644
index 0000000..86d3ecb
--- /dev/null
+++ b/Assets/Scripts/UIFlip.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 9bb4e59514e90489d985e9a17c838085
+timeCreated: 1525607243
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UIGradient.cs b/Assets/Scripts/UIGradient.cs
new file mode 100644
index 0000000..b184182
--- /dev/null
+++ b/Assets/Scripts/UIGradient.cs
@@ -0,0 +1,319 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// UIGradient.
+ /// </summary>
+ [DisallowMultipleComponent]
+ [AddComponentMenu("UI/UIEffects/UIGradient", 101)]
+ public class UIGradient : BaseMeshEffect
+ {
+ static readonly Vector2[] s_SplitedCharacterPosition = {Vector2.up, Vector2.one, Vector2.right, Vector2.zero};
+
+ /// <summary>
+ /// Gradient direction.
+ /// </summary>
+ public enum Direction
+ {
+ Horizontal,
+ Vertical,
+ Angle,
+ Diagonal,
+ }
+
+ /// <summary>
+ /// Gradient space for Text.
+ /// </summary>
+ public enum GradientStyle
+ {
+ Rect,
+ Fit,
+ Split,
+ }
+
+
+ [Tooltip("Gradient Direction.")] [SerializeField]
+ Direction m_Direction;
+
+ [Tooltip("Color1: Top or Left.")] [SerializeField]
+ Color m_Color1 = Color.white;
+
+ [Tooltip("Color2: Bottom or Right.")] [SerializeField]
+ Color m_Color2 = Color.white;
+
+ [Tooltip("Color3: For diagonal.")] [SerializeField]
+ Color m_Color3 = Color.white;
+
+ [Tooltip("Color4: For diagonal.")] [SerializeField]
+ Color m_Color4 = Color.white;
+
+ [Tooltip("Gradient rotation.")] [SerializeField] [Range(-180, 180)]
+ float m_Rotation;
+
+ [Tooltip("Gradient offset for Horizontal, Vertical or Angle.")] [SerializeField] [Range(-1, 1)]
+ float m_Offset1;
+
+ [Tooltip("Gradient offset for Diagonal.")] [SerializeField] [Range(-1, 1)]
+ float m_Offset2;
+
+ [Tooltip("Gradient style for Text.")] [SerializeField]
+ GradientStyle m_GradientStyle;
+
+ [Tooltip("Color space to correct color.")] [SerializeField]
+ ColorSpace m_ColorSpace = ColorSpace.Uninitialized;
+
+ [Tooltip("Ignore aspect ratio.")] [SerializeField]
+ bool m_IgnoreAspectRatio = true;
+
+ /// <summary>
+ /// Gradient Direction.
+ /// </summary>
+ public Direction direction
+ {
+ get { return m_Direction; }
+ set
+ {
+ if (m_Direction == value) return;
+ m_Direction = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Color1: Top or Left.
+ /// </summary>
+ public Color color1
+ {
+ get { return m_Color1; }
+ set
+ {
+ if (m_Color1 == value) return;
+ m_Color1 = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Color2: Bottom or Right.
+ /// </summary>
+ public Color color2
+ {
+ get { return m_Color2; }
+ set
+ {
+ if (m_Color2 == value) return;
+ m_Color2 = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Color3: For diagonal.
+ /// </summary>
+ public Color color3
+ {
+ get { return m_Color3; }
+ set
+ {
+ if (m_Color3 == value) return;
+ m_Color3 = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Color4: For diagonal.
+ /// </summary>
+ public Color color4
+ {
+ get { return m_Color4; }
+ set
+ {
+ if (m_Color4 == value) return;
+ m_Color4 = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gradient rotation.
+ /// </summary>
+ public float rotation
+ {
+ get
+ {
+ return m_Direction == Direction.Horizontal ? -90
+ : m_Direction == Direction.Vertical ? 0
+ : m_Rotation;
+ }
+ set
+ {
+ if (Mathf.Approximately(m_Rotation, value)) return;
+ m_Rotation = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gradient offset for Horizontal, Vertical or Angle.
+ /// </summary>
+ public float offset
+ {
+ get { return m_Offset1; }
+ set
+ {
+ if (Mathf.Approximately(m_Offset1, value)) return;
+ m_Offset1 = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gradient offset for Diagonal.
+ /// </summary>
+ public Vector2 offset2
+ {
+ get { return new Vector2(m_Offset2, m_Offset1); }
+ set
+ {
+ if (Mathf.Approximately(m_Offset1, value.y) && Mathf.Approximately(m_Offset2, value.x)) return;
+ m_Offset1 = value.y;
+ m_Offset2 = value.x;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gradient style for Text.
+ /// </summary>
+ public GradientStyle gradientStyle
+ {
+ get { return m_GradientStyle; }
+ set
+ {
+ if (m_GradientStyle == value) return;
+ m_GradientStyle = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Color space to correct color.
+ /// </summary>
+ public ColorSpace colorSpace
+ {
+ get { return m_ColorSpace; }
+ set
+ {
+ if (m_ColorSpace == value) return;
+ m_ColorSpace = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Ignore aspect ratio.
+ /// </summary>
+ public bool ignoreAspectRatio
+ {
+ get { return m_IgnoreAspectRatio; }
+ set
+ {
+ if (m_IgnoreAspectRatio == value) return;
+ m_IgnoreAspectRatio = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Call used to modify mesh.
+ /// </summary>
+ public override void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ if (!isActiveAndEnabled)
+ return;
+
+ // Gradient space.
+ var rect = default(Rect);
+ var vertex = default(UIVertex);
+ switch (m_GradientStyle)
+ {
+ case GradientStyle.Rect:
+ // RectTransform.
+ rect = graphic.rectTransform.rect;
+ break;
+ case GradientStyle.Split:
+ // Each characters.
+ rect.Set(0, 0, 1, 1);
+ break;
+ case GradientStyle.Fit:
+ {
+ // Fit to contents.
+ rect.xMin = rect.yMin = float.MaxValue;
+ rect.xMax = rect.yMax = float.MinValue;
+ for (var i = 0; i < vh.currentVertCount; i++)
+ {
+ vh.PopulateUIVertex(ref vertex, i);
+ rect.xMin = Mathf.Min(rect.xMin, vertex.position.x);
+ rect.yMin = Mathf.Min(rect.yMin, vertex.position.y);
+ rect.xMax = Mathf.Max(rect.xMax, vertex.position.x);
+ rect.yMax = Mathf.Max(rect.yMax, vertex.position.y);
+ }
+
+ break;
+ }
+ }
+
+ // Gradient rotation.
+ var rad = rotation * Mathf.Deg2Rad;
+ var dir = new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
+ if (!m_IgnoreAspectRatio && Direction.Angle <= m_Direction)
+ {
+ dir.x *= rect.height / rect.width;
+ dir = dir.normalized;
+ }
+
+ // Calculate vertex color.
+ var localMatrix = new Matrix2x3(rect, dir.x, dir.y); // Get local matrix.
+ for (var i = 0; i < vh.currentVertCount; i++)
+ {
+ vh.PopulateUIVertex(ref vertex, i);
+
+ // Normalize vertex position by local matrix.
+ Vector2 normalizedPos;
+ if (m_GradientStyle == GradientStyle.Split)
+ {
+ // Each characters.
+ normalizedPos = localMatrix * s_SplitedCharacterPosition[i % 4] + offset2;
+ }
+ else
+ {
+ normalizedPos = localMatrix * vertex.position + offset2;
+ }
+
+ // Interpolate vertex color.
+ Color color;
+ if (direction == Direction.Diagonal)
+ {
+ color = Color.LerpUnclamped(
+ Color.LerpUnclamped(m_Color1, m_Color2, normalizedPos.x),
+ Color.LerpUnclamped(m_Color3, m_Color4, normalizedPos.x),
+ normalizedPos.y);
+ }
+ else
+ {
+ color = Color.LerpUnclamped(m_Color2, m_Color1, normalizedPos.y);
+ }
+
+ // Correct color.
+ vertex.color *= (m_ColorSpace == ColorSpace.Gamma) ? color.gamma
+ : (m_ColorSpace == ColorSpace.Linear) ? color.linear
+ : color;
+
+ vh.SetUIVertex(vertex, i);
+ }
+ }
+ }
+}
diff --git a/Assets/Scripts/UIGradient.cs.meta b/Assets/Scripts/UIGradient.cs.meta
new file mode 100644
index 0000000..8b596ad
--- /dev/null
+++ b/Assets/Scripts/UIGradient.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 3fb48d82dc0e94a2b9246d17d04f8748
+timeCreated: 1515744842
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UIHsvModifier.cs b/Assets/Scripts/UIHsvModifier.cs
new file mode 100644
index 0000000..8445bb7
--- /dev/null
+++ b/Assets/Scripts/UIHsvModifier.cs
@@ -0,0 +1,170 @@
+using System;
+using UnityEngine;
+using UnityEngine.Serialization;
+using UnityEngine.UI;
+
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// HSV Modifier.
+ /// </summary>
+ [AddComponentMenu("UI/UIEffects/UIHsvModifier", 4)]
+ public class UIHsvModifier : BaseMaterialEffect
+ {
+ private const uint k_ShaderId = 6 << 3;
+ private static readonly ParameterTexture s_ParamTex = new ParameterTexture(7, 128, "_ParamTex");
+
+ [Header("Target")] [Tooltip("Target color to affect hsv shift.")] [SerializeField] [ColorUsage(false)]
+ Color m_TargetColor = Color.red;
+
+ [Tooltip("Color range to affect hsv shift [0 ~ 1].")] [SerializeField] [Range(0, 1)]
+ float m_Range = 0.1f;
+
+ [Header("Adjustment")] [Tooltip("Hue shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)]
+ float m_Hue;
+
+ [Tooltip("Saturation shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)]
+ float m_Saturation;
+
+ [Tooltip("Value shift [-0.5 ~ 0.5].")] [SerializeField] [Range(-0.5f, 0.5f)]
+ float m_Value;
+
+ /// <summary>
+ /// Target color to affect hsv shift.
+ /// </summary>
+ public Color targetColor
+ {
+ get { return m_TargetColor; }
+ set
+ {
+ if (m_TargetColor == value) return;
+ m_TargetColor = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Color range to affect hsv shift [0 ~ 1].
+ /// </summary>
+ public float range
+ {
+ get { return m_Range; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_Range, value)) return;
+ m_Range = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Saturation shift [-0.5 ~ 0.5].
+ /// </summary>
+ public float saturation
+ {
+ get { return m_Saturation; }
+ set
+ {
+ value = Mathf.Clamp(value, -0.5f, 0.5f);
+ if (Mathf.Approximately(m_Saturation, value)) return;
+ m_Saturation = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Value shift [-0.5 ~ 0.5].
+ /// </summary>
+ public float value
+ {
+ get { return m_Value; }
+ set
+ {
+ value = Mathf.Clamp(value, -0.5f, 0.5f);
+ if (Mathf.Approximately(m_Value, value)) return;
+ m_Value = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Hue shift [-0.5 ~ 0.5].
+ /// </summary>
+ public float hue
+ {
+ get { return m_Hue; }
+ set
+ {
+ value = Mathf.Clamp(value, -0.5f, 0.5f);
+ if (Mathf.Approximately(m_Hue, value)) return;
+ m_Hue = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gets the parameter texture.
+ /// </summary>
+ public override ParameterTexture paramTex
+ {
+ get { return s_ParamTex; }
+ }
+
+ public override Hash128 GetMaterialHash(Material material)
+ {
+ if (!isActiveAndEnabled || !material || !material.shader)
+ return k_InvalidHash;
+
+ return new Hash128(
+ (uint) material.GetInstanceID(),
+ k_ShaderId,
+ 0,
+ 0
+ );
+ }
+
+ public override void ModifyMaterial(Material newMaterial, Graphic graphic)
+ {
+ var connector = GraphicConnector.FindConnector(graphic);
+
+ newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIHsvModifier)", newMaterial.shader.name));
+ paramTex.RegisterMaterial(newMaterial);
+ }
+
+ public override void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ if (!isActiveAndEnabled)
+ return;
+
+ var normalizedIndex = paramTex.GetNormalizedIndex(this);
+ var vertex = default(UIVertex);
+ var count = vh.currentVertCount;
+ for (var i = 0; i < count; i++)
+ {
+ vh.PopulateUIVertex(ref vertex, i);
+
+ vertex.uv0 = new Vector2(
+ Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
+ normalizedIndex
+ );
+ vh.SetUIVertex(vertex, i);
+ }
+ }
+
+ protected override void SetEffectParamsDirty()
+ {
+ float h, s, v;
+ Color.RGBToHSV(m_TargetColor, out h, out s, out v);
+
+ paramTex.SetData(this, 0, h); // param1.x : target hue
+ paramTex.SetData(this, 1, s); // param1.y : target saturation
+ paramTex.SetData(this, 2, v); // param1.z : target value
+ paramTex.SetData(this, 3, m_Range); // param1.w : target range
+ paramTex.SetData(this, 4, m_Hue + 0.5f); // param2.x : hue shift
+ paramTex.SetData(this, 5, m_Saturation + 0.5f); // param2.y : saturation shift
+ paramTex.SetData(this, 6, m_Value + 0.5f); // param2.z : value shift
+ }
+ }
+}
diff --git a/Assets/Scripts/UIHsvModifier.cs.meta b/Assets/Scripts/UIHsvModifier.cs.meta
new file mode 100644
index 0000000..44ca568
--- /dev/null
+++ b/Assets/Scripts/UIHsvModifier.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: efe700dddcd8341ff8607ac2c827b4b5
+timeCreated: 1523859834
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UIShadow.cs b/Assets/Scripts/UIShadow.cs
new file mode 100644
index 0000000..42ec596
--- /dev/null
+++ b/Assets/Scripts/UIShadow.cs
@@ -0,0 +1,383 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Serialization;
+using UnityEngine.UI;
+#if UNITY_EDITOR
+using System.IO;
+using System.Linq;
+using UnityEditor;
+
+#endif
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// UIEffect.
+ /// </summary>
+ [RequireComponent(typeof(Graphic))]
+ [AddComponentMenu("UI/UIEffects/UIShadow", 100)]
+ public class UIShadow : BaseMeshEffect, IParameterTexture
+ {
+ static readonly List<UIShadow> tmpShadows = new List<UIShadow>();
+ static readonly List<UIVertex> s_Verts = new List<UIVertex>(4096);
+
+ int _graphicVertexCount;
+ UIEffect _uiEffect;
+
+ [Tooltip("How far is the blurring shadow from the graphic.")]
+ [FormerlySerializedAs("m_Blur")]
+ [SerializeField]
+ [Range(0, 1)]
+ float m_BlurFactor = 1;
+
+ [Tooltip("Shadow effect style.")] [SerializeField]
+ ShadowStyle m_Style = ShadowStyle.Shadow;
+
+ [SerializeField] private Color m_EffectColor = new Color(0f, 0f, 0f, 0.5f);
+
+ [SerializeField] private Vector2 m_EffectDistance = new Vector2(1f, -1f);
+
+ [SerializeField] private bool m_UseGraphicAlpha = true;
+
+ private const float kMaxEffectDistance = 600f;
+
+ public Color effectColor
+ {
+ get { return m_EffectColor; }
+ set
+ {
+ if (m_EffectColor == value) return;
+ m_EffectColor = value;
+ SetVerticesDirty();
+ }
+ }
+
+ public Vector2 effectDistance
+ {
+ get { return m_EffectDistance; }
+ set
+ {
+ if (value.x > kMaxEffectDistance)
+ value.x = kMaxEffectDistance;
+ if (value.x < -kMaxEffectDistance)
+ value.x = -kMaxEffectDistance;
+
+ if (value.y > kMaxEffectDistance)
+ value.y = kMaxEffectDistance;
+ if (value.y < -kMaxEffectDistance)
+ value.y = -kMaxEffectDistance;
+
+ if (m_EffectDistance == value) return;
+ m_EffectDistance = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ public bool useGraphicAlpha
+ {
+ get { return m_UseGraphicAlpha; }
+ set
+ {
+ if (m_UseGraphicAlpha == value) return;
+ m_UseGraphicAlpha = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// How far is the blurring shadow from the graphic.
+ /// </summary>
+ public float blurFactor
+ {
+ get { return m_BlurFactor; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 2);
+ if (Mathf.Approximately(m_BlurFactor, value)) return;
+ m_BlurFactor = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Shadow effect style.
+ /// </summary>
+ public ShadowStyle style
+ {
+ get { return m_Style; }
+ set
+ {
+ if (m_Style == value) return;
+ m_Style = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the parameter index.
+ /// </summary>
+ public int parameterIndex { get; set; }
+
+ /// <summary>
+ /// Gets the parameter texture.
+ /// </summary>
+ public ParameterTexture paramTex { get; private set; }
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+
+ _uiEffect = GetComponent<UIEffect>();
+ if (!_uiEffect) return;
+
+ paramTex = _uiEffect.paramTex;
+ paramTex.Register(this);
+ }
+
+ protected override void OnDisable()
+ {
+ base.OnDisable();
+
+ _uiEffect = null;
+ if (paramTex == null) return;
+
+ paramTex.Unregister(this);
+ paramTex = null;
+ }
+
+
+// #if UNITY_EDITOR
+// protected override void OnValidate()
+// {
+// effectDistance = m_EffectDistance;
+// base.OnValidate();
+// }
+// #endif
+
+ // #if TMP_PRESENT
+ // protected void OnCullStateChanged (bool state)
+ // {
+ // SetVerticesDirty ();
+ // }
+ //
+ // Vector2 res;
+ // protected override void LateUpdate ()
+ // {
+ // if (res.x != Screen.width || res.y != Screen.height)
+ // {
+ // res.x = Screen.width;
+ // res.y = Screen.height;
+ // SetVerticesDirty ();
+ // }
+ // if (textMeshPro && transform.hasChanged)
+ // {
+ // transform.hasChanged = false;
+ // }
+ // base.LateUpdate ();
+ // }
+ // #endif
+
+ /// <summary>
+ /// Modifies the mesh.
+ /// </summary>
+ public override void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ if (!isActiveAndEnabled || vh.currentVertCount <= 0 || m_Style == ShadowStyle.None)
+ {
+ return;
+ }
+
+ vh.GetUIVertexStream(s_Verts);
+
+ GetComponents<UIShadow>(tmpShadows);
+
+ foreach (var s in tmpShadows)
+ {
+ if (!s.isActiveAndEnabled) continue;
+ if (s == this)
+ {
+ foreach (var s2 in tmpShadows)
+ {
+ s2._graphicVertexCount = s_Verts.Count;
+ }
+ }
+
+ break;
+ }
+
+ tmpShadows.Clear();
+
+ //================================
+ // Append shadow vertices.
+ //================================
+ {
+ _uiEffect = _uiEffect ? _uiEffect : GetComponent<UIEffect>();
+ var start = s_Verts.Count - _graphicVertexCount;
+ var end = s_Verts.Count;
+
+ if (paramTex != null && _uiEffect && _uiEffect.isActiveAndEnabled)
+ {
+ paramTex.SetData(this, 0, _uiEffect.effectFactor); // param.x : effect factor
+ paramTex.SetData(this, 1, 255); // param.y : color factor
+ paramTex.SetData(this, 2, m_BlurFactor); // param.z : blur factor
+ }
+
+ ApplyShadow(s_Verts, effectColor, ref start, ref end, effectDistance, style, useGraphicAlpha);
+ }
+
+ vh.Clear();
+ vh.AddUIVertexTriangleStream(s_Verts);
+
+ s_Verts.Clear();
+ }
+
+ /// <summary>
+ /// Append shadow vertices.
+ /// * It is similar to Shadow component implementation.
+ /// </summary>
+ private void ApplyShadow(List<UIVertex> verts, Color color, ref int start, ref int end, Vector2 distance,
+ ShadowStyle style, bool alpha)
+ {
+ if (style == ShadowStyle.None || color.a <= 0)
+ return;
+
+ var x = distance.x;
+ var y = distance.y;
+ // Append Shadow.
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, y, alpha);
+
+ switch (style)
+ {
+ // Append Shadow3.
+ case ShadowStyle.Shadow3:
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, 0, alpha);
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, 0, y, alpha);
+ break;
+ // Append Outline.
+ case ShadowStyle.Outline:
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, -y, alpha);
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, y, alpha);
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, -y, alpha);
+ break;
+ // Append Outline8.
+ case ShadowStyle.Outline8:
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, -y, alpha);
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, y, alpha);
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, -y, alpha);
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, -x, 0, alpha);
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, 0, -y, alpha);
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, x, 0, alpha);
+ ApplyShadowZeroAlloc(verts, color, ref start, ref end, 0, y, alpha);
+ break;
+ }
+ }
+
+ /// <summary>
+ /// Append shadow vertices.
+ /// * It is similar to Shadow component implementation.
+ /// </summary>
+ private void ApplyShadowZeroAlloc(List<UIVertex> verts, Color color, ref int start, ref int end, float x,
+ float y, bool alpha)
+ {
+ // Check list capacity.
+ var count = end - start;
+ var neededCapacity = verts.Count + count;
+ if (verts.Capacity < neededCapacity)
+ verts.Capacity *= 2;
+
+ var normalizedIndex = paramTex != null && _uiEffect && _uiEffect.isActiveAndEnabled
+ ? paramTex.GetNormalizedIndex(this)
+ : -1;
+
+ // Add
+ var vt = default(UIVertex);
+ for (var i = 0; i < count; i++)
+ {
+ verts.Add(vt);
+ }
+
+ // Move
+ for (var i = verts.Count - 1; count <= i; i--)
+ {
+ verts[i] = verts[i - count];
+ }
+
+ // Append shadow vertices to the front of list.
+ // * The original vertex is pushed backward.
+ for (var i = 0; i < count; ++i)
+ {
+ vt = verts[i + start + count];
+
+ var v = vt.position;
+ vt.position.Set(v.x + x, v.y + y, v.z);
+
+ var vertColor = effectColor;
+ vertColor.a = alpha ? color.a * vt.color.a / 255 : color.a;
+ vt.color = vertColor;
+
+
+ // Set UIEffect parameters
+ if (0 <= normalizedIndex)
+ {
+ vt.uv0 = new Vector2(
+ vt.uv0.x,
+ normalizedIndex
+ );
+ }
+
+ verts[i] = vt;
+ }
+
+ // Update next shadow offset.
+ start = end;
+ end = verts.Count;
+ }
+
+ /// <summary>
+ /// Mark the UIEffect as dirty.
+ /// </summary>
+ // void _SetDirty()
+ // {
+ // if (graphic)
+ // graphic.SetVerticesDirty();
+ // }
+
+// #if UNITY_EDITOR
+// public void OnBeforeSerialize()
+// {
+// }
+//
+// public void OnAfterDeserialize()
+// {
+// EditorApplication.delayCall += UpgradeIfNeeded;
+// }
+//
+//
+// #pragma warning disable 0612
+// void UpgradeIfNeeded()
+// {
+// if (0 < m_AdditionalShadows.Count)
+// {
+// foreach (var s in m_AdditionalShadows)
+// {
+// if (s.style == ShadowStyle.None)
+// {
+// continue;
+// }
+//
+// var shadow = gameObject.AddComponent<UIShadow>();
+// shadow.style = s.style;
+// shadow.effectDistance = s.effectDistance;
+// shadow.effectColor = s.effectColor;
+// shadow.useGraphicAlpha = s.useGraphicAlpha;
+// shadow.blurFactor = s.blur;
+// }
+//
+// m_AdditionalShadows = null;
+// }
+// }
+// #pragma warning restore 0612
+// #endif
+ }
+}
diff --git a/Assets/Scripts/UIShadow.cs.meta b/Assets/Scripts/UIShadow.cs.meta
new file mode 100644
index 0000000..257198c
--- /dev/null
+++ b/Assets/Scripts/UIShadow.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0848bff101191904ead4bb831f7084db
+timeCreated: 1485321967
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: -400
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UIShiny.cs b/Assets/Scripts/UIShiny.cs
new file mode 100644
index 0000000..3b938cb
--- /dev/null
+++ b/Assets/Scripts/UIShiny.cs
@@ -0,0 +1,278 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Serialization;
+using UnityEngine.UI;
+using System.Collections;
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// UIEffect.
+ /// </summary>
+ [AddComponentMenu("UI/UIEffects/UIShiny", 2)]
+ public class UIShiny : BaseMaterialEffect
+ {
+ private const uint k_ShaderId = 1 << 3;
+ private static readonly ParameterTexture s_ParamTex = new ParameterTexture(8, 128, "_ParamTex");
+
+ float _lastRotation;
+ EffectArea _lastEffectArea;
+
+ [Tooltip("Location for shiny effect.")] [FormerlySerializedAs("m_Location")] [SerializeField] [Range(0, 1)]
+ float m_EffectFactor = 0.5f;
+
+ [Tooltip("Width for shiny effect.")] [SerializeField] [Range(0, 1)]
+ float m_Width = 0.25f;
+
+ [Tooltip("Rotation for shiny effect.")] [SerializeField] [Range(-180, 180)]
+ float m_Rotation = 135;
+
+ [Tooltip("Softness for shiny effect.")] [SerializeField] [Range(0.01f, 1)]
+ float m_Softness = 1f;
+
+ [Tooltip("Brightness for shiny effect.")] [FormerlySerializedAs("m_Alpha")] [SerializeField] [Range(0, 1)]
+ float m_Brightness = 1f;
+
+ [Tooltip("Gloss factor for shiny effect.")] [FormerlySerializedAs("m_Highlight")] [SerializeField] [Range(0, 1)]
+ float m_Gloss = 1;
+
+ [Header("Advanced Option")] [Tooltip("The area for effect.")] [SerializeField]
+ protected EffectArea m_EffectArea;
+
+ [SerializeField] EffectPlayer m_Player;
+
+ /// <summary>
+ /// Effect factor between 0(start) and 1(end).
+ /// </summary>
+ public float effectFactor
+ {
+ get { return m_EffectFactor; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_EffectFactor, value)) return;
+ m_EffectFactor = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Width for shiny effect.
+ /// </summary>
+ public float width
+ {
+ get { return m_Width; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_Width, value)) return;
+ m_Width = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Softness for shiny effect.
+ /// </summary>
+ public float softness
+ {
+ get { return m_Softness; }
+ set
+ {
+ value = Mathf.Clamp(value, 0.01f, 1);
+ if (Mathf.Approximately(m_Softness, value)) return;
+ m_Softness = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Brightness for shiny effect.
+ /// </summary>
+ public float brightness
+ {
+ get { return m_Brightness; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_Brightness, value)) return;
+ m_Brightness = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gloss factor for shiny effect.
+ /// </summary>
+ public float gloss
+ {
+ get { return m_Gloss; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_Gloss, value)) return;
+ m_Gloss = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Rotation for shiny effect.
+ /// </summary>
+ public float rotation
+ {
+ get { return m_Rotation; }
+ set
+ {
+ if (Mathf.Approximately(m_Rotation, value)) return;
+ m_Rotation = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// The area for effect.
+ /// </summary>
+ public EffectArea effectArea
+ {
+ get { return m_EffectArea; }
+ set
+ {
+ if (m_EffectArea == value) return;
+ m_EffectArea = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gets the parameter texture.
+ /// </summary>
+ public override ParameterTexture paramTex
+ {
+ get { return s_ParamTex; }
+ }
+
+ public EffectPlayer effectPlayer
+ {
+ get { return m_Player ?? (m_Player = new EffectPlayer()); }
+ }
+
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ effectPlayer.OnEnable(f => effectFactor = f);
+ }
+
+ /// <summary>
+ /// This function is called when the behaviour becomes disabled () or inactive.
+ /// </summary>
+ protected override void OnDisable()
+ {
+ base.OnDisable();
+ effectPlayer.OnDisable();
+ }
+
+
+ public override Hash128 GetMaterialHash(Material material)
+ {
+ if (!isActiveAndEnabled || !material || !material.shader)
+ return k_InvalidHash;
+
+ return new Hash128(
+ (uint) material.GetInstanceID(),
+ k_ShaderId,
+ 0,
+ 0
+ );
+ }
+
+ public override void ModifyMaterial(Material newMaterial, Graphic graphic)
+ {
+ var connector = GraphicConnector.FindConnector(graphic);
+
+ newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIShiny)", newMaterial.shader.name));
+ paramTex.RegisterMaterial(newMaterial);
+ }
+
+ /// <summary>
+ /// Modifies the mesh.
+ /// </summary>
+ public override void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ if (!isActiveAndEnabled)
+ return;
+
+ var normalizedIndex = paramTex.GetNormalizedIndex(this);
+ var rect = m_EffectArea.GetEffectArea(vh, rectTransform.rect);
+
+ // rotation.
+ var rad = m_Rotation * Mathf.Deg2Rad;
+ var dir = new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
+ dir.x *= rect.height / rect.width;
+ dir = dir.normalized;
+
+ // Calculate vertex position.
+ var vertex = default(UIVertex);
+ var localMatrix = new Matrix2x3(rect, dir.x, dir.y); // Get local matrix.
+ for (int i = 0; i < vh.currentVertCount; i++)
+ {
+ vh.PopulateUIVertex(ref vertex, i);
+ Vector2 normalizedPos;
+ connector.GetNormalizedFactor(m_EffectArea, i, localMatrix, vertex.position, out normalizedPos);
+
+ vertex.uv0 = new Vector2(
+ Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
+ Packer.ToFloat(normalizedPos.y, normalizedIndex)
+ );
+
+ vh.SetUIVertex(vertex, i);
+ }
+ }
+
+ /// <summary>
+ /// Play effect.
+ /// </summary>
+ public void Play(bool reset = true)
+ {
+ effectPlayer.Play(reset);
+ }
+
+ /// <summary>
+ /// Stop effect.
+ /// </summary>
+ public void Stop(bool reset = true)
+ {
+ effectPlayer.Stop(reset);
+ }
+
+ protected override void SetEffectParamsDirty()
+ {
+ paramTex.SetData(this, 0, m_EffectFactor); // param1.x : location
+ paramTex.SetData(this, 1, m_Width); // param1.y : width
+ paramTex.SetData(this, 2, m_Softness); // param1.z : softness
+ paramTex.SetData(this, 3, m_Brightness); // param1.w : blightness
+ paramTex.SetData(this, 4, m_Gloss); // param2.x : gloss
+ }
+
+ protected override void SetVerticesDirty()
+ {
+ base.SetVerticesDirty();
+
+ _lastRotation = m_Rotation;
+ _lastEffectArea = m_EffectArea;
+ }
+
+ protected override void OnDidApplyAnimationProperties()
+ {
+ base.OnDidApplyAnimationProperties();
+
+ if (!Mathf.Approximately(_lastRotation, m_Rotation)
+ || _lastEffectArea != m_EffectArea)
+ SetVerticesDirty();
+ }
+ }
+}
diff --git a/Assets/Scripts/UIShiny.cs.meta b/Assets/Scripts/UIShiny.cs.meta
new file mode 100644
index 0000000..97bec07
--- /dev/null
+++ b/Assets/Scripts/UIShiny.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f19b7e2285c104f6ca47d583f3e5444f
+timeCreated: 1523859834
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UISyncEffect.cs b/Assets/Scripts/UISyncEffect.cs
new file mode 100644
index 0000000..ada9be8
--- /dev/null
+++ b/Assets/Scripts/UISyncEffect.cs
@@ -0,0 +1,83 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Dissolve effect for uGUI.
+ /// </summary>
+ [ExecuteInEditMode]
+ public class UISyncEffect : BaseMaterialEffect
+ {
+ [Tooltip("The target effect to synchronize.")] [SerializeField]
+ private BaseMeshEffect m_TargetEffect;
+
+ public BaseMeshEffect targetEffect
+ {
+ get { return m_TargetEffect != this ? m_TargetEffect : null; }
+ set
+ {
+ if (m_TargetEffect == value) return;
+ m_TargetEffect = value;
+
+ SetVerticesDirty();
+ SetMaterialDirty();
+ SetEffectParamsDirty();
+ }
+ }
+
+ protected override void OnEnable()
+ {
+ if (targetEffect)
+ targetEffect.syncEffects.Add(this);
+ base.OnEnable();
+ }
+
+ protected override void OnDisable()
+ {
+ if (targetEffect)
+ targetEffect.syncEffects.Remove(this);
+ base.OnDisable();
+ }
+
+ public override Hash128 GetMaterialHash(Material baseMaterial)
+ {
+ if (!isActiveAndEnabled) return k_InvalidHash;
+
+ var matEffect = targetEffect as BaseMaterialEffect;
+ if (!matEffect || !matEffect.isActiveAndEnabled) return k_InvalidHash;
+
+ return matEffect.GetMaterialHash(baseMaterial);
+ }
+
+ public override void ModifyMaterial(Material newMaterial, Graphic graphic)
+ {
+ if (!isActiveAndEnabled) return;
+
+ var matEffect = targetEffect as BaseMaterialEffect;
+ if (!matEffect || !matEffect.isActiveAndEnabled) return;
+
+ matEffect.ModifyMaterial(newMaterial, graphic);
+ }
+
+ public override void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ if (!isActiveAndEnabled) return;
+ if (!targetEffect || !targetEffect.isActiveAndEnabled) return;
+
+ targetEffect.ModifyMesh(vh, graphic);
+ }
+
+#if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ SetVerticesDirty();
+ SetMaterialDirty();
+ SetEffectParamsDirty();
+ }
+#endif
+ }
+}
diff --git a/Assets/Scripts/UISyncEffect.cs.meta b/Assets/Scripts/UISyncEffect.cs.meta
new file mode 100644
index 0000000..5b14421
--- /dev/null
+++ b/Assets/Scripts/UISyncEffect.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a7be078926b3448089fe9995b32f75f1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UITransitionEffect.cs b/Assets/Scripts/UITransitionEffect.cs
new file mode 100644
index 0000000..b75dfd2
--- /dev/null
+++ b/Assets/Scripts/UITransitionEffect.cs
@@ -0,0 +1,332 @@
+using UnityEngine;
+using UnityEngine.UI;
+using UnityEngine.Serialization;
+using System;
+
+namespace Coffee.UIEffects
+{
+ /// <summary>
+ /// Transition effect.
+ /// </summary>
+ [AddComponentMenu("UI/UIEffects/UITransitionEffect", 5)]
+ public class UITransitionEffect : BaseMaterialEffect
+ {
+ /// <summary>
+ /// Effect mode.
+ /// </summary>
+ public enum EffectMode
+ {
+ Fade = 1,
+ Cutoff = 2,
+ Dissolve = 3,
+ }
+
+ private const uint k_ShaderId = 5 << 3;
+ private static readonly int k_TransitionTexId = Shader.PropertyToID("_TransitionTex");
+ private static readonly ParameterTexture s_ParamTex = new ParameterTexture(8, 128, "_ParamTex");
+
+ private bool _lastKeepAspectRatio;
+ private static Texture _defaultTransitionTexture;
+
+ [Tooltip("Effect mode.")] [SerializeField]
+ EffectMode m_EffectMode = EffectMode.Cutoff;
+
+ [Tooltip("Effect factor between 0(hidden) and 1(shown).")] [SerializeField] [Range(0, 1)]
+ float m_EffectFactor = 0.5f;
+
+ [Tooltip("Transition texture (single channel texture).")] [SerializeField]
+ Texture m_TransitionTexture;
+
+ [Header("Advanced Option")] [Tooltip("The area for effect.")] [SerializeField]
+ EffectArea m_EffectArea = EffectArea.RectTransform;
+
+ [Tooltip("Keep effect aspect ratio.")] [SerializeField]
+ bool m_KeepAspectRatio;
+
+ [Tooltip("Dissolve edge width.")] [SerializeField] [Range(0, 1)]
+ float m_DissolveWidth = 0.5f;
+
+ [Tooltip("Dissolve edge softness.")] [SerializeField] [Range(0, 1)]
+ float m_DissolveSoftness = 0.5f;
+
+ [Tooltip("Dissolve edge color.")] [SerializeField] [ColorUsage(false)]
+ Color m_DissolveColor = new Color(0.0f, 0.25f, 1.0f);
+
+ [Tooltip("Disable the graphic's raycast target on hidden.")] [SerializeField]
+ bool m_PassRayOnHidden;
+
+ [Header("Effect Player")] [SerializeField]
+ EffectPlayer m_Player;
+
+
+ /// <summary>
+ /// Effect factor between 0(no effect) and 1(complete effect).
+ /// </summary>
+ public float effectFactor
+ {
+ get { return m_EffectFactor; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_EffectFactor, value)) return;
+ m_EffectFactor = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Transition texture.
+ /// </summary>
+ public Texture transitionTexture
+ {
+ get
+ {
+ return m_TransitionTexture
+ ? m_TransitionTexture
+ : defaultTransitionTexture;
+ }
+ set
+ {
+ if (m_TransitionTexture == value) return;
+ m_TransitionTexture = value;
+ SetMaterialDirty();
+ }
+ }
+
+ private static Texture defaultTransitionTexture
+ {
+ get
+ {
+ return _defaultTransitionTexture
+ ? _defaultTransitionTexture
+ : (_defaultTransitionTexture = Resources.Load<Texture>("Default-Transition"));
+ }
+ }
+
+ /// <summary>
+ /// Effect mode.
+ /// </summary>
+ public EffectMode effectMode
+ {
+ get { return m_EffectMode; }
+ set
+ {
+ if (m_EffectMode == value) return;
+ m_EffectMode = value;
+ SetMaterialDirty();
+ }
+ }
+
+ /// <summary>
+ /// Keep aspect ratio.
+ /// </summary>
+ public bool keepAspectRatio
+ {
+ get { return m_KeepAspectRatio; }
+ set
+ {
+ if (m_KeepAspectRatio == value) return;
+ m_KeepAspectRatio = value;
+ SetVerticesDirty();
+ }
+ }
+
+ /// <summary>
+ /// Gets the parameter texture.
+ /// </summary>
+ public override ParameterTexture paramTex
+ {
+ get { return s_ParamTex; }
+ }
+
+ /// <summary>
+ /// Dissolve edge width.
+ /// </summary>
+ public float dissolveWidth
+ {
+ get { return m_DissolveWidth; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_DissolveWidth, value)) return;
+ m_DissolveWidth = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Dissolve edge softness.
+ /// </summary>
+ public float dissolveSoftness
+ {
+ get { return m_DissolveSoftness; }
+ set
+ {
+ value = Mathf.Clamp(value, 0, 1);
+ if (Mathf.Approximately(m_DissolveSoftness, value)) return;
+ m_DissolveSoftness = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Dissolve edge color.
+ /// </summary>
+ public Color dissolveColor
+ {
+ get { return m_DissolveColor; }
+ set
+ {
+ if (m_DissolveColor == value) return;
+ m_DissolveColor = value;
+ SetEffectParamsDirty();
+ }
+ }
+
+ /// <summary>
+ /// Disable graphic's raycast target on hidden.
+ /// </summary>
+ public bool passRayOnHidden
+ {
+ get { return m_PassRayOnHidden; }
+ set { m_PassRayOnHidden = value; }
+ }
+
+ public EffectPlayer effectPlayer
+ {
+ get { return m_Player ?? (m_Player = new EffectPlayer()); }
+ }
+
+ /// <summary>
+ /// Show transition.
+ /// </summary>
+ public void Show(bool reset = true)
+ {
+ effectPlayer.loop = false;
+ effectPlayer.Play(reset, f => effectFactor = f);
+ }
+
+ /// <summary>
+ /// Hide transition.
+ /// </summary>
+ public void Hide(bool reset = true)
+ {
+ effectPlayer.loop = false;
+ effectPlayer.Play(reset, f => effectFactor = 1 - f);
+ }
+
+
+ public override Hash128 GetMaterialHash(Material material)
+ {
+ if (!isActiveAndEnabled || !material || !material.shader)
+ return k_InvalidHash;
+
+ var shaderVariantId = (uint) ((int) m_EffectMode << 6);
+ var resourceId = (uint) transitionTexture.GetInstanceID();
+ return new Hash128(
+ (uint) material.GetInstanceID(),
+ k_ShaderId + shaderVariantId,
+ resourceId,
+ 0
+ );
+ }
+
+ public override void ModifyMaterial(Material newMaterial, Graphic graphic)
+ {
+ var connector = GraphicConnector.FindConnector(graphic);
+ newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UITransition)", newMaterial.shader.name));
+ SetShaderVariants(newMaterial, m_EffectMode);
+
+ newMaterial.SetTexture(k_TransitionTexId, transitionTexture);
+ paramTex.RegisterMaterial(newMaterial);
+ }
+
+ /// <summary>
+ /// Modifies the mesh.
+ /// </summary>
+ public override void ModifyMesh(VertexHelper vh, Graphic graphic)
+ {
+ if (!isActiveAndEnabled)
+ {
+ return;
+ }
+
+ var normalizedIndex = paramTex.GetNormalizedIndex(this);
+
+ // rect.
+ var tex = transitionTexture;
+ var aspectRatio = m_KeepAspectRatio && tex ? ((float) tex.width) / tex.height : -1;
+ var rect = m_EffectArea.GetEffectArea(vh, rectTransform.rect, aspectRatio);
+
+ // Set parameters to vertex.
+ var vertex = default(UIVertex);
+ var count = vh.currentVertCount;
+ for (var i = 0; i < count; i++)
+ {
+ vh.PopulateUIVertex(ref vertex, i);
+ float x;
+ float y;
+ connector.GetPositionFactor(m_EffectArea, i, rect, vertex.position, out x, out y);
+
+ vertex.uv0 = new Vector2(
+ Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
+ Packer.ToFloat(x, y, normalizedIndex)
+ );
+ vh.SetUIVertex(vertex, i);
+ }
+ }
+
+ /// <summary>
+ /// This function is called when the object becomes enabled and active.
+ /// </summary>
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ effectPlayer.OnEnable(null);
+ effectPlayer.loop = false;
+ }
+
+ /// <summary>
+ /// This function is called when the behaviour becomes disabled () or inactive.
+ /// </summary>
+ protected override void OnDisable()
+ {
+ base.OnDisable();
+ effectPlayer.OnDisable();
+ }
+
+ protected override void SetEffectParamsDirty()
+ {
+ paramTex.SetData(this, 0, m_EffectFactor); // param1.x : effect factor
+ if (m_EffectMode == EffectMode.Dissolve)
+ {
+ paramTex.SetData(this, 1, m_DissolveWidth); // param1.y : width
+ paramTex.SetData(this, 2, m_DissolveSoftness); // param1.z : softness
+ paramTex.SetData(this, 4, m_DissolveColor.r); // param2.x : red
+ paramTex.SetData(this, 5, m_DissolveColor.g); // param2.y : green
+ paramTex.SetData(this, 6, m_DissolveColor.b); // param2.z : blue
+ }
+
+ // Disable graphic's raycastTarget on hidden.
+ if (m_PassRayOnHidden)
+ {
+ graphic.raycastTarget = 0 < m_EffectFactor;
+ }
+ }
+
+ protected override void SetVerticesDirty()
+ {
+ base.SetVerticesDirty();
+
+ _lastKeepAspectRatio = m_KeepAspectRatio;
+ }
+
+ protected override void OnDidApplyAnimationProperties()
+ {
+ base.OnDidApplyAnimationProperties();
+
+ if (_lastKeepAspectRatio != m_KeepAspectRatio)
+ SetVerticesDirty();
+ }
+ }
+}
diff --git a/Assets/Scripts/UITransitionEffect.cs.meta b/Assets/Scripts/UITransitionEffect.cs.meta
new file mode 100644
index 0000000..6069e80
--- /dev/null
+++ b/Assets/Scripts/UITransitionEffect.cs.meta
@@ -0,0 +1,16 @@
+fileFormatVersion: 2
+guid: 922b805bc01c243e5853d9cbb544118c
+timeCreated: 1538827562
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences:
+ - m_EffectMaterial: {instanceID: 0}
+ - m_PtexMaterial: {instanceID: 0}
+ - m_TransitionTexture: {fileID: 2800000, guid: 3e04c247fb2604af186173fce0bc62de,
+ type: 3}
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: