356 lines
11 KiB
C#
356 lines
11 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Coffee.UIExtensions
|
|
{
|
|
/// <summary>
|
|
/// Transition effect.
|
|
/// </summary>
|
|
[AddComponentMenu("UI/UIEffect/UITransitionEffect", 5)]
|
|
public class UITransitionEffect : UIEffectBase
|
|
{
|
|
//################################
|
|
// Constant or Static Members.
|
|
//################################
|
|
public const string shaderName = "UI/Hidden/UI-Effect-Transition";
|
|
static readonly ParameterTexture _ptex = new ParameterTexture(8, 128, "_ParamTex");
|
|
|
|
/// <summary>
|
|
/// Effect mode.
|
|
/// </summary>
|
|
public enum EffectMode
|
|
{
|
|
Fade = 1,
|
|
Cutoff = 2,
|
|
Dissolve = 3,
|
|
}
|
|
|
|
|
|
//################################
|
|
// Serialize Members.
|
|
//################################
|
|
[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 = 1;
|
|
|
|
[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 graphic's raycast target on hidden.")]
|
|
[SerializeField] bool m_PassRayOnHidden;
|
|
|
|
[Header("Effect Player")]
|
|
[SerializeField] EffectPlayer m_Player;
|
|
|
|
//################################
|
|
// Public Members.
|
|
//################################
|
|
|
|
/// <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))
|
|
{
|
|
m_EffectFactor = value;
|
|
SetDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Transition texture.
|
|
/// </summary>
|
|
public Texture transitionTexture
|
|
{
|
|
get { return m_TransitionTexture; }
|
|
set
|
|
{
|
|
if (m_TransitionTexture != value)
|
|
{
|
|
m_TransitionTexture = value;
|
|
if (graphic)
|
|
{
|
|
ModifyMaterial();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effect mode.
|
|
/// </summary>
|
|
public EffectMode effectMode { get { return m_EffectMode; } }
|
|
|
|
/// <summary>
|
|
/// Keep aspect ratio.
|
|
/// </summary>
|
|
public bool keepAspectRatio
|
|
{
|
|
get { return m_KeepAspectRatio; }
|
|
set
|
|
{
|
|
if (m_KeepAspectRatio != value)
|
|
{
|
|
m_KeepAspectRatio = value;
|
|
targetGraphic.SetVerticesDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the parameter texture.
|
|
/// </summary>
|
|
public override ParameterTexture ptex { get { return _ptex; } }
|
|
|
|
/// <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))
|
|
{
|
|
m_DissolveWidth = value;
|
|
SetDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <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))
|
|
{
|
|
m_DissolveSoftness = value;
|
|
SetDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dissolve edge color.
|
|
/// </summary>
|
|
public Color dissolveColor
|
|
{
|
|
get { return m_DissolveColor; }
|
|
set
|
|
{
|
|
if (m_DissolveColor != value)
|
|
{
|
|
m_DissolveColor = value;
|
|
SetDirty();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Duration for showing/hiding.
|
|
/// </summary>
|
|
public float duration { get { return _player.duration; } set { _player.duration = Mathf.Max(value, 0.1f); } }
|
|
|
|
/// <summary>
|
|
/// Disable graphic's raycast target on hidden.
|
|
/// </summary>
|
|
public bool passRayOnHidden { get { return m_PassRayOnHidden; } set { m_PassRayOnHidden = value; } }
|
|
|
|
/// <summary>
|
|
/// Update mode for showing/hiding.
|
|
/// </summary>
|
|
public AnimatorUpdateMode updateMode { get { return _player.updateMode; } set { _player.updateMode = value; } }
|
|
|
|
/// <summary>
|
|
/// Show transition.
|
|
/// </summary>
|
|
public void Show(bool reset = true)
|
|
{
|
|
_player.loop = false;
|
|
_player.Play(reset, f => effectFactor = f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hide transition.
|
|
/// </summary>
|
|
public void Hide(bool reset = true)
|
|
{
|
|
_player.loop = false;
|
|
_player.Play(reset, f => effectFactor = 1 - f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Modifies the material.
|
|
/// </summary>
|
|
public override void ModifyMaterial()
|
|
{
|
|
if (isTMPro)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ulong hash = (m_TransitionTexture ? (uint)m_TransitionTexture.GetInstanceID() : 0) + ((ulong)2 << 32) + ((ulong)m_EffectMode << 36);
|
|
if (_materialCache != null && (_materialCache.hash != hash || !isActiveAndEnabled || !m_EffectMaterial))
|
|
{
|
|
MaterialCache.Unregister(_materialCache);
|
|
_materialCache = null;
|
|
}
|
|
|
|
if (!isActiveAndEnabled || !m_EffectMaterial)
|
|
{
|
|
material = null;
|
|
}
|
|
else if (!m_TransitionTexture)
|
|
{
|
|
material = m_EffectMaterial;
|
|
}
|
|
else if (_materialCache != null && _materialCache.hash == hash)
|
|
{
|
|
material = _materialCache.material;
|
|
}
|
|
else
|
|
{
|
|
_materialCache = MaterialCache.Register(hash, m_TransitionTexture, () =>
|
|
{
|
|
var mat = new Material(m_EffectMaterial);
|
|
mat.name += "_" + m_TransitionTexture.name;
|
|
mat.SetTexture("_NoiseTex", m_TransitionTexture);
|
|
return mat;
|
|
});
|
|
material = _materialCache.material;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Modifies the mesh.
|
|
/// </summary>
|
|
public override void ModifyMesh(VertexHelper vh)
|
|
{
|
|
if (!isActiveAndEnabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool isText = isTMPro || graphic is Text;
|
|
float normalizedIndex = ptex.GetNormalizedIndex(this);
|
|
|
|
// rect.
|
|
var tex = transitionTexture;
|
|
var aspectRatio = m_KeepAspectRatio && tex ? ((float)tex.width) / tex.height : -1;
|
|
Rect rect = m_EffectArea.GetEffectArea(vh, rectTransform.rect, aspectRatio);
|
|
|
|
// Set prameters to vertex.
|
|
UIVertex vertex = default(UIVertex);
|
|
float x, y;
|
|
int count = vh.currentVertCount;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
vh.PopulateUIVertex(ref vertex, i);
|
|
m_EffectArea.GetPositionFactor(i, rect, vertex.position, isText, isTMPro, 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 Members.
|
|
//################################
|
|
|
|
/// <summary>
|
|
/// This function is called when the object becomes enabled and active.
|
|
/// </summary>
|
|
protected override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
_player.OnEnable(null);
|
|
_player.loop = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This function is called when the behaviour becomes disabled () or inactive.
|
|
/// </summary>
|
|
protected override void OnDisable()
|
|
{
|
|
base.OnDisable();
|
|
MaterialCache.Unregister(_materialCache);
|
|
_materialCache = null;
|
|
_player.OnDisable();
|
|
}
|
|
|
|
protected override void SetDirty()
|
|
{
|
|
foreach (var m in materials)
|
|
{
|
|
ptex.RegisterMaterial(m);
|
|
}
|
|
ptex.SetData(this, 0, m_EffectFactor); // param1.x : effect factor
|
|
if (m_EffectMode == EffectMode.Dissolve)
|
|
{
|
|
ptex.SetData(this, 1, m_DissolveWidth); // param1.y : width
|
|
ptex.SetData(this, 2, m_DissolveSoftness); // param1.z : softness
|
|
ptex.SetData(this, 4, m_DissolveColor.r); // param2.x : red
|
|
ptex.SetData(this, 5, m_DissolveColor.g); // param2.y : green
|
|
ptex.SetData(this, 6, m_DissolveColor.b); // param2.z : blue
|
|
}
|
|
|
|
// Disable graphic's raycastTarget on hidden.
|
|
if (m_PassRayOnHidden)
|
|
{
|
|
targetGraphic.raycastTarget = 0 < m_EffectFactor;
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
/// <summary>
|
|
/// Gets the material.
|
|
/// </summary>
|
|
/// <returns>The material.</returns>
|
|
protected override Material GetMaterial()
|
|
{
|
|
return MaterialResolver.GetOrGenerateMaterialVariant(Shader.Find(shaderName), m_EffectMode);
|
|
}
|
|
#endif
|
|
|
|
//################################
|
|
// Private Members.
|
|
//################################
|
|
MaterialCache _materialCache = null;
|
|
|
|
EffectPlayer _player { get { return m_Player ?? (m_Player = new EffectPlayer()); } }
|
|
}
|
|
}
|