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 very confusing. But Unity events are very handy and can help reduce the link between the scripts inside your game, if you understand and use them in the right way.

In this tutorial, we will see what are events and delegates, and how to use them effectively.

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

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 a delegate, and 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.

Let’s demonstrate, how to use a delegate with a simple 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 and log the statement “My name is VionixStudio”.

Things to note about Delegates

  1. Function assigned to a delegate should match the delegate’s format.
  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.

When you use the ‘=’ operator to assign the function, the delegate is overwritten with the new function. In order to add multiple function to the delegate we need to use the ‘+=’ operator.

Here is a code sample to use delegates to execute multiple functions.

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 simply replace the existing function by assigning a new function to the delegate.

The below code demonstrates how to replace a function inside the 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                
}

You can also remove a function that is stored inside a multicast delegate using the ‘-=’ operator. Here is a code example for that

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.
  3. Delegates enable game developers to create customizable systems. By exposing certain delegates in the game’s code, developers can easily add or modify functionality without changing the core game’s code.
  4. Delegates are majorly used to create event system.

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 never 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 variable and 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, there are two ways to do it.

  1. You need to use the namespace using UnityEngine.Events and you have to use the AddListener function to subscribe to the event.
  2. Second method is using, C# delegates and events.

We will see how to use all these methods in the examples below.

Unity Event tutorial using Unity Action delegate

  • Add a new Toggle to your scene by going to Add>UI>Toggle in the Hierarchy window.
  • Create a new Game object called toggle_event_test.
  • Add a script called event_test to the game object and open it for editing.
  • 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. It takes a variable of type Boolean.
On Value Changed function in Unity inspector
  • 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.
  • To subscribe to the OnValueChange event of the toggle UI, we need to access the Toggle UI. Let’s create a public variable of type toggle.
  • In the Start() Function, let’s subscribe to the Unity action variable using the function On_change(). Now let’s subscribe it to the noValueChange 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;

    void Start()
    {
        my_action+=On_change;
        tog.onValueChanged.AddListener(my_action);
        
    }

    void On_change(bool state)
    {
        Debug.Log("value changed to "+state);
    }
}

Save the code and assign the Toggle UI to the variable. Play the game and change the toggle. The On_change() will be called and the current state of the toggle will be displayed on the console window.

Custom Unity Event tutorial without Delegates

Let’s create a custom event which is called when escape key is pressed, 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.

Here are the steps to create a custom event

  • In an empty scene, add an empty game object. Add a new script called event_test to the game object.
  • 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 ");
    }
}

Using the above code, we have created an event for escape key. You can subscribe to this event using multiple functions. All the functions, will be called when the escape key is pressed.

Custom Unity event using Delegates

This method 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’s template.

Let’s try to create the same scenario, where the function 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 have added a listener, then you can use the remove listener function.

Here is how to do it

void OnDestroy()
 {

     my_event-=On_change; //unsubscribe to an event

     //if you have added a listener

     my_event.RemoveListener(On_change);
    
 }

You have learnt about Delegates, Events, Unity actions and Unity events in this tutorial. Now it’s your turn to try them out.

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.

Discover more from VionixStudio

Subscribe now to keep reading and get access to the full archive.

Continue reading