Delegates and events

Sometimes a developer needs to communicate two or more scripts in order to execute functions.

For example, if I want to change a cube’s color when OnTriggerEnter is called, the code could be some like this:

This code will work with every game object that has the Player1 script attached to it.
But let’s say the developer wants a Player2, Player3 and also an Enemy1 to change the color. He’d have to create 3 additional variables, and check if all of them in the OnTriggerEnter function.

Another situation could be that Player1 script is changed to NewPlayer1. The CubeTrigger code should be refactored to make it work.

In order to avoid these situations, we can use Delegates and Events


The definition found in Microsoft documentation (here) is:
“A delegate is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke (or call) the method through the delegate instance.”
public delegate void Calculate();
public delegate int Calculate1(int x, int y);

Delegates support single and multi casting, it is, a delegate variable can hold one or many methods that match its signature.


Microsoft documentation (here) says:
“Events enable a class or object to notify other classes or objects when something of interest occurs.
The class that sends (or raises) the event is called the publisher and the classes that receive (or handle) the event are called subscribers.”

Delegates and Events are part of the Observer pattern.

In Wikipedia we find this definition: “The observer pattern is a software design pattern in which an object, named the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

Using the example above, let’s make some changes.

Correction: unsubscribing in OnDisable():
OtherTranining.onLimitPassed -= ChangeColor
OtherTranining.onLimitPassed -= ChangeSize

Keep in mind:

  • The class who raises the event is CubeTrigger
  • The class who is listening to the event is Player1. When the event is raised, Player1 will execute ChangeColor
  • It is a good practice to check if the event is null before raising it.
  • Also, it is a good practice to subscribe and unsubscribe to the events, using commonly OnEnable and OnDisable

Now, everytime the cubeTrigger raises the OnLimitPassed event (that happens when OnTriggerEnter is executed), each listener (Player1 and Player2) will execute the respective function ( ChangeColor and ChangeSize).

Why is it so important?
Because now we can add as many listeners (Classes) as we want, and all of them will execute their own method when the event ( OnLimitPassed) is raised, it is, is called in OnTriggerEnter

From the coding point of view, it is called decoupling or loose coupling, it is, there is no inter-dependency between scripts. It’s a very important coding design pattern.

What is that?

It means that, for example, if I remove Player2 from the scene or the project, there won’t be any errors or refactoring issues, because the way listeners and subscribers communicate with each other is through events.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store