218 lines
6.1 KiB
C#
218 lines
6.1 KiB
C#
|
using System.Collections.Generic;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><>ʾһ<CABE><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>һϵ<D2BB>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD>ÿ֡<C3BF><D6A1><EFBFBD><EFBFBD>ʾʱ<CABE>䡣
|
|||
|
/// </summary>
|
|||
|
[System.Serializable]
|
|||
|
public class AnimationSequence
|
|||
|
{
|
|||
|
[Tooltip("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еľ<D0B5><C4BE><EFBFBD><EFBFBD>б<EFBFBD>")]
|
|||
|
public List<Sprite> sprites = new List<Sprite>();
|
|||
|
|
|||
|
[Tooltip("ÿһ֡<D2BB><D6A1>ʱ<EFBFBD>䣬<EFBFBD><E4A3AC>λ<EFBFBD><CEBB>")]
|
|||
|
public float frameTime = 0.1f; // ÿ֡<C3BF>ij<EFBFBD><C4B3><EFBFBD>ʱ<EFBFBD>䣨<EFBFBD>룩
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD>ƾ<EFBFBD><C6BE>鶯<EFBFBD><E9B6AF><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><C5B5>࣬ʹ<E0A3AC><CAB9> Dictionary <20><><EFBFBD>о<EFBFBD><D0BE>黺<EFBFBD><E9BBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
/// </summary>
|
|||
|
public class SpriteAnimator : MonoBehaviour
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD>嶯<EFBFBD><E5B6AF><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD>
|
|||
|
/// </summary>
|
|||
|
public enum LoopType
|
|||
|
{
|
|||
|
Loop, // <20><><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
|
|||
|
Once, // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
|
|||
|
PingPong // <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
|||
|
}
|
|||
|
|
|||
|
[Header("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>")]
|
|||
|
[Tooltip("<22><><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")]
|
|||
|
public List<AnimationSequence> animationSequences = new List<AnimationSequence>();
|
|||
|
|
|||
|
[Header("SpriteRenderer<65><72><EFBFBD><EFBFBD>")]
|
|||
|
[Tooltip("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SpriteRenderer")]
|
|||
|
public SpriteRenderer spriteRenderer;
|
|||
|
|
|||
|
[Header("<22><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")]
|
|||
|
[Tooltip("<22><>ǰ<EFBFBD><C7B0><EFBFBD>ŵĶ<C5B5><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")]
|
|||
|
public int currentAnimationIndex = 0;
|
|||
|
|
|||
|
[Header("ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")]
|
|||
|
[Tooltip("ѡ<><EFBFBD><F1B6AFBB><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")]
|
|||
|
public LoopType loopType = LoopType.Loop;
|
|||
|
|
|||
|
// <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
private Dictionary<int, AnimationSequence> animationDictionary = new Dictionary<int, AnimationSequence>();
|
|||
|
private AnimationSequence currentAnimation;
|
|||
|
private int currentFrameIndex = 0;
|
|||
|
private float frameTimer = 0f;
|
|||
|
private bool isPlaying = true;
|
|||
|
private bool pingPongForward = true;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>档
|
|||
|
/// </summary>
|
|||
|
private void Awake()
|
|||
|
{
|
|||
|
if (animationSequences == null || animationSequences.Count == 0)
|
|||
|
{
|
|||
|
Debug.LogError("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>Ϊ<EFBFBD>ա<EFBFBD><D5A1><EFBFBD><EFBFBD><EFBFBD> Inspector <20><><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
for (int i = 0; i < animationSequences.Count; i++)
|
|||
|
{
|
|||
|
if (!animationDictionary.ContainsKey(i))
|
|||
|
{
|
|||
|
animationDictionary.Add(i, animationSequences[i]);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogWarning($"<22><><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> {i}<7D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8>");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
SetAnimation(currentAnimationIndex);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20>ڿ<EFBFBD>ʼʱ<CABC><CAB1><EFBFBD>г<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
|||
|
/// </summary>
|
|||
|
private void Start()
|
|||
|
{
|
|||
|
if (spriteRenderer == null)
|
|||
|
{
|
|||
|
Debug.LogError("SpriteRenderer 'spriteRenderer' Ϊ<>ա<EFBFBD><D5A1><EFBFBD><EFBFBD><EFBFBD> Inspector <20>з<EFBFBD><D0B7><EFBFBD> SpriteRenderer<65><72>");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (currentAnimation != null && currentAnimation.sprites.Count > 0)
|
|||
|
{
|
|||
|
frameTimer = currentAnimation.frameTime;
|
|||
|
spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogError("<22><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ջ<D5BB><F2B2BBB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>顣");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// ÿ֡<C3BF><D6A1><EFBFBD>¶<EFBFBD><C2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>š<EFBFBD>
|
|||
|
/// </summary>
|
|||
|
private void Update()
|
|||
|
{
|
|||
|
if (!isPlaying || currentAnimation == null || currentAnimation.sprites.Count == 0)
|
|||
|
return;
|
|||
|
|
|||
|
frameTimer -= Time.deltaTime;
|
|||
|
|
|||
|
if (frameTimer <= 0f)
|
|||
|
{
|
|||
|
AdvanceFrame();
|
|||
|
frameTimer = currentAnimation.frameTime;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD>õ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>ŵĶ<C5B5><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>
|
|||
|
/// </summary>
|
|||
|
/// <param name="index"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
|||
|
public void SetAnimation(int index)
|
|||
|
{
|
|||
|
if (animationDictionary.TryGetValue(index, out AnimationSequence selectedAnimation))
|
|||
|
{
|
|||
|
currentAnimation = selectedAnimation;
|
|||
|
currentFrameIndex = 0;
|
|||
|
pingPongForward = true;
|
|||
|
frameTimer = currentAnimation.frameTime;
|
|||
|
|
|||
|
if (currentAnimation.sprites.Count > 0)
|
|||
|
{
|
|||
|
spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogWarning($"ѡ<>еĶ<D0B5><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> {index} û<>а<EFBFBD><D0B0><EFBFBD><EFBFBD>κξ<CEBA><CEBE>顣");
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogError($"SetAnimation: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> {index} <20><> animationDictionary <20><>δ<EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2>ź<EFBFBD><C5BA><EFBFBD>ͣ<EFBFBD><CDA3>
|
|||
|
/// </summary>
|
|||
|
/// <param name="play">true: <20><><EFBFBD>Ŷ<EFBFBD><C5B6><EFBFBD>, false: <20><>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD></param>
|
|||
|
public void PlayPauseAnimation(bool play)
|
|||
|
{
|
|||
|
isPlaying = play;
|
|||
|
if (isPlaying && currentAnimation != null && currentAnimation.sprites.Count > 0)
|
|||
|
{
|
|||
|
// ȷ<><C8B7><EFBFBD><EFBFBD>ǰ֡<C7B0><D6A1>ʾ<EFBFBD><CABE>ȷ
|
|||
|
spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex];
|
|||
|
frameTimer = currentAnimation.frameTime;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ֡<D2BB><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CDB4><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
/// </summary>
|
|||
|
private void AdvanceFrame()
|
|||
|
{
|
|||
|
switch (loopType)
|
|||
|
{
|
|||
|
case LoopType.Loop:
|
|||
|
currentFrameIndex = (currentFrameIndex + 1) % currentAnimation.sprites.Count;
|
|||
|
break;
|
|||
|
|
|||
|
case LoopType.Once:
|
|||
|
currentFrameIndex = Mathf.Min(currentFrameIndex + 1, currentAnimation.sprites.Count - 1);
|
|||
|
if (currentFrameIndex == currentAnimation.sprites.Count - 1)
|
|||
|
{
|
|||
|
isPlaying = false; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϻ<EFBFBD>ֹͣ
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case LoopType.PingPong:
|
|||
|
if (pingPongForward)
|
|||
|
{
|
|||
|
currentFrameIndex++;
|
|||
|
if (currentFrameIndex >= currentAnimation.sprites.Count - 1)
|
|||
|
{
|
|||
|
currentFrameIndex = currentAnimation.sprites.Count - 1;
|
|||
|
pingPongForward = false;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
currentFrameIndex--;
|
|||
|
if (currentFrameIndex <= 0)
|
|||
|
{
|
|||
|
currentFrameIndex = 0;
|
|||
|
pingPongForward = true;
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex];
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><D9B6><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>档
|
|||
|
/// </summary>
|
|||
|
private void OnDestroy()
|
|||
|
{
|
|||
|
animationDictionary.Clear();
|
|||
|
animationSequences = null;
|
|||
|
currentAnimation = null;
|
|||
|
}
|
|||
|
}
|