序列帧动画原理是首先必须要有一个载体,一般是一个图片,然后申请一个数组或List用来存放序列帧,然后再根据需要遍历这个数组替换载体的图片源,这样就实现动画效果了。代码如下:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using System;
namespace Engine
{
[RequireComponent(typeof(Image))]
public class SimpleFrameAnim : MonoBehaviour
{
private Image ImageSource;
private int mCurFrame = 0;
private float mDelta = 0;
public float FPS = 20;
public List<Sprite> SpriteFrames;
public bool IsPlaying = false;
public bool Foward = true;
public bool AutoPlay = false;
public bool Loop = false;
private Action<object> animPlayEndAction = null;
private object caller = null;
public int FrameCount
{
get
{
return SpriteFrames.Count;
}
}
void Awake()
{
ImageSource = GetComponent<Image>();
}
void Start()
{
if (AutoPlay)
{
Play();
}
else
{
IsPlaying = false;
}
}
private void SetSprite(int idx)
{
ImageSource.sprite = SpriteFrames[idx];
//该部分为设置成原始图片大小,如果只需要显示Image设定好的图片大小,注释掉该行即可。
ImageSource.SetNativeSize();
}
public void Play()
{
IsPlaying = true;
Foward = true;
}
public void PlayReverse()
{
IsPlaying = true;
Foward = false;
}
void Update()
{
if (!IsPlaying || 0 == FrameCount)
{
return;
}
mDelta += Time.deltaTime;
if (mDelta > 1 / FPS)
{
mDelta = 0;
if(Foward)
{
mCurFrame++;
}
else
{
mCurFrame--;
}
if (mCurFrame >= FrameCount)
{
if (Loop)
{
mCurFrame = 0;
}
else
{
IsPlaying = false;
if (animPlayEndAction != null)
animPlayEndAction.Invoke(caller);
return;
}
}
else if (mCurFrame<0)
{
if (Loop)
{
mCurFrame = FrameCount-1;
}
else
{
IsPlaying = false;
if (animPlayEndAction != null)
animPlayEndAction.Invoke(caller);
return;
}
}
SetSprite(mCurFrame);
}
}
public void Pause()
{
IsPlaying = false;
}
public void Resume()
{
if (!IsPlaying)
{
IsPlaying = true;
}
}
public void Stop()
{
mCurFrame = 0;
SetSprite(mCurFrame);
IsPlaying = false;
}
public void Rewind()
{
mCurFrame = 0;
SetSprite(mCurFrame);
Play();
}
public void AddAnimPlayEndListener(Action<object> aciton, object caller)
{
animPlayEndAction = aciton;
this.caller = caller;
}
}
}
相比于转载的文章加入了回调函数,可以在 Lua中获取该组件并添加回调方法。