AxibugEmuOnline/AxibugEmuOnline.Client.Transplant/Assets/Plugins/Coffee/UIExtensions/UIEffect/Scripts/UIDissolve.cs

435 lines
13 KiB
C#

using System;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace Coffee.UIExtensions
{
/// <summary>
/// Dissolve effect for uGUI.
/// </summary>
[AddComponentMenu("UI/UIEffect/UIDissolve", 3)]
public class UIDissolve : UIEffectBase
{
//################################
// Constant or Static Members.
//################################
public const string shaderName = "UI/Hidden/UI-Effect-Dissolve";
static readonly ParameterTexture _ptex = new ParameterTexture(8, 128, "_ParamTex");
//################################
// Serialize Members.
//################################
[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] Texture m_NoiseTexture;
[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;
#pragma warning disable 0414
[Obsolete]
[HideInInspector]
[SerializeField][Range(0.1f, 10)] float m_Duration = 1;
[Obsolete]
[HideInInspector]
[SerializeField] AnimatorUpdateMode m_UpdateMode = AnimatorUpdateMode.Normal;
#pragma warning restore 0414
//################################
// Public Members.
//################################
/// <summary>
/// Effect factor between 0(start) and 1(end).
/// </summary>
[System.Obsolete("Use effectFactor instead (UnityUpgradable) -> effectFactor")]
public float location
{
get { return m_EffectFactor; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (!Mathf.Approximately(m_EffectFactor, value))
{
m_EffectFactor = value;
SetDirty();
}
}
}
/// <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))
{
m_EffectFactor = value;
SetDirty();
}
}
}
/// <summary>
/// Edge width.
/// </summary>
public float width
{
get { return m_Width; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (!Mathf.Approximately(m_Width, value))
{
m_Width = value;
SetDirty();
}
}
}
/// <summary>
/// Edge softness.
/// </summary>
public float softness
{
get { return m_Softness; }
set
{
value = Mathf.Clamp(value, 0, 1);
if (!Mathf.Approximately(m_Softness, value))
{
m_Softness = value;
SetDirty();
}
}
}
/// <summary>
/// Edge color.
/// </summary>
public Color color
{
get { return m_Color; }
set
{
if (m_Color != value)
{
m_Color = value;
SetDirty();
}
}
}
/// <summary>
/// Noise texture.
/// </summary>
public Texture noiseTexture
{
get { return m_NoiseTexture ?? material.GetTexture("_NoiseTex"); }
set
{
if (m_NoiseTexture != value)
{
m_NoiseTexture = value;
if (graphic)
{
ModifyMaterial();
}
}
}
}
/// <summary>
/// The area for effect.
/// </summary>
public EffectArea effectArea
{
get { return m_EffectArea; }
set
{
if (m_EffectArea != value)
{
m_EffectArea = value;
SetVerticesDirty();
}
}
}
/// <summary>
/// Keep aspect ratio.
/// </summary>
public bool keepAspectRatio
{
get { return m_KeepAspectRatio; }
set
{
if (m_KeepAspectRatio != value)
{
m_KeepAspectRatio = value;
SetVerticesDirty();
}
}
}
/// <summary>
/// Color effect mode.
/// </summary>
public ColorMode colorMode { get { return m_ColorMode; } }
/// <summary>
/// Play effect on enable.
/// </summary>
[System.Obsolete("Use Play/Stop method instead")]
public bool play { get { return _player.play; } set { _player.play = value; } }
/// <summary>
/// Play effect loop.
/// </summary>
[System.Obsolete]
public bool loop { get { return _player.loop; } set { _player.loop = value; } }
/// <summary>
/// The duration for playing effect.
/// </summary>
public float duration { get { return _player.duration; } set { _player.duration = Mathf.Max(value, 0.1f); } }
/// <summary>
/// Delay on loop effect.
/// </summary>
[System.Obsolete]
public float loopDelay { get { return _player.loopDelay; } set { _player.loopDelay = Mathf.Max(value, 0); } }
/// <summary>
/// Update mode for playing effect.
/// </summary>
public AnimatorUpdateMode updateMode { get { return _player.updateMode; } set { _player.updateMode = value; } }
/// <summary>
/// Reverse the dissolve effect.
/// </summary>
public bool reverse { get { return m_Reverse; } set { m_Reverse = value; } }
/// <summary>
/// Gets the parameter texture.
/// </summary>
public override ParameterTexture ptex { get { return _ptex; } }
/// <summary>
/// Modifies the material.
/// </summary>
public override void ModifyMaterial()
{
if (isTMPro)
{
return;
}
ulong hash = (m_NoiseTexture ? (uint)m_NoiseTexture.GetInstanceID() : 0) + ((ulong)1 << 32) + ((ulong)m_ColorMode << 36);
if (_materialCache != null && (_materialCache.hash != hash || !isActiveAndEnabled || !m_EffectMaterial))
{
MaterialCache.Unregister(_materialCache);
_materialCache = null;
}
if (!isActiveAndEnabled || !m_EffectMaterial)
{
material = null;
}
else if (!m_NoiseTexture)
{
material = m_EffectMaterial;
}
else if (_materialCache != null && _materialCache.hash == hash)
{
material = _materialCache.material;
}
else
{
_materialCache = MaterialCache.Register(hash, m_NoiseTexture, () =>
{
var mat = new Material(m_EffectMaterial);
mat.name += "_" + m_NoiseTexture.name;
mat.SetTexture("_NoiseTex", m_NoiseTexture);
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 = noiseTexture;
var aspectRatio = m_KeepAspectRatio && tex ? ((float)tex.width) / tex.height : -1;
Rect rect = m_EffectArea.GetEffectArea(vh, rectTransform.rect, aspectRatio);
// Calculate vertex position.
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)
);
// if(!isTMPro)
// {
// vertex.uv0 = new Vector2(
// Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
// Packer.ToFloat(x, y, normalizedIndex)
// );
// }
// #if UNITY_5_6_OR_NEWER
// else
// {
// vertex.uv2 = new Vector2 (
// Packer.ToFloat (x, y, normalizedIndex),
// 0
// );
// }
// #endif
vh.SetUIVertex(vertex, i);
}
}
protected override void SetDirty()
{
foreach (var m in materials)
{
ptex.RegisterMaterial(m);
}
ptex.SetData(this, 0, m_EffectFactor); // param1.x : location
ptex.SetData(this, 1, m_Width); // param1.y : width
ptex.SetData(this, 2, m_Softness); // param1.z : softness
ptex.SetData(this, 4, m_Color.r); // param2.x : red
ptex.SetData(this, 5, m_Color.g); // param2.y : green
ptex.SetData(this, 6, m_Color.b); // param2.z : blue
}
/// <summary>
/// Play effect.
/// </summary>
public void Play(bool reset = true)
{
_player.Play(reset);
}
/// <summary>
/// Stop effect.
/// </summary>
public void Stop(bool reset = true)
{
_player.Stop(reset);
}
//################################
// Protected Members.
//################################
/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected override void OnEnable()
{
base.OnEnable();
_player.OnEnable((f) =>
{
effectFactor = m_Reverse ? 1f - f : f;
});
}
protected override void OnDisable()
{
base.OnDisable();
MaterialCache.Unregister(_materialCache);
_materialCache = null;
_player.OnDisable();
}
#if UNITY_EDITOR
/// <summary>
/// Gets the material.
/// </summary>
/// <returns>The material.</returns>
protected override Material GetMaterial()
{
if (isTMPro)
{
return null;
}
return MaterialResolver.GetOrGenerateMaterialVariant(Shader.Find(shaderName), m_ColorMode);
}
#pragma warning disable 0612
protected override void UpgradeIfNeeded()
{
// Upgrade for v3.0.0
if (IsShouldUpgrade(300))
{
_player.play = false;
_player.duration = m_Duration;
_player.loop = false;
_player.loopDelay = 1;
_player.updateMode = m_UpdateMode;
}
}
#pragma warning restore 0612
#endif
//################################
// Private Members.
//################################
MaterialCache _materialCache = null;
EffectPlayer _player { get { return m_Player ?? (m_Player = new EffectPlayer()); } }
}
}