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 函數里對事件進行清空處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM