using System.Collections.Generic; using UnityEngine; /// /// 定义动画序列的循环类型。 /// public enum MyLoopType { Once, // 播放一次 Count, // 播放指定次数 Forever // 无限循环 } /// /// 定义动画组的循环类型。 /// public enum GroupLoopType { Once, // 动画组循环一次后销毁 Count, // 动画组循环指定次数后销毁 Forever // 动画组无限循环 } /// /// 表示一个动画序列,包括一系列精灵、每帧的显示时间和循环类型。 /// [System.Serializable] public class AnimationSequence { [Tooltip("动画序列中的精灵列表")] public List sprites = new List(); [Tooltip("每一帧的时间,单位秒")] public float frameTime = 0.1f; // 每帧的持续时间(秒) [Tooltip("动画序列的循环类型")] public MyLoopType loopType = MyLoopType.Forever; // 动画序列的循环类型 [Tooltip("动画序列的循环次数(仅当 LoopType 为 Count 时生效)")] public int loopCount = 1; // 动画序列的循环次数 } /// /// 控制精灵动画播放的类,支持组循环并允许为每个动画序列设置循环类型和循环次数。 /// public class SpriteAnimator : MonoBehaviour { [Header("动画序列列表")] [Tooltip("所有动画序列")] public List animationSequences = new List(); [Header("SpriteRenderer组件")] [Tooltip("用于显示动画的SpriteRenderer")] public SpriteRenderer spriteRenderer; [Header("组循环设置")] [Tooltip("选择动画组的循环类型")] public GroupLoopType groupLoopType = GroupLoopType.Forever; [Tooltip("动画组循环次数(仅当 GroupLoopType 为 Count 时生效)")] public int groupLoopCount = 1; // 内部变量 private Dictionary animationDictionary = new Dictionary(); private AnimationSequence currentAnimation; private int currentFrameIndex = 0; private float frameTimer = 0f; private bool isPlaying = true; private int currentAnimationIndex = 0; // 当前播放的动画序列索引 private int currentGroupLoopIteration = 0; // 当前动画组已循环次数 private int currentSequenceLoopIteration = 0; // 当前动画序列已循环次数 /// /// 初始化动画缓存。 /// private void Awake() { if (animationSequences == null || animationSequences.Count == 0) { Debug.LogError("动画序列列表为空。请在 Inspector 中添加动画序列。"); return; } for (int i = 0; i < animationSequences.Count; i++) { if (!animationDictionary.ContainsKey(i)) { animationDictionary.Add(i, animationSequences[i]); } else { Debug.LogWarning($"发现重复的动画索引 {i}。跳过重复项。"); } } SetAnimation(currentAnimationIndex); } /// /// 在开始时进行初始化。 /// private void Start() { if (spriteRenderer == null) { Debug.LogError("SpriteRenderer 'spriteRenderer' 为空。请在 Inspector 中分配 SpriteRenderer。"); return; } if (currentAnimation != null && currentAnimation.sprites.Count > 0) { frameTimer = currentAnimation.frameTime; spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex]; } else { Debug.LogError("当前动画序列为空或不包含精灵。"); } } /// /// 每帧更新动画播放。 /// private void Update() { 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; } } /// /// 设置当前播放的动画序列。 /// /// 动画编号 public void SetAnimation(int index) { if (animationDictionary.TryGetValue(index, out AnimationSequence selectedAnimation)) { currentAnimation = selectedAnimation; currentFrameIndex = 0; frameTimer = currentAnimation.frameTime; currentSequenceLoopIteration = 0; if (currentAnimation.sprites.Count > 0) { spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex]; } else { Debug.LogWarning($"选中的动画索引 {index} 没有包含任何精灵。"); } } else { Debug.LogError($"SetAnimation: 动画索引 {index} 在 animationDictionary 中未找到。"); } } /// /// 控制动画的播放和暂停。 /// /// true: 播放动画, false: 暂停动画 public void PlayPauseAnimation(bool play) { isPlaying = play; if (isPlaying && currentAnimation != null && currentAnimation.sprites.Count > 0) { // 确保当前帧显示正确 spriteRenderer.sprite = currentAnimation.sprites[currentFrameIndex]; frameTimer = currentAnimation.frameTime; // 不重置 currentSequenceLoopIteration,以免影响循环次数控制 } } /// /// 前进到下一帧并更新SpriteRenderer的精灵。 /// private void AdvanceFrame() { if (currentAnimation.sprites.Count == 0) return; currentFrameIndex++; if (currentFrameIndex >= currentAnimation.sprites.Count) { 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); } /// /// 在销毁对象时清理缓存。 /// private void OnDestroy() { animationDictionary.Clear(); animationSequences = null; currentAnimation = null; } }