Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to set AnimationEvent to not require receiver to prevent error

Discussion in 'Animation' started by bluilisht, Jan 8, 2021.

  1. bluilisht

    bluilisht

    Joined:
    Dec 6, 2016
    Posts:
    9
    I want to use several animation clips on different object. They have animation event but not all object have the required function.
    So how do I make the animation event to not give me error when there's no receiver?

    There's messageOptions property on Animation Event but I can't find the setting on Animation Window or the Animation Event inspector.
     
    Last edited: Jan 8, 2021
  2. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,555
    I don't think it's possible. Animator.fireEvents could disable all events for an object, but otherwise you just need to make a dummy script with empty functions to receive the events you don't want.
     
  3. reevthechameleon

    reevthechameleon

    Joined:
    Dec 22, 2020
    Posts:
    3
    Sorry for necromancing the thread, but I have just ran into this problem, so I wrote some code which seems to work for me:
    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using UnityEngine;
    3. using System;
    4. using UnityEditor;
    5.  
    6. public static class AnimationEventWindowCustomMenu{
    7.     static void setAnimationWindowEventSendMessageOption(SendMessageOptions sendMessageOption){
    8.         Type typeAnimationWindowEvent = Selection.activeObject.GetType();
    9.         AnimationClip clip =
    10.             (AnimationClip)typeAnimationWindowEvent.GetField("clip") //this field is public
    11.             .GetValue(Selection.activeObject)
    12.         ;
    13.         AnimationEvent[] aAnimationEvent = AnimationUtility.GetAnimationEvents(clip);
    14.         for(int i=0; i<Selection.objects.Length; ++i){
    15.             int eventIndex =
    16.                 (int)typeAnimationWindowEvent.GetField("eventIndex").GetValue(Selection.objects[i]);
    17.             aAnimationEvent[eventIndex].messageOptions = sendMessageOption;
    18.         }
    19.         AnimationUtility.SetAnimationEvents(clip,aAnimationEvent);
    20.     }
    21.  
    22.     static SendMessageOptions getAnimationWindowEventSendMessageOption(){
    23.         Type typeAnimationWindowEvent = Selection.activeObject.GetType();
    24.         AnimationClip clip =
    25.             (AnimationClip)typeAnimationWindowEvent.GetField("clip") //this field is public
    26.             .GetValue(Selection.activeObject)
    27.         ;
    28.         int eventIndexActive =
    29.             (int)typeAnimationWindowEvent.GetField("eventIndex").GetValue(Selection.activeObject);
    30.         AnimationEvent[] aAnimationEvent = AnimationUtility.GetAnimationEvents(clip);
    31.         return aAnimationEvent[eventIndexActive].messageOptions;
    32.     }
    33.  
    34.     [MenuItem("CONTEXT/AnimationWindowEvent/Set Require Receiver")]
    35.     static void animationWindowEventSetRequireReceiver(){
    36.         setAnimationWindowEventSendMessageOption(SendMessageOptions.RequireReceiver);
    37.     }
    38.  
    39.     [MenuItem("CONTEXT/AnimationWindowEvent/Set Require Receiver",true)]
    40.     static bool animationWindowEventSetRequireReceiverValidate(){
    41.         return getAnimationWindowEventSendMessageOption()!=SendMessageOptions.RequireReceiver;
    42.     }
    43.  
    44.     [MenuItem("CONTEXT/AnimationWindowEvent/Clear Require Receiver")]
    45.     static void animationWindowEventClearRequireReceiver(){
    46.         setAnimationWindowEventSendMessageOption(SendMessageOptions.DontRequireReceiver);
    47.     }
    48.  
    49.     [MenuItem("CONTEXT/AnimationWindowEvent/Clear Require Receiver",true)]
    50.     static bool animationWindowEventClearRequireReceiverValidate(){
    51.         return getAnimationWindowEventSendMessageOption()!=SendMessageOptions.DontRequireReceiver;
    52.     }
    53. }
    54. #endif
    55.  
    Add this piece of code to the project (preferably in the folder named "Editor"). This code adds context menu to AnimationEvent Inspector, so you can right-click on it and choose to set/clear MessageOptions for each AnimationEvent. It uses reflection, so it may not work if something changes in future version, but at least it works on my 2020.3.30f version.
    As for AnimationEvent that comes attached with the model, I have no idea how to set that, except perhaps by opening the .meta file to change values in it manually.
     
    Yuchen_Chang likes this.
  4. Daniel_leal_lima

    Daniel_leal_lima

    Joined:
    Nov 8, 2020
    Posts:
    2
    I added this to my start Func:
    Code (CSharp):
    1. private void Start()
    2.     {
    3.         List<AnimationEvent> lstEvent = new List<AnimationEvent>();
    4.         Animator _anim = GetComponent<Animator>();
    5.         foreach (AnimationClip ac in _anim.runtimeAnimatorController.animationClips)
    6.         {
    7.             // look at all the animation clips here!
    8.             foreach (AnimationEvent ev in ac.events)
    9.             {
    10.                 ev.messageOptions = SendMessageOptions.DontRequireReceiver;
    11.                 lstEvent.Add(ev);
    12.             }
    13.             ac.events = lstEvent.ToArray();
    14.             lstEvent.Clear();
    15.         }
    16.     }