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组件实现更稳定,步骤如下:
- 给目标GameObject添加Animator组件;
- 用代码动态创建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,提问作者Дима Шестаев
相关产品推荐
相关产品推荐

