'Why choose UnityEvent over native C# events?

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?



Solution 1:[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:[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:[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 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

  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 (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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 liyonghelpme
Solution 3