- Home /
How to add a persistent method with a single argument to a UnityEvent?
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.
Answer by Bunny83 · Oct 22, 2016 at 09:35 PM
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.
ps. I'm not sure what SetActive you try to use here. If you have access to the actual class, there's no need for reflection. For example if you want to bind GameObject.SetActive
you can simply do:
UnityEngine.Events.UnityAction<bool> action = gameObject.SetActive;
Note that we assign "the method" itself so don't use the execution brackets "()" behind the method name.
Good to know - and no, this is not about that specific function - but this unfortunately still doesn't solve the problem!
I can't use UnityAction < T1 > because that would give me a compile error on the AddPersistentListener() method: it takes (UnityEvent, UnityAction) or (UnityEvent < T1 >, UnityAction < T1 >) as arguments, not (UnityEvent < T1 >, UnityAction). This is where all my problems come from.
(Sorry - had to heavily edit my previous comment as the markup removed all my < T1 > things from the text for no good reason...)
I've edited my answer. I think i finally understood what you want to do ^^.
This was really a useful bit of information, @Bunny83 thank you!
Your answer
Follow this Question
Related Questions
What is Unityevent and how do they relate to Unityaction? 1 Answer
How to unsubscribe from a delegate that is inside of a singleton? 2 Answers
Subscribers of Delegates? 2 Answers
Score Workflow 1 Answer