221 lines
4.3 KiB
C#
221 lines
4.3 KiB
C#
using UnityEngine.UI;
|
|
using UnityEngine;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
[ExecuteAlways]
|
|
public class FrameAnimator : MonoBehaviour
|
|
{
|
|
public Sprite[] sprites;
|
|
public float frameRate = 10f;
|
|
|
|
public bool preview;
|
|
public bool isPlaying = false;
|
|
public bool loop = true;
|
|
public int currentFrame = 0;
|
|
|
|
float m_frameTimer = 0f;
|
|
bool m_previewPlaying = false;
|
|
#if UNITY_EDITOR
|
|
double m_lastEditorTime = 0d;
|
|
#endif
|
|
Image m_img;
|
|
Image img {
|
|
get{
|
|
if(m_img==null){
|
|
m_img= GetComponent<Image>();
|
|
}
|
|
return m_img;
|
|
}
|
|
}
|
|
|
|
void OnValidate()
|
|
{
|
|
if(preview)
|
|
{
|
|
preview=false;
|
|
StartPreviewOnce();
|
|
}
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (!Application.isPlaying)
|
|
{
|
|
m_lastEditorTime = EditorApplication.timeSinceStartup;
|
|
EditorApplication.update -= OnEditorUpdate;
|
|
EditorApplication.update += OnEditorUpdate;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
#if UNITY_EDITOR
|
|
EditorApplication.update -= OnEditorUpdate;
|
|
#endif
|
|
}
|
|
void Start()
|
|
{
|
|
if (sprites == null || sprites.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentFrame = Mathf.Clamp(currentFrame, 0, sprites.Length - 1);
|
|
ApplyCurrentFrame();
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (!Application.isPlaying)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TickAnimation(Time.deltaTime);
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
void OnEditorUpdate()
|
|
{
|
|
if (Application.isPlaying || this == null || !isActiveAndEnabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
double now = EditorApplication.timeSinceStartup;
|
|
float dt = (float)(now - m_lastEditorTime);
|
|
m_lastEditorTime = now;
|
|
|
|
if (dt <= 0f)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TickAnimation(dt);
|
|
EditorApplication.QueuePlayerLoopUpdate();
|
|
}
|
|
#endif
|
|
|
|
void TickAnimation(float deltaTime)
|
|
{
|
|
if (frameRate <= 0f || sprites == null || sprites.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool shouldAnimate = m_previewPlaying || isPlaying;
|
|
if (!shouldAnimate)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_frameTimer += deltaTime;
|
|
float frameDuration = 1f / frameRate;
|
|
|
|
while (m_frameTimer >= frameDuration)
|
|
{
|
|
m_frameTimer -= frameDuration;
|
|
if (m_previewPlaying)
|
|
{
|
|
AdvancePreviewFrame();
|
|
}
|
|
else
|
|
{
|
|
AdvanceFrame();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Play(bool restart = false)
|
|
{
|
|
if (sprites == null || sprites.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (restart)
|
|
{
|
|
currentFrame = 0;
|
|
m_frameTimer = 0f;
|
|
ApplyCurrentFrame();
|
|
}
|
|
|
|
isPlaying = true;
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
isPlaying = false;
|
|
m_frameTimer = 0f;
|
|
}
|
|
|
|
public void ResetToFirstFrame()
|
|
{
|
|
currentFrame = 0;
|
|
m_frameTimer = 0f;
|
|
ApplyCurrentFrame();
|
|
}
|
|
|
|
void StartPreviewOnce()
|
|
{
|
|
if (sprites == null || sprites.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
isPlaying = false;
|
|
m_previewPlaying = true;
|
|
m_frameTimer = 0f;
|
|
currentFrame = 0;
|
|
ApplyCurrentFrame();
|
|
}
|
|
|
|
void AdvancePreviewFrame()
|
|
{
|
|
currentFrame++;
|
|
if (currentFrame >= sprites.Length)
|
|
{
|
|
currentFrame = sprites.Length - 1;
|
|
m_previewPlaying = false;
|
|
}
|
|
|
|
ApplyCurrentFrame();
|
|
}
|
|
|
|
void AdvanceFrame()
|
|
{
|
|
currentFrame++;
|
|
|
|
if (currentFrame >= sprites.Length)
|
|
{
|
|
if (loop)
|
|
{
|
|
currentFrame = 0;
|
|
}
|
|
else
|
|
{
|
|
currentFrame = sprites.Length - 1;
|
|
isPlaying = false;
|
|
}
|
|
}
|
|
|
|
ApplyCurrentFrame();
|
|
}
|
|
|
|
void ApplyCurrentFrame()
|
|
{
|
|
if (img == null || sprites == null || sprites.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentFrame = Mathf.Clamp(currentFrame, 0, sprites.Length - 1);
|
|
img.sprite = sprites[currentFrame];
|
|
}
|
|
}
|