You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity脚本创建Sprite动画片段无法播放问题求助(附测试代码)

修复Legacy Animation播放问题

你的代码里有两个核心问题导致动画无法正常播放:

  • 关键帧时间计算错误:你直接把循环变量i设为关键帧的time,这会让每帧间隔1秒,和你设置的5fps帧率不匹配。正确的每帧时间应该是i / animClip.frameRate,这样动画总时长才是sprites.Length / 5秒,符合帧率设定。
  • 属性名错误:Unity序列化的Sprite属性内部名称是m_Sprite,不是你写的Sprite,这会导致动画无法找到要修改的属性。

另外,建议用AddClip把剪辑添加到Animation组件后再通过名称播放,比直接赋值anim.clip更可靠;按需设置wrapMode可以控制循环播放。

修复后的完整代码:

Sprite[] sprites;
    
void Start()
{
    AnimationClip animClip = new AnimationClip();
    Animation anim = GetComponent<Animation>();

    sprites = Resources.LoadAll<Sprite>("Sprite/punch2");
    Debug.Log(sprites.Length);
    animClip.frameRate = 5f;
    // 设置循环模式,按需选择Loop/Once等
    animClip.wrapMode = WrapMode.Loop;

    EditorCurveBinding spriteBinding = new EditorCurveBinding();
    spriteBinding.type = typeof(SpriteRenderer);
    spriteBinding.path = "";
    spriteBinding.propertyName = "m_Sprite"; // 修正属性名

    ObjectReferenceKeyframe[] spriteKeyFrames = new ObjectReferenceKeyframe[sprites.Length];
    for (int i = 0; i < sprites.Length; i++)
    {
        ObjectReferenceKeyframe orkf = new ObjectReferenceKeyframe
        {
            time = i / animClip.frameRate, // 修正时间计算
            value = sprites[i]
        };
        spriteKeyFrames[i] = orkf;
    }
    AnimationUtility.SetObjectReferenceCurve(animClip, spriteBinding, spriteKeyFrames);

    animClip.legacy = true;

    anim.AddClip(animClip, "PunchAnim"); // 添加剪辑到组件
    anim.Play("PunchAnim"); // 通过剪辑名播放
}

更推荐的Animator方案(现代Unity工作流)

Legacy Animation已经被逐步淘汰,用Animator组件实现更稳定,步骤如下:

  1. 给目标GameObject添加Animator组件;
  2. 用代码动态创建Animation Clip和Animator Controller,将动画状态添加到控制器中:
Sprite[] sprites;
    
void Start()
{
    sprites = Resources.LoadAll<Sprite>("Sprite/punch2");
    Debug.Log(sprites.Length);

    // 创建动画片段
    AnimationClip animClip = new AnimationClip();
    animClip.frameRate = 5f;
    animClip.wrapMode = WrapMode.Loop;

    EditorCurveBinding spriteBinding = new EditorCurveBinding();
    spriteBinding.type = typeof(SpriteRenderer);
    spriteBinding.path = "";
    spriteBinding.propertyName = "m_Sprite";

    ObjectReferenceKeyframe[] spriteKeyFrames = new ObjectReferenceKeyframe[sprites.Length];
    for (int i = 0; i < sprites.Length; i++)
    {
        spriteKeyFrames[i] = new ObjectReferenceKeyframe
        {
            time = i / animClip.frameRate,
            value = sprites[i]
        };
    }
    AnimationUtility.SetObjectReferenceCurve(animClip, spriteBinding, spriteKeyFrames);

    // 创建并赋值Animator Controller
    Animator animator = GetComponent<Animator>();
    AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath("Assets/TempPunchController.controller");
    animator.runtimeAnimatorController = controller;

    // 将动画添加到默认状态机
    AnimatorStateMachine stateMachine = controller.layers[0].stateMachine;
    AnimatorState punchState = stateMachine.AddState("PunchState");
    punchState.motion = animClip;

    // 控制器默认会播放第一个添加的状态,无需额外调用Play
}

这个方案不需要依赖Legacy组件,更符合Unity当前的动画生态,后续扩展状态切换也更方便。

内容的提问来源于stack exchange,提问作者Дима Шестаев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 07:16:09