Why choose UnityEvent over native C# events?

21,829

Solution 1

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.

Solution 2

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.

Solution 3

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 thing in UI is, that you want the a OneShot handler for an event - 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

  1. play some animation,
  2. close the dialog and then
  3. 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 or UnityEvent<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 or Rx.Unity - and if reactive programming is a goal your team shared, it would probably be smart to do the same.

Share:
21,829
Adriano Di Giovanni
Author by

Adriano Di Giovanni

I’m a professional software consultant with 15+ years of experience in both mobile, web and desktop development. I have worked for startups, small companies, agencies and major clients such as Enel, Eni, Hyundai and Siemens. Currently, I develop and maintain the back-end infrastructure for an Italy-based online gaming firm. I’m focused on improving. People know me as a results-driven ever-growing person. My everyday skills are Javascript, Node.js, Objective-C, Swift, iOS, Java, Android, Cordova, MySQL, Redis, Ansible, Git, BDD, TDD, OSS. When I’m not on the job, I love to spend my time reading, working out, shooting my bow, climbing, playing guitar, singing, doing yoga, meditating.

Updated on November 19, 2021

Comments

  • Adriano Di Giovanni
    Adriano Di Giovanni over 2 years

    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?