Search Unity

How to Add Animation Events at runtime

Discussion in 'Animation' started by kylin9872, Jan 21, 2015.

  1. kylin9872

    kylin9872

    Joined:
    Nov 3, 2014
    Posts:
    4
    With MecAnim, how to add/remove animation event at runtime?
    can anyone give an example?
    THX a lot!!!
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
  3. kylin9872

    kylin9872

    Joined:
    Nov 3, 2014
    Posts:
    4
    Thank you!
    I tried add events with AnimationClip.events in Unity 5.0. Basically it works.
    But sometimes (not always), the editor would pop up "Fatal error" window and crash.
    the content of "Fatal error":
    CheckDisalowAllocation. Allocating memory when it is not allowed to allocate memory.

    How can I fix it?

    the code:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class _AAA : MonoBehaviour {
    5.  
    6.     private AnimationClip _aniclip;
    7.     private AnimationEvent[] _aEvents;
    8.     private Animator _myAnim;
    9.  
    10.  
    11.     // Use this for initialization
    12.     void Start () {
    13.         _myAnim = GetComponent<Animator> ();
    14.  
    15.         _aniclip = _myAnim.runtimeAnimatorController.animationClips[0];
    16.  
    17.         _aEvents = new AnimationEvent[3];
    18.         for (int i = 0; i < 3; i++){
    19.             _aEvents[i] = new AnimationEvent();
    20.             _aEvents[i].functionName = "aaa";
    21.             _aEvents[i].time = .1f * i;
    22.         }
    23. //        Debug.Log (_aniclip.events.IsReadOnly);
    24.         _aniclip.events = _aEvents;
    25.         Debug.Log (_aniclip.events.Length);
    26.  
    27.     }
    28.  
    29.     // Update is called once per frame
    30.     void Update () {
    31.  
    32.     }
    33.  
    34.     public void aaa(){
    35.         Debug.Log ("+++aaaaa+++++");
    36.     }
    37. }
    To do so, the events were added.
    the results:
    3
    +++aaaaa+++++
    +++aaaaa+++++
    +++aaaaa+++++


    Thank you.
     
    Last edited: Jan 22, 2015
  4. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    It probably something that you cannot fix from your script.

    Please log a bug with your project that repro this bug.
     
  5. canis

    canis

    Joined:
    Oct 25, 2013
    Posts:
    79
    Hi, I know this thread was old, and I'm using U3D2018,
    anyway here is my problem:

    how to addEvent to CORRECT animationClip when I was using StateMachineBehaviour (SMB) ??

    information :
    • My animator contain a set of animation, and some of them are attached SMB
    • SMB tried to add animation event during runtime. (I know I can add event in editor manually, just... please do it via script.)
    What I want to achieve is using SMB to add animation event on it's own clip (they are attached on same state)

    here is what I tried.
    my concept are using the AnimatorStateInfo[] to fetch all animation clip onStateEnter,
    however the return array will more then one clip if we are during transition.
    so my real question was how to identify the correct clip in this case ?
    or any work around to add animation event in this case ?

    Code (CSharp):
    1. public class ComboSMB : BaseSMB
    2.     {
    3.         [SerializeField] eComboType m_ComboType = eComboType.None;
    4.         public eComboType ComboType { get { return m_ComboType; } }
    5.         [SerializeField] bool m_NextComboRequest = true;
    6.         [SerializeField, Range(0f, 1f)] float m_NextComboTiming = 0.8f;
    7.         bool _NextComboRequestSent = false;
    8.  
    9.         [SerializeField] bool m_ClearComboRequest = false;
    10.         [SerializeField, Range(0f, 1f)] float m_ClearComboTiming = 0.9f;
    11.         bool _ClearComboRequestSent = false;
    12.  
    13.         bool m_EventAdded = false;
    14.  
    15.         public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex, AnimatorControllerPlayable controller)
    16.         {
    17.             base.OnStateEnter(animator, stateInfo, layerIndex, controller);
    18.             if (!m_EventAdded)
    19.                 InsertAnimationEvent(animator.GetCurrentAnimatorClipInfo(layerIndex));
    20.         }
    21.  
    22.         private void InsertAnimationEvent(AnimatorClipInfo[] infos)
    23.         {
    24.             // this function will only call once.
    25.             if (m_EventAdded)
    26.                 throw new System.InvalidProgramException();
    27.  
    28.             m_EventAdded = true;
    29.  
    30.             AnimationClip clip = infos[0].clip; // Hm..... here is the problem ?!
    31.             string funcName = CAvatar.AvatarAnimationEvent;
    32.  
    33.             if (m_NextComboRequest)
    34.             {
    35.                 float time2Trigger = m_NextComboTiming * clip.length;
    36.                 AnimationEvent nextComboRequestEvent = new AnimationEvent()
    37.                 {
    38.                     functionName = funcName,
    39.                     time = time2Trigger,
    40.                     stringParameter = ComboSystem.ComboRequest,
    41.                 };
    42.                 clip.AddEvent(nextComboRequestEvent);
    43.             }
    44.  
    45.             if (m_ClearComboRequest)
    46.             {
    47.                 float time2Trigger = m_ClearComboTiming * clip.length;
    48.                 AnimationEvent clearComboRequestEvent = new AnimationEvent()
    49.                 {
    50.                     functionName = funcName,
    51.                     time = time2Trigger,
    52.                     stringParameter = ComboSystem.ComboResetRequest,
    53.                 };
    54.                 clip.AddEvent(clearComboRequestEvent);
    55.             }
    56.         }
    57.     }
     
  6. tarnumius

    tarnumius

    Joined:
    Feb 16, 2018
    Posts:
    7
    May be, you need select clip from this array - GetComponent<Animator>().runtimeAnimatorController.animationClips?
     
  7. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    You should not use this exception type in your code. The invalid program exception means invalid or broken IL instructuions in your assembly, but it is not the case. If you want to use exceptions, you derive from the ApplicationException and throw those
     
    canis likes this.
  8. Spring_Heng

    Spring_Heng

    Joined:
    Aug 29, 2017
    Posts:
    1
    maybe could try it:
    AnimationEvent[] animationEvent = new AnimationEvent[0];
    AnimationUntility.SetAnimationEvents(clip,animationEvent);