单序列帧动画 & Example示例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 动画序列数据结构
/// </summary>
[System.Serializable]
public class AnimationSequence
{
[Header("序列设置")]
public string name = "Animation"; // 动画名称
public Sprite[] frames; // 序列帧图片数组
[Range(1f, 120f)]
public float framerate = 30f; // 播放帧率
public bool loop = true; // 是否循环播放
[Header("渲染组件")]
public SpriteRenderer targetSpriteRenderer; // 目标SpriteRenderer组件
public Image targetImage; // 目标UI Image组件
public bool useGlobalRenderer = true; // 是否使用全局渲染器(如果为false,使用上面指定的组件)
[Header("渲染设置")]
public bool setNativeSize = false; // 是否设置为原始尺寸(仅对Image有效)
public bool preserveAspect = true; // 是否保持宽高比(仅对Image有效)
public Color tintColor = Color.white; // 着色颜色
public Material overrideMaterial; // 覆盖材质
[Header("变换设置")]
public bool useCustomScale = false; // 是否使用自定义缩放
public Vector3 customScale = Vector3.one; // 自定义缩放值
public bool useCustomRotation = false; // 是否使用自定义旋转
public Vector3 customRotation = Vector3.zero; // 自定义旋转值
[Header("排序设置")]
public bool overrideSortingOrder = false; // 是否覆盖排序层级
public int sortingOrder = 0; // 排序层级
public string sortingLayerName = "Default"; // 排序层名称
[Header("曲线控制")]
public AnimationCurve curve; // 动画曲线,用于控制播放速度
public bool useCurve = false; // 是否使用曲线控制
// 运行时数据(不序列化)
[System.NonSerialized]
private Vector3 originalScale;
[System.NonSerialized]
private Vector3 originalRotation;
[System.NonSerialized]
private Color originalColor;
[System.NonSerialized]
private Material originalMaterial;
[System.NonSerialized]
private int originalSortingOrder;
[System.NonSerialized]
private string originalSortingLayer;
[System.NonSerialized]
private bool hasStoredOriginalValues = false;
// 构造函数
public AnimationSequence()
{
curve = AnimationCurve.Linear(0f, 1f, 1f, 1f);
}
public AnimationSequence(string animName, Sprite[] animFrames, float rate = 30f, bool isLoop = true)
{
name = animName;
frames = animFrames;
framerate = rate;
loop = isLoop;
curve = AnimationCurve.Linear(0f, 1f, 1f, 1f);
}
/// <summary>
/// 存储原始值(用于恢复)
/// </summary>
public void StoreOriginalValues(SpriteRenderer spriteRenderer, Image image)
{
if (hasStoredOriginalValues) return;
if (!useGlobalRenderer)
{
if (targetSpriteRenderer != null)
spriteRenderer = targetSpriteRenderer;
if (targetImage != null)
image = targetImage;
}
if (spriteRenderer != null)
{
originalScale = spriteRenderer.transform.localScale;
originalRotation = spriteRenderer.transform.localEulerAngles;
originalColor = spriteRenderer.color;
originalMaterial = spriteRenderer.material;
originalSortingOrder = spriteRenderer.sortingOrder;
originalSortingLayer = spriteRenderer.sortingLayerName;
}
else if (image != null)
{
originalScale = image.transform.localScale;
originalRotation = image.transform.localEulerAngles;
originalColor = image.color;
originalMaterial = image.material;
}
hasStoredOriginalValues = true;
}
/// <summary>
/// 恢复原始值
/// </summary>
public void RestoreOriginalValues(SpriteRenderer spriteRenderer, Image image)
{
if (!hasStoredOriginalValues) return;
if (!useGlobalRenderer)
{
if (targetSpriteRenderer != null)
spriteRenderer = targetSpriteRenderer;
if (targetImage != null)
image = targetImage;
}
if (spriteRenderer != null)
{
spriteRenderer.transform.localScale = originalScale;
spriteRenderer.transform.localEulerAngles = originalRotation;
spriteRenderer.color = originalColor;
spriteRenderer.material = originalMaterial;
spriteRenderer.sortingOrder = originalSortingOrder;
spriteRenderer.sortingLayerName = originalSortingLayer;
}
else if (image != null)
{
image.transform.localScale = originalScale;
image.transform.localEulerAngles = originalRotation;
image.color = originalColor;
image.material = originalMaterial;
}
}
/// <summary>
/// 应用渲染设置
/// </summary>
public void ApplyRenderSettings(SpriteRenderer spriteRenderer, Image image)
{
if (!useGlobalRenderer)
{
if (targetSpriteRenderer != null)
spriteRenderer = targetSpriteRenderer;
if (targetImage != null)
image = targetImage;
}
if (spriteRenderer != null)
{
// 应用颜色
spriteRenderer.color = tintColor;
// 应用材质
if (overrideMaterial != null)
spriteRenderer.material = overrideMaterial;
// 应用排序设置
if (overrideSortingOrder)
{
spriteRenderer.sortingOrder = sortingOrder;
spriteRenderer.sortingLayerName = sortingLayerName;
}
// 应用变换设置
if (useCustomScale)
spriteRenderer.transform.localScale = customScale;
if (useCustomRotation)
spriteRenderer.transform.localEulerAngles = customRotation;
}
else if (image != null)
{
// 应用颜色
image.color = tintColor;
// 应用材质
if (overrideMaterial != null)
image.material = overrideMaterial;
// 应用Image特有设置
if (setNativeSize)
image.SetNativeSize();
image.preserveAspect = preserveAspect;
// 应用变换设置
if (useCustomScale)
image.transform.localScale = customScale;
if (useCustomRotation)
image.transform.localEulerAngles = customRotation;
}
}
/// <summary>
/// 获取实际使用的SpriteRenderer
/// </summary>
public SpriteRenderer GetSpriteRenderer(SpriteRenderer defaultRenderer)
{
return useGlobalRenderer ? defaultRenderer : targetSpriteRenderer;
}
/// <summary>
/// 获取实际使用的Image
/// </summary>
public Image GetImage(Image defaultImage)
{
return useGlobalRenderer ? defaultImage : targetImage;
}
}
/// <summary>
/// 序列帧动画播放器
/// 支持SpriteRenderer和Image两种组件,支持多个动画序列
/// </summary>
public class SequenceFramePlayer : MonoBehaviour
{
[Header("动画序列")]
[SerializeField] private List<AnimationSequence> animations = new List<AnimationSequence>(); // 多个动画序列
[SerializeField] private int defaultAnimationIndex = 0; // 默认播放的动画索引
[SerializeField] private bool playOnStart = true; // 启动时自动播放
[SerializeField] private bool ignoreTimeScale = false; // 是否忽略时间缩放
[Header("渲染组件")]
[SerializeField] private SpriteRenderer spriteRenderer; // SpriteRenderer组件
[SerializeField] private Image image; // UI Image组件
// 私有变量
private int currentAnimationIndex = 0; // 当前播放的动画索引
private int currentFrameIndex = 0;
private float timer = 0f;
private bool isPlaying = false;
// 属性
public bool IsPlaying => isPlaying;
public int CurrentAnimationIndex => currentAnimationIndex;
public string CurrentAnimationName => GetCurrentAnimation()?.name ?? "None";
public int CurrentFrame => currentFrameIndex;
public int TotalFrames => GetCurrentAnimation()?.frames?.Length ?? 0;
public float Progress => TotalFrames > 0 ? (float)currentFrameIndex / TotalFrames : 0f;
public int AnimationCount => animations?.Count ?? 0;
// 事件
public System.Action OnAnimationStart;
public System.Action OnAnimationComplete;
public System.Action<int> OnFrameChanged;
public System.Action<int, string> OnAnimationChanged; // 动画切换事件 (索引, 名称)
private void Awake()
{
// 自动获取组件
if (spriteRenderer == null)
spriteRenderer = GetComponent<SpriteRenderer>();
if (image == null)
image = GetComponent<Image>();
// 初始化默认动画索引
if (defaultAnimationIndex >= 0 && defaultAnimationIndex < animations.Count)
{
currentAnimationIndex = defaultAnimationIndex;
}
}
private void Start()
{
if (playOnStart && HasValidAnimation())
{
Play();
}
}
/// <summary>
/// 获取当前动画序列
/// </summary>
private AnimationSequence GetCurrentAnimation()
{
if (animations == null || currentAnimationIndex < 0 || currentAnimationIndex >= animations.Count)
return null;
return animations[currentAnimationIndex];
}
/// <summary>
/// 检查当前是否有有效的动画
/// </summary>
private bool HasValidAnimation()
{
var anim = GetCurrentAnimation();
return anim != null && anim.frames != null && anim.frames.Length > 0;
}
private void Update()
{
if (!isPlaying || !HasValidAnimation())
return;
var currentAnim = GetCurrentAnimation();
// 计算最终帧率
float finalFramerate = currentAnim.framerate;
if (currentAnim.useCurve && currentAnim.curve != null)
{
// 从曲线获取当前帧率
float curveValue = currentAnim.curve.Evaluate((float)currentFrameIndex / currentAnim.frames.Length);
finalFramerate = curveValue * currentAnim.framerate;
}
// 帧率有效(添加最小值保护)
if (finalFramerate > 0.01f) // 最小帧率保护
{
// 获取当前时间
float time = ignoreTimeScale ? Time.unscaledTime : Time.time;
// 计算帧间隔时间
float interval = 1.0f / finalFramerate;
// 满足更新条件,执行更新操作
if (time - timer > interval)
{
// 执行更新操作
DoUpdate();
timer = time;
}
}
else
{
// 帧率过低时,使用默认帧率
Debug.LogWarning($"Framerate too low ({finalFramerate}), using default framerate.");
finalFramerate = 1f; // 使用1帧/秒作为最低帧率
float time = ignoreTimeScale ? Time.unscaledTime : Time.time;
float interval = 1.0f / finalFramerate;
if (time - timer > interval)
{
DoUpdate();
timer = time;
}
}
}
/// <summary>
/// 执行帧更新
/// </summary>
private void DoUpdate()
{
var currentAnim = GetCurrentAnimation();
if (currentAnim == null) return;
// 更新帧索引
currentFrameIndex++;
// 检查是否播放完成
if (currentFrameIndex >= currentAnim.frames.Length)
{
if (currentAnim.loop)
{
currentFrameIndex = 0; // 循环播放
}
else
{
currentFrameIndex = currentAnim.frames.Length - 1;
Stop();
OnAnimationComplete?.Invoke();
return;
}
}
// 更新显示的帧
UpdateFrame();
// 触发帧变化事件
OnFrameChanged?.Invoke(currentFrameIndex);
}
/// <summary>
/// 更新当前显示的帧
/// </summary>
private void UpdateFrame()
{
var currentAnim = GetCurrentAnimation();
if (currentAnim?.frames == null || currentFrameIndex < 0 || currentFrameIndex >= currentAnim.frames.Length)
return;
Sprite currentSprite = currentAnim.frames[currentFrameIndex];
// 获取实际使用的渲染组件
SpriteRenderer targetSpriteRenderer = currentAnim.GetSpriteRenderer(spriteRenderer);
Image targetImage = currentAnim.GetImage(image);
// 更新SpriteRenderer
if (targetSpriteRenderer != null)
{
targetSpriteRenderer.sprite = currentSprite;
}
// 更新Image
if (targetImage != null)
{
targetImage.sprite = currentSprite;
}
}
/// <summary>
/// 开始播放当前动画
/// </summary>
public void Play()
{
if (!HasValidAnimation())
{
Debug.LogWarning("No valid animation to play!");
return;
}
// 应用当前动画的渲染设置
var currentAnim = GetCurrentAnimation();
if (currentAnim != null)
{
currentAnim.StoreOriginalValues(spriteRenderer, image);
currentAnim.ApplyRenderSettings(spriteRenderer, image);
}
isPlaying = true;
timer = ignoreTimeScale ? Time.unscaledTime : Time.time;
UpdateFrame();
OnAnimationStart?.Invoke();
}
/// <summary>
/// 播放指定索引的动画
/// </summary>
public void PlayAnimation(int animationIndex)
{
if (SetAnimation(animationIndex))
{
Play();
}
}
/// <summary>
/// 播放指定名称的动画
/// </summary>
public void PlayAnimation(string animationName)
{
int index = GetAnimationIndex(animationName);
if (index >= 0)
{
PlayAnimation(index);
}
else
{
Debug.LogWarning($"Animation '{animationName}' not found!");
}
}
/// <summary>
/// 停止播放
/// </summary>
public void Stop()
{
isPlaying = false;
}
/// <summary>
/// 暂停播放
/// </summary>
public void Pause()
{
isPlaying = false;
}
/// <summary>
/// 重置到第一帧
/// </summary>
public void Reset()
{
currentFrameIndex = 0;
UpdateFrame();
}
/// <summary>
/// 跳转到指定帧
/// </summary>
public void SetFrame(int frameIndex)
{
var currentAnim = GetCurrentAnimation();
if (currentAnim?.frames == null || frameIndex < 0 || frameIndex >= currentAnim.frames.Length)
return;
currentFrameIndex = frameIndex;
UpdateFrame();
OnFrameChanged?.Invoke(currentFrameIndex);
}
/// <summary>
/// 设置当前动画
/// </summary>
public bool SetAnimation(int animationIndex)
{
if (animations == null || animationIndex < 0 || animationIndex >= animations.Count)
{
Debug.LogWarning($"Invalid animation index: {animationIndex}");
return false;
}
if (currentAnimationIndex != animationIndex)
{
// 恢复之前动画的设置
var previousAnim = GetCurrentAnimation();
if (previousAnim != null)
{
previousAnim.RestoreOriginalValues(spriteRenderer, image);
}
// 切换到新动画
currentAnimationIndex = animationIndex;
// 存储并应用新动画的设置
var newAnim = GetCurrentAnimation();
if (newAnim != null)
{
newAnim.StoreOriginalValues(spriteRenderer, image);
newAnim.ApplyRenderSettings(spriteRenderer, image);
}
Reset();
OnAnimationChanged?.Invoke(currentAnimationIndex, CurrentAnimationName);
}
return true;
}
/// <summary>
/// 设置当前动画(通过名称)
/// </summary>
public bool SetAnimation(string animationName)
{
int index = GetAnimationIndex(animationName);
if (index >= 0)
{
return SetAnimation(index);
}
return false;
}
/// <summary>
/// 获取动画索引(通过名称)
/// </summary>
public int GetAnimationIndex(string animationName)
{
if (animations == null) return -1;
for (int i = 0; i < animations.Count; i++)
{
if (animations[i].name == animationName)
return i;
}
return -1;
}
/// <summary>
/// 添加新的动画序列
/// </summary>
public void AddAnimation(AnimationSequence newAnimation)
{
if (animations == null)
animations = new List<AnimationSequence>();
animations.Add(newAnimation);
}
/// <summary>
/// 添加新的动画序列
/// </summary>
public void AddAnimation(string name, Sprite[] frames, float framerate = 30f, bool loop = true)
{
AddAnimation(new AnimationSequence(name, frames, framerate, loop));
}
/// <summary>
/// 移除动画序列
/// </summary>
public bool RemoveAnimation(int index)
{
if (animations == null || index < 0 || index >= animations.Count)
return false;
animations.RemoveAt(index);
// 调整当前动画索引
if (currentAnimationIndex >= animations.Count)
{
currentAnimationIndex = Mathf.Max(0, animations.Count - 1);
}
return true;
}
/// <summary>
/// 移除动画序列
/// </summary>
public bool RemoveAnimation(string animationName)
{
int index = GetAnimationIndex(animationName);
return index >= 0 && RemoveAnimation(index);
}
/// <summary>
/// 获取所有动画名称
/// </summary>
public string[] GetAnimationNames()
{
if (animations == null) return new string[0];
string[] names = new string[animations.Count];
for (int i = 0; i < animations.Count; i++)
{
names[i] = animations[i].name;
}
return names;
}
/// <summary>
/// 获取当前动画使用的SpriteRenderer
/// </summary>
public SpriteRenderer GetCurrentSpriteRenderer()
{
var currentAnim = GetCurrentAnimation();
return currentAnim?.GetSpriteRenderer(spriteRenderer);
}
/// <summary>
/// 获取当前动画使用的Image
/// </summary>
public Image GetCurrentImage()
{
var currentAnim = GetCurrentAnimation();
return currentAnim?.GetImage(image);
}
/// <summary>
/// 设置当前动画的渲染颜色
/// </summary>
public void SetCurrentAnimationColor(Color color)
{
var currentAnim = GetCurrentAnimation();
if (currentAnim != null)
{
currentAnim.tintColor = color;
// 立即应用
SpriteRenderer targetSpriteRenderer = currentAnim.GetSpriteRenderer(spriteRenderer);
Image targetImage = currentAnim.GetImage(image);
if (targetSpriteRenderer != null)
targetSpriteRenderer.color = color;
if (targetImage != null)
targetImage.color = color;
}
}
/// <summary>
/// 设置当前动画的排序层级
/// </summary>
public void SetCurrentAnimationSortingOrder(int order)
{
var currentAnim = GetCurrentAnimation();
if (currentAnim != null)
{
currentAnim.sortingOrder = order;
currentAnim.overrideSortingOrder = true;
// 立即应用
SpriteRenderer targetSpriteRenderer = currentAnim.GetSpriteRenderer(spriteRenderer);
if (targetSpriteRenderer != null)
targetSpriteRenderer.sortingOrder = order;
}
}
/// <summary>
/// 设置当前动画的缩放
/// </summary>
public void SetCurrentAnimationScale(Vector3 scale)
{
var currentAnim = GetCurrentAnimation();
if (currentAnim != null)
{
currentAnim.customScale = scale;
currentAnim.useCustomScale = true;
// 立即应用
SpriteRenderer targetSpriteRenderer = currentAnim.GetSpriteRenderer(spriteRenderer);
Image targetImage = currentAnim.GetImage(image);
if (targetSpriteRenderer != null)
targetSpriteRenderer.transform.localScale = scale;
if (targetImage != null)
targetImage.transform.localScale = scale;
}
}
/// <summary>
/// 为指定动画设置目标渲染组件
/// </summary>
public void SetAnimationRenderer(int animationIndex, SpriteRenderer targetRenderer, Image targetImg = null)
{
if (animations == null || animationIndex < 0 || animationIndex >= animations.Count)
return;
animations[animationIndex].targetSpriteRenderer = targetRenderer;
animations[animationIndex].targetImage = targetImg;
animations[animationIndex].useGlobalRenderer = (targetRenderer == null && targetImg == null);
}
/// <summary>
/// 为指定动画设置目标渲染组件(通过名称)
/// </summary>
public void SetAnimationRenderer(string animationName, SpriteRenderer targetRenderer, Image targetImg = null)
{
int index = GetAnimationIndex(animationName);
if (index >= 0)
{
SetAnimationRenderer(index, targetRenderer, targetImg);
}
}
/// <summary>
/// 启用/禁用组件
/// </summary>
private void OnEnable()
{
if (playOnStart && HasValidAnimation())
{
Play();
}
}
private void OnDisable()
{
Stop();
// 恢复原始设置
var currentAnim = GetCurrentAnimation();
if (currentAnim != null)
{
currentAnim.RestoreOriginalValues(spriteRenderer, image);
}
}
}
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// SequenceFramePlayer 使用示例
/// </summary>
public class SequenceFramePlayerExample : MonoBehaviour
{
[Header("示例组件")]
public SequenceFramePlayer framePlayer;
public SpriteRenderer backgroundRenderer;
public SpriteRenderer characterRenderer;
public Image uiImage;
[Header("示例序列帧")]
public Sprite[] idleFrames;
public Sprite[] walkFrames;
public Sprite[] attackFrames;
public Sprite[] uiFrames;
private void Start()
{
// 示例1:基础使用
BasicUsageExample();
// 示例2:多渲染器使用
MultiRendererExample();
// 示例3:运行时动态管理
RuntimeManagementExample();
// 示例4:事件监听
EventListenerExample();
}
/// <summary>
/// 示例1:基础使用 - 简单播放动画
/// </summary>
void BasicUsageExample()
{
Debug.Log("=== 基础使用示例 ===");
// 直接播放当前动画(默认第0个)
framePlayer.Play();
// 播放指定索引的动画
framePlayer.PlayAnimation(1);
// 播放指定名称的动画
framePlayer.PlayAnimation("idle");
// 控制播放
StartCoroutine(BasicPlaybackControl());
}
IEnumerator BasicPlaybackControl()
{
yield return new WaitForSeconds(2f);
// 暂停
framePlayer.Pause();
Debug.Log("动画暂停");
yield return new WaitForSeconds(1f);
// 继续播放
framePlayer.Play();
Debug.Log("动画继续");
yield return new WaitForSeconds(2f);
// 跳转到指定帧
framePlayer.SetFrame(5);
Debug.Log("跳转到第5帧");
yield return new WaitForSeconds(1f);
// 重置到第一帧
framePlayer.Reset();
Debug.Log("重置到第一帧");
}
/// <summary>
/// 示例2:多渲染器使用 - 不同动画渲染到不同组件
/// </summary>
void MultiRendererExample()
{
Debug.Log("=== 多渲染器示例 ===");
// 为不同动画设置不同的渲染器
framePlayer.SetAnimationRenderer("background", backgroundRenderer);
framePlayer.SetAnimationRenderer("character", characterRenderer);
framePlayer.SetAnimationRenderer("ui", null, uiImage); // UI动画渲染到Image
// 播放背景动画
framePlayer.PlayAnimation("background");
StartCoroutine(SwitchRenderers());
}
IEnumerator SwitchRenderers()
{
yield return new WaitForSeconds(3f);
// 切换到角色动画(会自动切换到characterRenderer)
framePlayer.PlayAnimation("character");
Debug.Log("切换到角色动画");
yield return new WaitForSeconds(3f);
// 切换到UI动画(会自动切换到uiImage)
framePlayer.PlayAnimation("ui");
Debug.Log("切换到UI动画");
}
/// <summary>
/// 示例3:运行时动态管理 - 动态添加、修改动画
/// </summary>
void RuntimeManagementExample()
{
Debug.Log("=== 运行时管理示例 ===");
// 运行时添加新动画
if (idleFrames != null && idleFrames.Length > 0)
{
framePlayer.AddAnimation("runtime_idle", idleFrames, 24f, true);
Debug.Log("添加了运行时空闲动画");
}
if (walkFrames != null && walkFrames.Length > 0)
{
framePlayer.AddAnimation("runtime_walk", walkFrames, 30f, true);
Debug.Log("添加了运行时行走动画");
}
// 获取所有动画名称
string[] animNames = framePlayer.GetAnimationNames();
Debug.Log($"当前动画数量: {animNames.Length}");
foreach (string name in animNames)
{
Debug.Log($"动画: {name}");
}
StartCoroutine(RuntimeDynamicControl());
}
IEnumerator RuntimeDynamicControl()
{
yield return new WaitForSeconds(1f);
// 播放运行时添加的动画
framePlayer.PlayAnimation("runtime_idle");
Debug.Log("播放运行时空闲动画");
yield return new WaitForSeconds(2f);
// 动态修改当前动画的颜色
framePlayer.SetCurrentAnimationColor(Color.red);
Debug.Log("设置动画颜色为红色");
yield return new WaitForSeconds(1f);
// 动态修改当前动画的缩放
framePlayer.SetCurrentAnimationScale(new Vector3(1.5f, 1.5f, 1f));
Debug.Log("设置动画缩放为1.5倍");
yield return new WaitForSeconds(1f);
// 动态修改排序层级
framePlayer.SetCurrentAnimationSortingOrder(10);
Debug.Log("设置排序层级为10");
yield return new WaitForSeconds(2f);
// 切换到其他动画(会自动恢复原始设置)
framePlayer.PlayAnimation("runtime_walk");
Debug.Log("切换到行走动画(自动恢复设置)");
}
/// <summary>
/// 示例4:事件监听 - 监听动画事件
/// </summary>
void EventListenerExample()
{
Debug.Log("=== 事件监听示例 ===");
// 监听动画开始事件
framePlayer.OnAnimationStart += () => {
Debug.Log($"动画开始播放: {framePlayer.CurrentAnimationName}");
};
// 监听动画完成事件
framePlayer.OnAnimationComplete += () => {
Debug.Log($"动画播放完成: {framePlayer.CurrentAnimationName}");
OnAnimationCompleted();
};
// 监听帧变化事件
framePlayer.OnFrameChanged += (frameIndex) => {
Debug.Log($"当前帧: {frameIndex}/{framePlayer.TotalFrames},进度: {framePlayer.Progress:P1}");
};
// 监听动画切换事件
framePlayer.OnAnimationChanged += (index, name) => {
Debug.Log($"动画切换: 索引 {index},名称 '{name}'");
OnAnimationSwitched(index, name);
};
}
void OnAnimationCompleted()
{
// 动画完成后的逻辑
Debug.Log("执行动画完成后的逻辑");
}
void OnAnimationSwitched(int index, string name)
{
// 动画切换后的逻辑
Debug.Log($"动画已切换到: {name}");
// 获取当前使用的渲染组件
SpriteRenderer currentSpriteRenderer = framePlayer.GetCurrentSpriteRenderer();
Image currentImage = framePlayer.GetCurrentImage();
if (currentSpriteRenderer != null)
Debug.Log($"当前使用SpriteRenderer: {currentSpriteRenderer.name}");
if (currentImage != null)
Debug.Log($"当前使用Image: {currentImage.name}");
}
/// <summary>
/// 键盘控制示例
/// </summary>
void Update()
{
// 数字键1-4控制动画播放
if (Input.GetKeyDown(KeyCode.Alpha1))
{
framePlayer.PlayAnimation(0);
Debug.Log("播放动画 0");
}
if (Input.GetKeyDown(KeyCode.Alpha2))
{
framePlayer.PlayAnimation(1);
Debug.Log("播放动画 1");
}
if (Input.GetKeyDown(KeyCode.Alpha3))
{
framePlayer.PlayAnimation(2);
Debug.Log("播放动画 2");
}
if (Input.GetKeyDown(KeyCode.Alpha4))
{
framePlayer.PlayAnimation(3);
Debug.Log("播放动画 3");
}
// 空格键暂停/播放
if (Input.GetKeyDown(KeyCode.Space))
{
if (framePlayer.IsPlaying)
{
framePlayer.Pause();
Debug.Log("暂停动画");
}
else
{
framePlayer.Play();
Debug.Log("继续动画");
}
}
// R键重置
if (Input.GetKeyDown(KeyCode.R))
{
framePlayer.Reset();
Debug.Log("重置动画");
}
// C键改变颜色
if (Input.GetKeyDown(KeyCode.C))
{
Color randomColor = new Color(Random.value, Random.value, Random.value, 1f);
framePlayer.SetCurrentAnimationColor(randomColor);
Debug.Log($"设置随机颜色: {randomColor}");
}
// S键改变缩放
if (Input.GetKeyDown(KeyCode.S))
{
float scale = Random.Range(0.5f, 2f);
framePlayer.SetCurrentAnimationScale(Vector3.one * scale);
Debug.Log($"设置缩放: {scale}");
}
}
/// <summary>
/// 高级用法示例 - 创建复杂的动画序列
/// </summary>
public void AdvancedUsageExample()
{
Debug.Log("=== 高级用法示例 ===");
// 创建一个复杂的动画序列
var complexAnim = new AnimationSequence();
complexAnim.name = "complex_animation";
complexAnim.frames = attackFrames;
complexAnim.framerate = 60f;
complexAnim.loop = false;
// 设置渲染属性
complexAnim.useGlobalRenderer = false;
complexAnim.targetSpriteRenderer = characterRenderer;
complexAnim.tintColor = Color.yellow;
complexAnim.useCustomScale = true;
complexAnim.customScale = new Vector3(2f, 2f, 1f);
complexAnim.overrideSortingOrder = true;
complexAnim.sortingOrder = 100;
// 设置曲线控制
complexAnim.useCurve = true;
complexAnim.curve = AnimationCurve.EaseInOut(0f, 0.5f, 1f, 2f); // 先慢后快
// 添加到播放器
framePlayer.AddAnimation(complexAnim);
// 播放这个复杂动画
framePlayer.PlayAnimation("complex_animation");
}
}