更新动画控制器
This commit is contained in:
parent
b109b30ae1
commit
314c5d4c32
@ -2,7 +2,27 @@ using System.Collections.Generic;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 表示一个动画序列,包括一系列精灵和每帧的显示时间。
|
/// 定义动画序列的循环类型。
|
||||||
|
/// </summary>
|
||||||
|
public enum MyLoopType
|
||||||
|
{
|
||||||
|
Once, // 播放一次
|
||||||
|
Count, // 播放指定次数
|
||||||
|
Forever // 无限循环
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 定义动画组的循环类型。
|
||||||
|
/// </summary>
|
||||||
|
public enum GroupLoopType
|
||||||
|
{
|
||||||
|
Once, // 动画组循环一次后销毁
|
||||||
|
Count, // 动画组循环指定次数后销毁
|
||||||
|
Forever // 动画组无限循环
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示一个动画序列,包括一系列精灵、每帧的显示时间和循环类型。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class AnimationSequence
|
public class AnimationSequence
|
||||||
@ -12,23 +32,19 @@ public class AnimationSequence
|
|||||||
|
|
||||||
[Tooltip("每一帧的时间,单位秒")]
|
[Tooltip("每一帧的时间,单位秒")]
|
||||||
public float frameTime = 0.1f; // 每帧的持续时间(秒)
|
public float frameTime = 0.1f; // 每帧的持续时间(秒)
|
||||||
|
|
||||||
|
[Tooltip("动画序列的循环类型")]
|
||||||
|
public MyLoopType loopType = MyLoopType.Forever; // 动画序列的循环类型
|
||||||
|
|
||||||
|
[Tooltip("动画序列的循环次数(仅当 LoopType 为 Count 时生效)")]
|
||||||
|
public int loopCount = 1; // 动画序列的循环次数
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 控制精灵动画播放的类,使用 Dictionary 进行精灵缓存管理。
|
/// 控制精灵动画播放的类,支持组循环并允许为每个动画序列设置循环类型和循环次数。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SpriteAnimator : MonoBehaviour
|
public class SpriteAnimator : MonoBehaviour
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 定义动画的循环类型。
|
|
||||||
/// </summary>
|
|
||||||
public enum LoopType
|
|
||||||
{
|
|
||||||
Loop, // 无限循环
|
|
||||||
Once, // 播放一次
|
|
||||||
PingPong // 来回播放
|
|
||||||
}
|
|
||||||
|
|
||||||
[Header("动画序列列表")]
|
[Header("动画序列列表")]
|
||||||
[Tooltip("所有动画序列")]
|
[Tooltip("所有动画序列")]
|
||||||
public List<AnimationSequence> animationSequences = new List<AnimationSequence>();
|
public List<AnimationSequence> animationSequences = new List<AnimationSequence>();
|
||||||
@ -37,13 +53,12 @@ public class SpriteAnimator : MonoBehaviour
|
|||||||
[Tooltip("用于显示动画的SpriteRenderer")]
|
[Tooltip("用于显示动画的SpriteRenderer")]
|
||||||
public SpriteRenderer spriteRenderer;
|
public SpriteRenderer spriteRenderer;
|
||||||
|
|
||||||
[Header("当前动画编号")]
|
[Header("组循环设置")]
|
||||||
[Tooltip("当前播放的动画编号")]
|
[Tooltip("选择动画组的循环类型")]
|
||||||
public int currentAnimationIndex = 0;
|
public GroupLoopType groupLoopType = GroupLoopType.Forever;
|
||||||
|
|
||||||
[Header("循环类型")]
|
[Tooltip("动画组循环次数(仅当 GroupLoopType 为 Count 时生效)")]
|
||||||
[Tooltip("选择动画的循环类型")]
|
public int groupLoopCount = 1;
|
||||||
public LoopType loopType = LoopType.Loop;
|
|
||||||
|
|
||||||
// 内部变量
|
// 内部变量
|
||||||
private Dictionary<int, AnimationSequence> animationDictionary = new Dictionary<int, AnimationSequence>();
|
private Dictionary<int, AnimationSequence> animationDictionary = new Dictionary<int, AnimationSequence>();
|
||||||
@ -51,7 +66,9 @@ public class SpriteAnimator : MonoBehaviour
|
|||||||
private int currentFrameIndex = 0;
|
private int currentFrameIndex = 0;
|
||||||
private float frameTimer = 0f;
|
private float frameTimer = 0f;
|
||||||
private bool isPlaying = true;
|
private bool isPlaying = true;
|
||||||
private bool pingPongForward = true;
|
private int currentAnimationIndex = 0; // 当前播放的动画序列索引
|
||||||
|
private int currentGroupLoopIteration = 0; // 当前动画组已循环次数
|
||||||
|
private int currentSequenceLoopIteration = 0; // 当前动画序列已循环次数
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化动画缓存。
|
/// 初始化动画缓存。
|
||||||
@ -109,11 +126,45 @@ public class SpriteAnimator : MonoBehaviour
|
|||||||
if (!isPlaying || currentAnimation == null || currentAnimation.sprites.Count == 0)
|
if (!isPlaying || currentAnimation == null || currentAnimation.sprites.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// 更新帧计时器
|
||||||
frameTimer -= Time.deltaTime;
|
frameTimer -= Time.deltaTime;
|
||||||
|
|
||||||
if (frameTimer <= 0f)
|
if (frameTimer <= 0f)
|
||||||
{
|
{
|
||||||
AdvanceFrame();
|
AdvanceFrame();
|
||||||
|
|
||||||
|
// 获取当前动画序列的循环类型
|
||||||
|
MyLoopType currentLoopType = currentAnimation.loopType;
|
||||||
|
|
||||||
|
switch (currentLoopType)
|
||||||
|
{
|
||||||
|
case MyLoopType.Once:
|
||||||
|
if (currentFrameIndex == currentAnimation.sprites.Count - 1)
|
||||||
|
{
|
||||||
|
MoveToNextSequence();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MyLoopType.Count:
|
||||||
|
if (currentFrameIndex == currentAnimation.sprites.Count - 1)
|
||||||
|
{
|
||||||
|
currentSequenceLoopIteration++;
|
||||||
|
if (currentSequenceLoopIteration >= currentAnimation.loopCount)
|
||||||
|
{
|
||||||
|
MoveToNextSequence();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResetCurrentSequence();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MyLoopType.Forever:
|
||||||
|
// 无需特殊处理,继续循环
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
frameTimer = currentAnimation.frameTime;
|
frameTimer = currentAnimation.frameTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,8 +179,8 @@ public class SpriteAnimator : MonoBehaviour
|
|||||||
{
|
{
|
||||||
currentAnimation = selectedAnimation;
|
currentAnimation = selectedAnimation;
|
||||||
currentFrameIndex = 0;
|
currentFrameIndex = 0;
|
||||||
pingPongForward = true;
|
|
||||||
frameTimer = currentAnimation.frameTime;
|
frameTimer = currentAnimation.frameTime;
|
||||||
|
currentSequenceLoopIteration = 0;
|
||||||
|
|
||||||
if (currentAnimation.sprites.Count > 0)
|
if (currentAnimation.sprites.Count > 0)
|
||||||
{
|
{
|
||||||
@ -158,53 +209,76 @@ public class SpriteAnimator : MonoBehaviour
|
|||||||
// 确保当前帧显示正确
|
// 确保当前帧显示正确
|
||||||
spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex];
|
spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex];
|
||||||
frameTimer = currentAnimation.frameTime;
|
frameTimer = currentAnimation.frameTime;
|
||||||
|
// 不重置 currentSequenceLoopIteration,以免影响循环次数控制
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 前进到下一帧或根据循环类型处理帧索引。
|
/// 前进到下一帧并更新SpriteRenderer的精灵。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void AdvanceFrame()
|
private void AdvanceFrame()
|
||||||
{
|
{
|
||||||
switch (loopType)
|
if (currentAnimation.sprites.Count == 0)
|
||||||
{
|
return;
|
||||||
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; // 动画播放完毕后停止
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LoopType.PingPong:
|
|
||||||
if (pingPongForward)
|
|
||||||
{
|
|
||||||
currentFrameIndex++;
|
currentFrameIndex++;
|
||||||
if (currentFrameIndex >= currentAnimation.sprites.Count - 1)
|
|
||||||
|
if (currentFrameIndex >= currentAnimation.sprites.Count)
|
||||||
{
|
{
|
||||||
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];
|
spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置当前动画序列的播放状态,以便重新循环。
|
||||||
|
/// </summary>
|
||||||
|
private void ResetCurrentSequence()
|
||||||
|
{
|
||||||
|
currentFrameIndex = 0;
|
||||||
|
frameTimer = currentAnimation.frameTime;
|
||||||
|
spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 切换到下一个动画序列,并根据组循环类型决定是否继续循环或销毁动画组。
|
||||||
|
/// </summary>
|
||||||
|
private void MoveToNextSequence()
|
||||||
|
{
|
||||||
|
currentAnimationIndex++;
|
||||||
|
|
||||||
|
if (currentAnimationIndex >= animationSequences.Count)
|
||||||
|
{
|
||||||
|
// 完整播放了一遍动画组
|
||||||
|
currentAnimationIndex = 0;
|
||||||
|
currentGroupLoopIteration++;
|
||||||
|
|
||||||
|
switch (groupLoopType)
|
||||||
|
{
|
||||||
|
case GroupLoopType.Once:
|
||||||
|
isPlaying = false;
|
||||||
|
Destroy(gameObject); // 销毁动画组
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GroupLoopType.Count:
|
||||||
|
if (currentGroupLoopIteration >= groupLoopCount)
|
||||||
|
{
|
||||||
|
isPlaying = false;
|
||||||
|
Destroy(gameObject); // 销毁动画组
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GroupLoopType.Forever:
|
||||||
|
// 无限循环,继续播放
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAnimation(currentAnimationIndex);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 在销毁对象时清理缓存。
|
/// 在销毁对象时清理缓存。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user