//----------------------------------------------
// NGUI: Next-Gen UI kit
// Copyright © 2011-2015 Tasharen Entertainment
//----------------------------------------------
using UnityEngine;
using System.Collections.Generic;
///
/// Very simple sprite animation. Attach to a sprite and specify a common prefix such as "idle" and it will cycle through them.
///
[ExecuteInEditMode]
[RequireComponent(typeof(UISprite))]
[AddComponentMenu("NGUI/UI/Sprite Animation")]
public class UISpriteAnimation : MonoBehaviour
{
[HideInInspector][SerializeField] protected int mFPS = 30;
[HideInInspector][SerializeField] protected string mPrefix = "";
[HideInInspector][SerializeField] protected bool mLoop = true;
[HideInInspector][SerializeField] protected bool mSnap = true;
[HideInInspector][SerializeField] protected bool mUseRealTime = false;
protected UISprite mSprite;
protected float mDelta = 0f;
protected int mIndex = 0;
protected bool mActive = true;
protected List mSpriteNames = null;
///
/// Number of frames in the animation.
///
public int frames { get { return mSpriteNames != null ? mSpriteNames.Count : 0; } }
///
/// Animation framerate.
///
public int framesPerSecond { get { return mFPS; } set { mFPS = value; } }
///
/// Set the name prefix used to filter sprites from the atlas.
///
public string namePrefix { get { return mPrefix; } set { if (mPrefix != value) { mPrefix = value; RebuildSpriteList(); } } }
///
/// Set the animation to be looping or not
///
public bool loop { get { return mLoop; } set { mLoop = value; } }
public bool PrefixSnap { get { return mSnap; } set { mSnap = value; } }
///
/// Returns is the animation is still playing or not
///
public bool isPlaying { get { return mActive; } }
///
/// Rebuild the sprite list first thing.
///
protected virtual void Start () { RebuildSpriteList(); }
///
/// Advance the sprite animation process.
///
protected virtual void Update ()
{
if (mActive && mSpriteNames != null && mSpriteNames.Count > 1 && Application.isPlaying && mFPS > 0)
{
if(mUseRealTime)
{
mDelta += RealTime.deltaTime;
}
else
{
mDelta += Time.deltaTime;
}
float rate = 1f / mFPS;
if (rate < mDelta)
{
mDelta = (rate > 0f) ? mDelta - rate : 0f;
if (++mIndex >= mSpriteNames.Count)
{
mIndex = 0;
mActive = mLoop;
}
if (mActive)
{
mSprite.spriteName = mSpriteNames[mIndex];
if (mSnap) mSprite.MakePixelPerfect();
}
}
}
}
///
/// Rebuild the sprite list after changing the sprite name.
///
private static Dictionary>> _spriteNameCache = new Dictionary>>();
public void RebuildSpriteList ()
{
if (mSprite == null) mSprite = GetComponent();
if (mSprite != null && mSprite.atlas != null)
{
var atlasName = mSprite.atlas.name;
Dictionary> atlasDic = null;
List prefixList = null;
if (_spriteNameCache.TryGetValue(atlasName, out atlasDic) && atlasDic.TryGetValue(mPrefix, out prefixList))
{
mSpriteNames = prefixList;
}
else
{
mSpriteNames = new List();
List sprites = mSprite.atlas.spriteList;
for (int i = 0, imax = sprites.Count; i < imax; ++i)
{
UISpriteData sprite = sprites[i];
if (string.IsNullOrEmpty(mPrefix) || sprite.name.StartsWith(mPrefix))
{
mSpriteNames.Add(sprite.name);
}
}
mSpriteNames.Sort();
if(!_spriteNameCache.ContainsKey(atlasName))
{
atlasDic = new Dictionary>();
_spriteNameCache.Add(atlasName, atlasDic);
}
if(!atlasDic.ContainsKey(mPrefix))
{
atlasDic.Add(mPrefix, mSpriteNames);
}
}
}
}
///
/// Reset the animation to the beginning.
///
public void Play () { mActive = true; }
///
/// Pause the animation.
///
public void Pause () { mActive = false; }
///
/// Reset the animation to frame 0 and activate it.
///
public void ResetToBeginning ()
{
mActive = true;
mIndex = 0;
if (mSprite != null && mSpriteNames != null && mSpriteNames.Count > 0)
{
mSprite.spriteName = mSpriteNames[mIndex];
if (mSnap) mSprite.MakePixelPerfect();
}
}
}