文章目录
- 1.代码
- 2.使用方式
- 3.注意事项
1.代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;// 播放Animator并加入播放完成回调。
[RequireComponent(typeof(Animator))]
public class AnimatorCallback : MonoBehaviour
{private string startFunName = "StartCallBack";private string endFunName = "EndCallBack";private Animator mAnim;private AnimatorOverrideController mController;private Dictionary<string, AnimationClip> mClipDic = new Dictionary<string, AnimationClip>();private Action endCallBack; // 动画结束回调private Action startCallBack; // 动画开始回调private AnimationEvent endEvt; // 结束帧private AnimationEvent startEvt; // 结束帧public void Awake(){mController = new AnimatorOverrideController();mAnim = transform.GetComponent<Animator>();ResetEvent();mController.runtimeAnimatorController = mAnim.runtimeAnimatorController;}public void Play(string animName, Action beginAction = null, Action endAction = null){startCallBack = beginAction;endCallBack = endAction;if (!mClipDic.ContainsKey(animName)){mClipDic.Add(animName, mController[animName]);endEvt = new AnimationEvent();endEvt.time = mClipDic[animName].length;startEvt = new AnimationEvent();startEvt.time = 0;endEvt.functionName = endFunName;startEvt.functionName = startFunName;mClipDic[animName].AddEvent(endEvt);mClipDic[animName].AddEvent(startEvt);}if (!mAnim.enabled) mAnim.enabled = true;mAnim.Play(animName, 0, 0);}private void EndCallBack(){if (endCallBack != null)endCallBack.Invoke();}private void StartCallBack(){if (startCallBack != null)startCallBack.Invoke();}#region help// 主要是为了防止已用的动画帧事件被移除private void ResetEvent(){foreach (var clip in mAnim.runtimeAnimatorController.animationClips){List<AnimationEvent> evts = new List<AnimationEvent>();foreach (var curEvt in clip.events){var newEvt = new AnimationEvent();if (curEvt.functionName.Equals(startFunName) || curEvt.functionName.Equals(endFunName))continue;CloneEvent(newEvt, curEvt);evts.Add(newEvt);}clip.events = null;foreach (var evt in evts){clip.AddEvent(evt);}evts = null;}}private void CloneEvent(AnimationEvent newEvt, AnimationEvent oldEvt){newEvt.functionName = oldEvt.functionName;newEvt.floatParameter = oldEvt.floatParameter;newEvt.intParameter = oldEvt.intParameter;newEvt.objectReferenceParameter = oldEvt.objectReferenceParameter;newEvt.time = oldEvt.time;}#endregion
}
2.使用方式
- 在需要调用事件的Animator物体上添加上面的脚本
- 调用Play方法
3.注意事项
如果你将Animator的某个AnimationClip的Speed设置为了-1(即倒播),动画的开始播放事件和结束播放事件任然是对应的开始帧和结束帧。