I mean, UnityEvents are slower than the native C# events and they still store a strong reference to the receivers. So, the only valid reason I can find to use UnityEvents over native C# events is their integration with the editor. Am I overlooking something?
-
Actually UnityEvent is a a misleading name as there is no real event in there, just a collection of Action. Note that there is no way to invoke a UnityEvent like a real event, you use Invoke. – Everts Jun 24 '17 at 10:04
-
2@Everts I don't understand how the term 'real' helps to understand the question. Also, I do not understand what you are saying: You invoke UnityEvent by using the invoke method. From what I understand, under the hood, native c# events are also a collection of Actions, they are just a native c# language construct that hides that list. – IARI Oct 13 '21 at 15:41
3 Answers
Am I overlooking something?
Nope, you are not overlooking anything. The only advantage and reason to use UnityEvent
is that it allows you to use events in the Editor. That's for drag and drop people or those making Editor plugins.
Another advantage of UnityEvent
is that it prevents the problem of Unity Object not being freed due to the misuse of delegates or using anonymous delegates with Unity Objects. Although they get freed when the main script that's holding them is destroyed. The reason for this is because UnityEvent
is implemented with weak references therefore removing/minimizing this problem. These two things are still not worth it to use UnityEvent
over native C# events.
You should always use native event and delegate over UnityEvent if you are not making an Editor plugin because of its fast performance and small memory usage. See this and this post post for more information.

- 121,791
- 22
- 236
- 328
-
-
Nope. Just use the normal C# event. I won't risk using anything that would prevent Unity from cleaning up their Objects such as `Texture2D`. – Programmer Jun 24 '17 at 09:02
-
Why WeakEventManager would prevent Unity from cleaning up objects? References are weak. – Adriano Di Giovanni Jun 24 '17 at 09:05
-
Bad phrasing. I don't know if it would and have not done test on this. Using some certain features in C# will prevent Unity from freeing their Objects. This includes misusing delegates or using anonymous delegates with Unity Objects. I think you should run a test and verify that nothing goes wrong with `WeakEventManager` before using it in a full game. Re-read my answer. I added one for point for `UnityEvent`. – Programmer Jun 24 '17 at 09:33
-
Jackson's blog post (the second link) was a thorough analysis on the topic. – gdbj Jun 24 '18 at 16:48
-
I had a frequent anonymous delegate problem. Everytime the monoscript is destroyed, ,the methods that are binded still get called. Should I use UnityEvent? – Zony Zhao Apr 18 '22 at 00:42
UnityEvent is mainly used with Unity UI system, because ugui need to serialize callbacks configuration in ui system, such as the button's OnClick callback.
Serialization is a most important feature in unity game engine, with c# builtin event system, you can't do serialize.
So if you work with unity UI System, you must use the UnityEvent, if you want to serialize callback function configuration, you must use the UnityEvent.
In other situation, just use the c# builtin event.

- 67
- 1
- 5
There is an advantage of UnityEvents over native c# events
with respect to software-design which has not yet been discussed:
Native events are no 'first class objects in c#.
- You cannot reference an event
- You cannot write Extension Methods on Events
- You cannot invoke events 'from the outside'
The Last restriction is actually a design feature - If you find yourself in a situation where you want to do that, probably your software architecture is messed up.
(For instance, I'm working on a code-base that has an 'EventManager' which is just a class that just hosts several events, which are Triggered from other components - that's a bad idea - but this is far beyond the scope of this Post.)
So no complaints, nothing wrong with c# events here.
However, I have recently encountered the other points as a Problem multiple times. For example, a common requirement in UI is, that an event handler is triggered only once - i.e. you want to register a handler to an event, that automatically removes itsself after the event has fired a single time. For example assume, you have a Button in a modal dialog that is supposed to
- play some animation,
- close the dialog and then
- start some other sequence or game logic. Maybe you want to register the click handler when the dialog opens, like
Button.onClick.AddListener(OnButtonClicked);
However, if the user decides to press the button again during the 1. animation, you want to prevent the click handler from executing again. If that's a one time thing, you'll get away with just removing the handler form the click event within the handler.
Button.onClick.RemoveListener(OnButtonClicked);
We hundreds of cases like this that also differ a lot in our code-base. Far enough, that I really actually want to be able to instead just write:
Button.onClick.OneShot(OnButtonClicked);
Implementating an extension method for this - and other similar nice things - is
- possible with an Object like
UnityEvent
orUnityEvent<T>
, but - impossible with native C# Events.
We have added several Extension Methods to all Unity Events in order to move our existing code base towards a more reactive style. Having that said it has to be noted that UnityEvent isn't the optimal solution for several reasons that would be far beyong the topic of this SO post. Still let me mention that we consider libraries like UniRx (seems abandoned though) or Rx.Unity - and if reactive programming is a goal your team shared, it would probably be smart to do the same.

- 1,217
- 1
- 18
- 35
-
Could you elaborate on why this is impossible for C# events? Couldn't you just call `Button.onClick -= OnButtonClicked`? – lufinkey Feb 25 '22 at 15:53
-
1@lufinkey I said Implementating an extension method for this is impossible. This is impossible, because in c# you can not write an extension method for events. You also can not write a method that receives an event as a parameter - Events simply can not be passed by reference. If there is still an open question to why this is an issue, feel free to reach out. – IARI Feb 28 '22 at 10:19
-
1To anyone reading, it is important to mention that UniRx is no longer maintained. Current repo has 180+ open issues. – fafase Mar 13 '22 at 19:52
-
@fafase thx for pointing that out, I added an according comment the answer. – IARI Mar 17 '22 at 20:03