As I’ve been getting up to speed on 4.6 I’ve noticed the new event system and specifically the UnityAction delegates. I also know that .NET has had built-in delegates called Actions that seem to be almost exactly the same and I’ve been using them in Unity for some time now:
The only difference I’ve been able to see so far is that UnityAction is limited to 4 parameters, whereas .NET’s Action goes up to 16.
Is there a reason to use UnityAction over .NET’s built-in Action?
No particular reason, other than if you’re working with the unity events system. Even though they’re shaped the same, you can’t coerce a delegate created as an Action into a UnityAction, or vice versa…
Really the main bit about UnityEvent and UnityAction that is useful is that they are searlized by the unity inspector, and you can assign the object and method to notify via drag and drop on the inspector.
That’s my understanding. Useful for telling a game object what to do, in the Inspector, instead of subclassing, or getting a reference to a scriptable object. It’s clean, unless the delegate needs to change.
Ya I use a mix of both, based on what I need at a time. I will use the built in C# ones if I just want to subscribe and tell it what method to use in code. Than I will use UnityEvent if I want to pass this information in via the inspector.
It’s worth mentioning here that even if you use System.Action you’re still limited to 4 parameters, cause you’re not using .NET’s Action, but Unity Mono’s
A thing to look out for when using Unity’s delegates, is that if you add a listener (via code) in-editor (i.e. in edit time), for some reason it doesn’t get added, it could be that I’m missing something, or a bug. Here’s a video. I made a thread about it in the past, no response. I ended up just using my custom delegates
That’s not true. Delegates can be namespace-level, so you can copy and paste from the MSDN until Unity gets with the program.
namespace System {
public delegate void Action<in T1, in T2, in T3, in T4, in T5>(
T1 arg1,
T2 arg2,
T3 arg3,
T4 arg4,
T5 arg5
);
}
I don’t actually recommend this. You should use structs instead, until Microsoft also gets with the program and introduces tuples with named parameters like in Swift.
I’ve noticed something similar. When I first started playing with the event system I tried adding a listener via code (at runtime) and then looking in the inspector to see if it showed anything, but it doesn’t. After digging a little more, the conclusion I came to was that there are actually two types of listeners, regular listeners and persistent listeners. Both of them get called when the event triggers, but under the hood, they’re different.
Regular listeners are added via the AddListener call in code. They add a simple zero-parameter delegate (UnityAction) callback. They are not serialized. They cannot be accessed via the inspector (even the debug inspector).
Persistent listeners are added via the inspector. They specify the GameObject, the method, and the parameters to be sent to that method. They are serialized. They cannot be accessed via code.
I originally wanted access to the persistent listener interface in code so that I could send some parameters along rather than being forced into calling a zero-parameter method… but I ended up using a lambda expression instead which actually works nicely without getting too messy. So, if I wanted to add a listener to the onClick of a Button that would call a ButtonPressed method with the int ID of that button, then I do this:
Something I think is relevant when considering what event system to use, is builds stripping levels.
From a mono compatibility standpoint, would be better to use UnityEngine.Events over System.Action, given that in some mscorlib profiles the later is not inluded (“micro” .net profile).
Not to hijack the thread (I came here wondering about .NET Action / UnityAction differences too) but:
I’ve been wondering about this ever since I saw a link to the stripping list a few weeks ago. Does it make any sense to use Unity on any of the limited hardware targeted by the .NET micro framework? Are any of these CPUs even targeted by Unity?
I’ve done a fair bit of duino work (and we even own two or three of the cool but poorly-supported Netdunios) and it would have never occurred to me to burn storage, RAM, or clocks on Unity-level overhead.
Since it turns out that event AddListener only accepts UnityAction refs, it’s sort of a moot question in my case (I prefer to standardize on just one or the other in a project).