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