NRE的编程笔记

导航

Unity动画系统Animator动态添加事件

之前一直都是手动给模型动画添加事件,最近在做项目的时候,感觉很麻烦,而且经常要改,就变的更麻烦了。于是就在网上查了下,事件是可以在运行时自动添加的,在此记录一下,免得自己以后忘了。

现在有一个模型和动画控制器如下:

很简单,没有什么骚操作。并在模型上挂了一个 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 函数里对事件进行清空处理。

posted on 2019-05-12 19:15  NRE  阅读(12146)  评论(0编辑  收藏  举报