之前一直都是手动给模型动画添加事件,最近在做项目的时候,感觉很麻烦,而且经常要改,就变的更麻烦了。于是就在网上查了下,事件是可以在运行时自动添加的,在此记录一下,免得自己以后忘了。
现在有一个模型和动画控制器如下:
很简单,没有什么骚操作。并在模型上挂了一个 Test 脚本,我在 Test 脚本里,分别在动画的开始,结束,和播放一半的时候添加事件。运行打印如下:
截图没办法很好的表示动态效果,大家可以自己尝试一下,代码如下,逻辑很简单,就不多说了:
1 using UnityEngine; 2 3 public class Test : MonoBehaviour 4 { 5 #region --变量定义 6 private Animator animator; 7 private AnimationClip[] clips; 8 #endregion 9 10 #region --系统函数 11 private void Start() 12 { 13 animator = this.GetComponent<Animator>(); 14 clips = animator.runtimeAnimatorController.animationClips; 15 16 AnimationClip _clip = clips[0]; 17 AddAnimationEvent(animator, _clip.name, "StartEvent", 0); 18 AddAnimationEvent(animator, _clip.name, "HalfEvent", _clip.length * 0.5f); 19 AddAnimationEvent(animator, _clip.name, "EndEvent", _clip.length); 20 } 21 private void OnDestroy() 22 { 23 CleanAllEvent(); 24 } 25 #endregion 26 27 #region --自定义函数 28 private void StartEvent() 29 { 30 Debug.Log("开始播放动画"); 31 } 32 private void HalfEvent() 33 { 34 Debug.Log("动画播放了一半"); 35 } 36 private void EndEvent() 37 { 38 Debug.Log("播放动画完毕"); 39 } 40 41 /// <summary> 42 /// 添加动画事件 43 /// </summary> 44 /// <param name="_animator"></param> 45 /// <param name="_clipName">动画名称</param> 46 /// <param name="_eventFunctionName">事件方法名称</param> 47 /// <param name="_time">添加事件时间。单位:秒</param> 48 private void AddAnimationEvent(Animator _animator, string _clipName, string _eventFunctionName, float _time) 49 { 50 AnimationClip[] _clips = _animator.runtimeAnimatorController.animationClips; 51 for (int i = 0; i < _clips.Length; i++) 52 { 53 if (_clips[i].name == _clipName) 54 { 55 AnimationEvent _event = new AnimationEvent(); 56 _event.functionName = _eventFunctionName; 57 _event.time = _time; 58 _clips[i].AddEvent(_event); 59 break; 60 } 61 } 62 _animator.Rebind(); 63 } 64 /// <summary> 65 /// 清除所有事件 66 /// </summary> 67 private void CleanAllEvent() 68 { 69 for (int i = 0; i < clips.Length; i++) 70 { 71 clips[i].events = default(AnimationEvent[]); 72 } 73 Debug.Log("清除所有事件"); 74 } 75 #endregion 76 }
有一点需要注意,事件添加过一次后,就会一直存在,除非关闭程序。也就是说,如果你实例化一个模型,并且在 Start 函数里执行添加 事件的逻辑,如果这个模型被实例化了两次,事件就会被添加两次。所以我建议大家像我这样,在 OnDestroy 函数里对事件进行清空处理。