using System;
using System.Collections.Generic;
using UnityEngine;
namespace Coffee.UIExtensions
{
///
/// Effect player.
///
[Serializable]
public class EffectPlayer
{
//################################
// Public Members.
//################################
///
/// Gets or sets a value indicating whether is playing.
///
[Header("Effect Player")]
[Tooltip("Playing.")]
public bool play = false;
///
/// Gets or sets the delay before looping.
///
[Tooltip("Initial play delay.")]
[Range(0f, 10f)]
public float initialPlayDelay = 0;
///
/// Gets or sets the duration.
///
[Tooltip("Duration.")]
[Range(0.01f, 10f)]
public float duration = 1;
///
/// Gets or sets a value indicating whether can loop.
///
[Tooltip("Loop.")]
public bool loop = false;
///
/// Gets or sets the delay before looping.
///
[Tooltip("Delay before looping.")]
[Range(0f, 10f)]
public float loopDelay = 0;
///
/// Gets or sets the update mode.
///
[Tooltip("Update mode")]
public AnimatorUpdateMode updateMode = AnimatorUpdateMode.Normal;
static List s_UpdateActions;
///
/// Register player.
///
public void OnEnable(Action callback = null)
{
if (s_UpdateActions == null)
{
s_UpdateActions = new List();
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;
}
///
/// Unregister player.
///
public void OnDisable()
{
_callback = null;
s_UpdateActions.Remove(OnWillRenderCanvases);
}
///
/// Start playing.
///
public void Play(bool reset, Action callback = null)
{
if (reset)
{
_time = 0;
}
play = true;
if (callback != null)
{
_callback = callback;
}
}
///
/// Stop playing.
///
public void Stop(bool reset)
{
if (reset)
{
_time = 0;
if (_callback != null)
{
_callback(_time);
}
}
play = false;
}
//################################
// Private Members.
//################################
float _time = 0;
Action _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);
}
}
}