Unity Events and Delegates Guide for beginners

Whenever you hear the term Unity events you also hear about Delegates, subscriptions and event listeners. For a beginner, this can be confusing and daunting. But Unity events are very handy and help reduce the coupling between the scripts inside your game if you understand and use them in the right way.

In this tutorial, we will see the following

In order to understand Unity Events, you need to understand Delegates first. So, we will start with Delegates.

Unity Events and Delegates banner.

What are Delegates?

Delegates are Method templates that can hold Methods or Functions that match the template format. Also, Delegates can be used to call the methods stored in them at any time.

To use a Delegate, you need to declare one, then you need to declare a variable of that Delegate. You can use that variable to save Methods that match the template of the Delegate.

Here is an Example Code

delegate void my_Delegate();                  //declaration of a Delegate
my_Delegate my_variable;                      //declaration of a Delegate variable

void Awake()
{
    my_variable=your_name;                  //passing the function your_name to Delegate.
}

void your_name()                                //function matching the Delegate Template
{
  Debug.Log("My name is VionixStudio");
}

void Start()
{
    my_variable();                                //calling the Delegate
}

When we call the Delegate, it will in turn call the function stored. In the above code, the Delegate will call the your_name function.

Things to note about Delegates

  1. Function assigned to a Delegate should match the template.
  2. When you assign the function no () is required.
  3. You can assign more than one function to a Delegate.
  4. It’s advised to check if the Delegate is not Null before calling it.

Null check a Delegate

As mentioned above its better to check if the Delegate is Null before calling it.

You can simply use an if statement to do that

if (my_variable != null)
            {
                my_variable();
            }

You can also simplify the if condition into a single line like this

my_variable?.Invoke();

Multicast a Delegate

You can add more than one function to a delegate and when you Invoke a Delegate it executes all the functions stored in it. The order of execution is not clearly mentioned anywhere so it’s better to use Coroutines rather than Delegates when you want the functions to be executed in an order.

delegate void my_Delegate();                  
my_Delegate my_variable;                      

void Awake()
{
    my_variable+=your_name; 
    my_variable+=another_func;                
}

void your_name()                               
{
  Debug.Log("My name is VionixStudio");
}


void another_func()
{
   Debug.Log("Just another Function");
}

void Start()
{
    my_variable();                               
}

The above code will execute both the functions when the delegate is triggered.

Remove a Function from a Delegate

You can also remove a function that is stored inside the Delegate using the “-=” operator. Also, if you just want to replace one existing function of a Single cast Delegate then you can just assign the new function name to it.

Replacing Function in Single cast Delegate

delegate void my_Delegate();                  
my_Delegate my_variable;                      

void Awake()
{
    my_variable=your_name; 
    my_variable=another_func;                     //the function your_name is replaced by another_func                
}

Removing a Function from a Multi cast Delegate

delegate void my_Delegate();                  
my_Delegate my_variable;                      

void Awake()
{
    my_variable+=your_name; 
    my_variable+=another_func             
}
void Start()
{
    my_variable-=your_name;             // the function your_name is removed from the delegate
}

When are Delegates useful?

Delegates can be used in the following cases

  1. When you need to call different function depending on the condition using the same call statement.
  2. Call Multiple function with a single line of code.

What are Events in C#?

Events are a type of delegates that can only have a void return type. Events have some restrictions on how to use them.

An event can be declared using an Event keyword and needs to be of type Delegate.

Here is a sample Event

delegate void my_Delegate();                  //declaration of a Delegate
event my_Delegate my_event;                 //declaration of an Event of type my_Delegate

Any event in C# is a multi-cast Delegate. So, it can be subscribed by multiple functions. But an event can near be triggered from outside its own class.

Subscribing and Unsubscribing to an event

Subscribing to an event is the same as assigning a function to a Delegate. You can use the “+=” to subscribe to an event and you can use the “-=” to unsubscribe to an event.

delegate void my_Delegate();                  
event my_Delegate my_event;

void Awake()
{
    my_event+=your_name; 
    my_event+=another_func;                
}

void your_name()                               
{
  Debug.Log("My name is VionixStudio");
}


void another_func()
{
   Debug.Log("Just another Function");
}

void Start()
{
    my_event();                               
}

If you want to subscribe to the event from another class then you need to specify the event variable as public static. Here is an example

public static event my_Delegate my_event;

Since the event variable is set as public static you can now subscribe to the event from any class using the event variables class name. Let’s say the event belongs to a class called “example” here is how you can subscribe to it.

example.my_event+=your_name; 

Unity Events

Unity has some in built events like Onclick, OnValue change which are used with Unity UI system. If you want to use them then you can do so with the help of an Inbuilt Delegate called UnityAction.

If you want to create a new custom event then you can use the Unity Events namespace to create your own Unity event variable and use them to subscribe to the custom event. There is no need to declare a Delegate.

If you are using events in Unity then you need to add the namespace “using UnityEngine.Events” and you have to use the AddListener function to subscribe to the event.

Let’s get into comparing both ways to using the Unity events.

Unity Event tutorial using Unity Actions

Add a new Toggle to your scene by going to Add>UI>Toggle in the Hierarchy window.

Create a new Gameobject called toggle_event_test

Add a script called event_test to the gameobejct and open it for editing.

Creating a Unity Action Delegate variable

Add the namespaces “using UnityEngine.Events” and “using UnityEngine.UI”.

Go to Unity editor and select the toggle. Go to inspector and scroll down to the On Value Changed event. You should be able to see that it takes a variable of type Boolean.

Go back to the code editor.

Let’s create a new Unity action variable of type UnityAction<bool> and call it my_action. Every UI element takes different parameter types. So, check it out in the Unity editor before creating a UnityAction variable.

We are going to subscribe to the OnValueChange event of the toggle UI. So, we need the Toggle UI. Let’s create a public variable of type toggle.

In the start Function let’s subscribe the function on_change() to the Unity action variable. Now let’s subscribe it to the OnvalueChange event using the Add listener function.

Here is the final code

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class event_test : MonoBehaviour
{
    UnityAction<bool> my_action;
    public Toggle tog;
    // Start is called before the first frame update
    void Start()
    {
        my_action+=On_change;
        tog.onValueChanged.AddListener(my_action);
        
    }

    // Update is called once per frame
    void On_change(bool state)
    {
        Debug.Log("value changed to "+state);
    }
}

Custom Unity Event tutorial without Delegates

Let’s create a custom event which is called when escape key is press and displays a message saying “Event happened” when the event occurs.

Using the Unity events without delegates has one drawback. The function used to subscribe to the event should have a return type of void and should not take any parameters.

Let’s get on with the tutorial.

In an empty scene add an empty Gameobject. Add a new script called event_test to the Gameobject.

Open the script for editing.

Add the namespace “using UnityEngine.Events”.

Create a new variable of type Unity Events, let’s call it my_event.

In the start function, subscribe to the event using the Add listener function.

In the Update function, check if the escape key is pressed and invoke our event.

Here is the Final code

using UnityEngine;
using UnityEngine.Events;


public class event_test : MonoBehaviour
{
    UnityEvent my_event=new UnityEvent();

    void Start()
    {
        my_event.AddListener(On_change);
    }
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Escape))
        {
            my_event.Invoke();
        }
    }
    void On_change()
    {
        Debug.Log("value changed to ");
    }
}

Custom Unity event using Delegates

This is similar to how we created an event in C#. You don’t need to use the namespace “using UnityEngine.Events” for this.

In this way of creating a Unity event you can have control on the Delegate template.

Let’s try to create the same scenario where the event is called when the escape key is pressed. Only difference is, in this case we will have the function return a bool and take a string as input.

Remove the unity event namespace from the above code.

Declare a Delegate with Bool return type and string as input.

Declare an Event variable.

In the start function subscribe to the event.

In the Update function check if the escape key is pressed and invoke the event.

Here is the Final code

using UnityEngine;


public class event_test : MonoBehaviour
{
    delegate bool my_delegate(string name);
    event my_delegate my_event;

    void Start()
    {
        my_event+=On_change;
    }
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Escape))
        {
            Debug.Log(my_event.Invoke("VionixStudio"));
        }
    }
    bool On_change(string my_name)
    {
        
        if(my_name=="VionixStudio")
        {
            return true;
        }
        return false;
        
    }
}

How to Unsubscribe or remove listener from Unity Events

The codes above do not include Null check and unsubscribing to the event. So, remember to add them when you use it in a game.

It’s better to Unsubscribe in the “OnDestory” or the “OnDisable” functions in Unity. If you added a listener then you can just add a remove listener function.

Here is how to do it

void OnDestroy()
 {

     my_event-=On_change;

     //if you have added a listener

     my_event.RemoveListener(On_change);
    
 }

So now you have learnt about Delegates, Events, Unity actions and Unity events.

If you have any other question regarding this then leave it in the comment box below.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

History of Game development. Is game development recession proof? Can you make a living with esports? Asset optimization techniques in Unity Why is Unity widely used than Unreal?