How to set AnimationEvent to not require receiver to prevent error

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.

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.

Sorry for necromancing the thread, but I have just ran into this problem, so I wrote some code which seems to work for me:

#if UNITY_EDITOR
using UnityEngine;
using System;
using UnityEditor;

public static class AnimationEventWindowCustomMenu{
    static void setAnimationWindowEventSendMessageOption(SendMessageOptions sendMessageOption){
        Type typeAnimationWindowEvent = Selection.activeObject.GetType();
        AnimationClip clip =
            (AnimationClip)typeAnimationWindowEvent.GetField("clip") //this field is public
            .GetValue(Selection.activeObject)
        ;
        AnimationEvent[] aAnimationEvent = AnimationUtility.GetAnimationEvents(clip);
        for(int i=0; i<Selection.objects.Length; ++i){
            int eventIndex =
                (int)typeAnimationWindowEvent.GetField("eventIndex").GetValue(Selection.objects[i]);
            aAnimationEvent[eventIndex].messageOptions = sendMessageOption;
        }
        AnimationUtility.SetAnimationEvents(clip,aAnimationEvent);
    }

    static SendMessageOptions getAnimationWindowEventSendMessageOption(){
        Type typeAnimationWindowEvent = Selection.activeObject.GetType();
        AnimationClip clip =
            (AnimationClip)typeAnimationWindowEvent.GetField("clip") //this field is public
            .GetValue(Selection.activeObject)
        ;
        int eventIndexActive =
            (int)typeAnimationWindowEvent.GetField("eventIndex").GetValue(Selection.activeObject);
        AnimationEvent[] aAnimationEvent = AnimationUtility.GetAnimationEvents(clip);
        return aAnimationEvent[eventIndexActive].messageOptions;
    }

    [MenuItem("CONTEXT/AnimationWindowEvent/Set Require Receiver")]
    static void animationWindowEventSetRequireReceiver(){
        setAnimationWindowEventSendMessageOption(SendMessageOptions.RequireReceiver);
    }

    [MenuItem("CONTEXT/AnimationWindowEvent/Set Require Receiver",true)]
    static bool animationWindowEventSetRequireReceiverValidate(){
        return getAnimationWindowEventSendMessageOption()!=SendMessageOptions.RequireReceiver;
    }

    [MenuItem("CONTEXT/AnimationWindowEvent/Clear Require Receiver")]
    static void animationWindowEventClearRequireReceiver(){
        setAnimationWindowEventSendMessageOption(SendMessageOptions.DontRequireReceiver);
    }

    [MenuItem("CONTEXT/AnimationWindowEvent/Clear Require Receiver",true)]
    static bool animationWindowEventClearRequireReceiverValidate(){
        return getAnimationWindowEventSendMessageOption()!=SendMessageOptions.DontRequireReceiver;
    }
}
#endif

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.

1 Like

I added this to my start Func:

private void Start()
    {
        List<AnimationEvent> lstEvent = new List<AnimationEvent>();
        Animator _anim = GetComponent<Animator>();
        foreach (AnimationClip ac in _anim.runtimeAnimatorController.animationClips)
        {
            // look at all the animation clips here!
            foreach (AnimationEvent ev in ac.events)
            {
                ev.messageOptions = SendMessageOptions.DontRequireReceiver;
                lstEvent.Add(ev);
            }
            ac.events = lstEvent.ToArray();
            lstEvent.Clear();
        }
    }
1 Like