I have a UnityEvent delegate that in the inspector I can fill with zero and single-argument methods. I’m trying to do the same in code:
UnityEngine.Events.UnityAction action = System.Delegate.CreateDelegate(typeof(UnityEngine.Events.UnityAction), false, this.GetType().GetMethod("SetActive")) as UnityEngine.Events.UnityAction;
UnityEditor.Events.UnityEventTools.AddPersistentListener(script.unityEventDelegate, action);
…but I’m getting a ‘ArgumentException: method argument length mismatch’ error because UnityEvent itself is a delegate for a method without arguments? So… how can I add single-argument methods in the inspector, and can’t add them through code? What am I missing here?
FYI: I can’t force the delegate on the script to take UnityEvent methods only.
There are several things wrong here. First of all “UnityAction” is a delegate without any parameters. You would need to use UnityAction<bool>
as delegate type.
Second “SetActive” is an instance method but you don’t pass the object reference as second parameter but “false”. CreateDelegate has many overloads so make sure you read the documentation carefully.
Note that “UnityEvent” is a special Unity class that represents a serializable delegate while “UnityAction” is an actual delegate type. UnityAction has no parameters. There are several generic variants which allows you to specify one or more argument types.
edit
Well, your question is lacking some information how you actually declared your event and how you want to invoke it. There are generally two ways how a UnityEvent can be used. The non-generic UnityEvent class doesn’t allow passing any parameters when it’s invoked. That’s why you usually can’t add a listener that requires a parameter. However the UnityEvent class can wrap a delegate that requires a parameter in a special class that saves a certain parameter along with the delegate. It then provides a method without parameter which in turn calls the delegate with the stored parameter. For this you have to use:
UnityEditor.Events.UnityEventTools.AddBoolPersistentListener().
It requires the UnityEvent, a UnityAction<bool>
and the actual boolean value that should be passed to the method.
When adding such a delegate in the inspector, Unity let you enter the required parameter in an edit field.