Delegates And Events In Unity – What Are They And How To Use Them

Table of Contents

Delegates And Events In Unity – What Are They And How To Use Them

Reading Time: 7 minutes
Level: Beginner – Intermediate – Advanced
Version: Unity 2020.3.1 LTS

Help Others Learn Game Development

Share on facebook
Share on twitter
Share on reddit
Share on linkedin

Delegation is a powerful concept that is used as a way to notify other classes when something happens.

You can think of delegates as reference type variables used to hold the references of methods that have the same signature as the declared delegate.

When the delegate is called, it will notify all the methods which are being referenced by that delegate.

Before we dive deeper in the concept of delegation, I want to mention that this tutorial is suited for beginners, intermediate and advanced Unity users.

However, if you are a beginner, I expect you to know your way around Unity.

I expect that you know how to create a new project, how to create a class, how to attach a class to a game object, I expect you to know the basics of programming with C# in Unity, how to print to the Unity console and other basic beginner stuff.

If you don’t know these things, then you should check out my C# tutorial series starting with variables.

After that go through my Rainy Knifes tutorial.

How Do We Declare Delegates And Events

For starters, I’ve created a new Unity project and inside I created two scripts. One is called Sender, the other is called Receiver.

Create an empty game object in the Hierarchy tab, name it however you want, and attach the Sender and Receiver scripts on it.

Make sure that you do these steps before you proceed with the tutorial.

Going back at the task at hand, how do we declare a delegate and how do we declare an event?

Inside the Sender script, write the following line:

				
					public delegate void PlayerDied();
				
			

The keyword delegate denotes that this is a delegate. The name of this delegate is PlayerDied, you can, of course, name the delegate however you want, and the name will be meaningful e.g. it will reflect what the delegate’s purpose is, and the same naming conventions that apply for functions apply for delegates as well.

You will also notice that we have the keyword void in the delegate’s declaration. This is because the delegate can return a value, or it can be void and not return anything, we will see examples for both cases.

Next we declare an event for the delegate:

				
					public delegate void PlayerDied();
    public static event PlayerDied playerDiedInfo;
				
			
The event is the one who actually informs the subscribers to that event that something has happened.
 
So essentially, we subscribe to the event, and when we want to inform all subscribers to that event that something has happened, we call the event.
 

What Is The Difference Between The Delegate And The Event

To explain in more depth how delegates and events work, I am going to use a metaphor.
 
Let’s say you have a newspaper company, and people can subscribe to your company to receive new newspapers whenever you publish them.
 
You can think of the delegate as the newspaper company, and the event is where people can subscribe to your newspaper company.
 
Whenever a new edition comes out, the event will inform all the people who have subscribed for the newspaper, that a new edition is out and we will send it to them.
 
But how does that work in a real world example?
 

Subscribing To Events

Using the example above, I am going to create a new delegate and event inside the Sender script:
 
				
					public delegate void NewspaperCompany();
    public static event NewspaperCompany newspaperSubscription;
				
			
Now that we have the delegate and the event in place, how do we subscribe to the event?
 
First we need to create a function that has the same signature as the declared delegate.
 
What does that mean?

Well, we see that the delegate is declared as void, which means it doesn’t return a value, the function we wish to subscribe to the event also needs to be void.
 
We also see that the delegate doesn’t take any parameters, the function we wish to subscribe to the event also needs to be without parameters.
 
So inside the Receiver script, declare the following function:
 
				
					void NewspaperReceiver()
    {
    }
				
			

The NewspaperReceiver has the same signature as the NewpaperCompany delegate and this is the function that we will use to subscribe to the event.

To subscribe to the event, we need to write the following line of code:

				
					Sender.newspaperSubscription += NewspaperReceiver;
				
			
Using the += we subscribe to the event by providing the function we wish to subscribe.
 
Since the newspaperSubscription variable is a static variable, we can call it by using the Sender class name.
 
If you don’t know what are static variables you can learn about them by clicking here.
 
Now we can put this line of code inside the Start function, but the best place to subscribe to the event is inside the OnEnable function:
 
				
					private void OnEnable()
    {
        Sender.newspaperSubscription += NewspaperReceiver;
    }
				
			
The reason for that is, when we subscribe to the event, that object will be registered in computer memory.
 
It can happen, that the game object who holds the script where we subscribed to the event gets destroyed.
 
Then the subscribed object will still stay in memory even though it is destroyed.
 
Because of that, we can also unsubscribe from the event using -= and we do that inside the OnDisable function:
 
				
					 private void OnDisable()
    {
        Sender.newspaperSubscription -= NewspaperReceiver;
    }
				
			
OnEnable and OnDisable are best suited for this job because OnEnable will be called every time a game object is created or it gets activated after it was deactivated.
 
And OnDisable will be called every time a game object gets deactivated after it was active, and when the game object gets destroyed and removed from the game completely.
 
This way we don’t risk of leaving any objects inside the computer memory that we can’t access.
 

Calling The Event And Informing Subscribers

Now that we subscribed to the event, let us see how can we call it.

First I am going to add a line of code in the NewspaperReceiver that will print to the console so that we know when it executes:

				
					void NewspaperReceiver()
    {
        Debug.Log("Function called by the event");
    }
				
			

Going back inside the Sender script, this is how we call the event:

				
					void Start()
    {
        if (newspaperSubscription != null)
        {
            newspaperSubscription();
        }
    }
				
			

On line 5 you will notice that we call the event like a function, but before we do that we need to test if the event is not null.

The event will be null only when there are no functions in any class that are subscribed to it, in our case the event is not null because we subscribed the NewspaperReceiver function to it.

If you call an event that has no subscribers to it, you will see a null reference exception warning in the console, that’s why we first perform a test, like we did on line 3 to check if the event is not null.

When we call the event, it will inform all functions that are subscribed to it, and yes, you can subscribe multiple functions to the same event, no matter if there are 2, 10, or 100 functions subscribed to that event, all those functions will be called.

Now let’s run the game and see what will happen:

When the event was called, it informed the subscribed function about it, in our case the NewspaperReceiver function, and the function executed the code that we put inside it which is the Debug.Log that printed to the console.
 

What Is The Purpose Of Delegates And Events And When Should I Use Them In My Game

Often when I explain a concept I get asked where can I use it.
 
When it comes to programming there is no general rule where you can use something. The more you practice and the better programmer you become, your mind will become better and better at solving computer problems and then you will be able to figure out should you use events to fix a specific problem or not.
 
But at the top of my head to give a few examples how you can use delegates and events in Unity, you can use events to spawn enemies in your game when the player reaches a certain point in the game.
 
You can use events to open doors in the game when the player solves a puzzle or triggers a collider.
 
When you pick up a certain item in your game you can trigger an event that will give the player an upgrade and so on.
 
As I already mentioned above, the more you practice, the more games you create and the better you become at game development, you will figure out how to use delegates and events to solve problems in your games.
 

Passing Parameters With Events

I already said that the delegates can take parameters, so let’s modify our delegate and event to take a parameter:

				
					public delegate void NewspaperCompany(string msg);
    public static event NewspaperCompany newspaperSubscription;
				
			

Now that the delegate takes a parameter, we need to modify our function that we will use to subscribe to the event so that it has the same signature as the delegate:

				
					void NewspaperReceiver(string msgFromEvent)
    {
        Debug.Log(msgFromEvent);
    }
				
			

The way we subscribe to the event will stay the same:

				
					private void OnEnable()
    {
        Sender.newspaperSubscription += NewspaperReceiver;
    }

    private void OnDisable()
    {
        Sender.newspaperSubscription -= NewspaperReceiver;
    }
				
			

When we call the event now, we will provide the required parameter that will be passed further to the function or functions that are subscribed to that event:

				
					void Start()
    {
        if (newspaperSubscription != null)
        {
            newspaperSubscription("Printing the parameter from the delegate");
        }
    }
				
			

When we run the game this is what we will see:

Now we see that what we passed as a parameter from the event to the function, is printed in the console.

Of course, delegates are not limited to one parameter and type of the variable that you can use as a parameter. You can have as many parameters as you want and they can be different types of variables depending on your needs.

Returning Values With Events

We can also return values using events and delegates. For that we need to modify our delegate and event:
 
				
					public delegate int NewspaperCompany(int a, int b);
    public static event NewspaperCompany newspaperSubscription;
				
			
Now we need to modify the function to have the same signature as the delegate:
 
				
					int NewspaperReceiver(int a, int b)
    {
        return a + b;
    }
				
			
Subscribing to the event will stay the same:
 
				
					private void OnEnable()
    {
        Sender.newspaperSubscription += NewspaperReceiver;
    }

    private void OnDisable()
    {
        Sender.newspaperSubscription -= NewspaperReceiver;
    }
				
			

When we call the event to inform the subscribed function, we can store the returned value in a variable:

				
					void Start()
    {
        if (newspaperSubscription != null)
        {
            int sum = newspaperSubscription(2, 3);
            Debug.Log("The sum of a and b is: " + sum);
        }
    }
				
			

When we run the game we will see the sum of a and b printed in the console:

Because the function will calculate the sum of a and b parameters, and return it, we can store the sum in a variable, which we did and we saw the result in the console.
 

Leave a Comment