summaryrefslogtreecommitdiff
path: root/Assets/Scripts/UITransitionEffect.cs
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-04-07 21:33:14 +0800
committerchai <chaifix@163.com>2021-04-07 21:33:14 +0800
commitc47b92e92cf33ae8bf2f38929e137294397e4735 (patch)
treec67ae3419eaf15e84f1679186e107f598de33978 /Assets/Scripts/UITransitionEffect.cs
Diffstat (limited to 'Assets/Scripts/UITransitionEffect.cs')
-rw-r--r--Assets/Scripts/UITransitionEffect.cs332
1 files changed, 332 insertions, 0 deletions
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();
+ }
+ }
+}