之前一直都是手動給模型動畫添加事件,最近在做項目的時候,感覺很麻煩,而且經常要改,就變的更麻煩了。於是就在網上查了下,事件是可以在運行時自動添加的,在此記錄一下,免得自己以后忘了。
現在有一個模型和動畫控制器如下:
很簡單,沒有什么騷操作。並在模型上掛了一個 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 函數里對事件進行清空處理。