Unity Programming - Delegates and Events

March 18, 2019

Unity Programming - Delegates and Events

Tutorials and Definitions

Youtube - Delegates - Unity Official Tutorials
By: Unity
Youtube - Events - Unity Official Tutorials
By: Unity

The scene management update has made significant progress, I am now currently loading and unloading the proper scenes at the proper times. The timing of the loading and unloading is still off however, as well as the fading animation timing is very strange. The fading error makes sense since I have the scene transition and the fading in the same method currently, so I will look to separate those and time them properly with IEnumerators. I was also told today that OnSceneLoad delegates would be a very helpful feature for me to look into to fix all my scene loading timings.

The basic IEnumerator timing I was also suggested to look into was: wait until animation is done, wait until next scene is loaded, then unload scenes to be unloaded.

Upon investigating delegates, I found that they are a very big part of coding in general. Looking into delegates also led me to events, which are somewhat like a specialized type of delegate. I believe understanding both of these will be very beneficial to my current scene loading issues, as well as being very useful for many other game programming purposes, so I wanted to take the time to better understand them before rushing back to my scene development needs.

TERMINOLOGY

Delegates

Delegates: Simply a container for a function that can be passed around, or used as a variable. Just like variables, delegates can have values assigned to them and can be changed at runtime. The difference is that while variables contain data, delegates contain functions.

First you create a delegate template with the delegate keyword. This dictates what types of methods we can assign to the delegate. Similar to a function, a delegate has: a return type, a name, and a parameter list. The methods you want to add to this delegate must have both the same type of return type and parameter list. You then have to declare a member variable with the type of the delegate you created.
Example:
delgate void MyDelegate(int num)
MyDelegate myDelegate

Then, you can either assign methods to the delegate as values directly, or add/remove methods from the delegate with the += or -= operators respectively. Adding several methods to a single delegate is called multicasting.

The example from the Unity Official Tutorial I linked is as follows: using UnityEngine;
using System.Collections;

public class MulticastScript : MonoBehaviour
{
delegate void MultiDelegate();
MultiDelegate myMultiDelegate;


void Start ()
{
myMultiDelegate += PowerUp;
myMultiDelegate += TurnRed;

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

void PowerUp()
{
print ("Orb is powering up!");
}

void TurnRed()
{
renderer.material.color = Color.red;
}
}

This shows the potential of a multicast delegate. On start, the PowerUp and TurnRed methods are both added to the myMultiDelegate delegate (which is possible since both methods have return type of void with no parameter list, just as the delegate does). Now anytime afterward, if the myMultiDelegate is called, it will perform all of the methods added to it (in this case both PowerUp and TurnRed). It is also noted that if you want to remove methods from myMultiDelegate, just use the -= operator along with the name of the method you want to remove.

One final note was that attempting to use a delegate that has not been assigned anything will cause an error. In this case, a delegate will have its default value, which is null. This is why they show in the tutorial that it is good practice to check that the delegate is !null before attempting to use it.

Events

Events: specialized delegates that are useful when you want to alert other classes that something has happened. An event can be thought of as a broadcast system. Any class interested in an event can subscribe methods to it. When that specific situation occurs, the event is invoked, which calls the methods of the subscribed classes. So an event is just like a delegate classes can send methods to, and then when that event is called, all of those methods will happen.

In the Unity Event tutorial I linked, they start by creating an EventManager script they place on the camera (this might be different with Event Systems now, this is an old tutorial). They then create a public delegate, which is then the type used for the public static event they create. So it appears that an event might be something similar to a list of delegates, and you add the type of delegate to it to determine what types of methods you can subscribe to this event. The tutorial then ties the event to a button press. Now any time this button is pressed, every method subscribed to the event will be invoked.

To show the broadcasting nature of events, there are two separate game objects with two separate scripts attached to them that subscribe different methods to the same event. They also show the proper fundamental practice of dealing with events. The scripts subscribe their methods to the event OnEnable, and unsubscribe them OnDisable (this is similarly does as with delegates; the += operator subscribes a method to an event, and the -= operator removes the method). It is a good rule of thumb that every time you subscribe a method to an event, you should create a corresponding unsubscribe for it as well. Failing to do this properly can lead to memory leaks and other various errors.

They then describe why this system is effect for dealing with action in your game. The event manager only needs to worry about the event itself and the triggers for the event. It does not need to know about the Teleport of TurnColor script, and these two scripts didn't need to know about each other either. This helps create a flexible broadcast system.

They then describe the difference between using a public delegate and the event they created. They state that you could acheive the same effect this way, since events are just specialized delegates. The reason to use an event here is that they have inherent security. Events ONLY allow other classes to subscribe and unsubscribe. If a delegate was used, other classes could invoke it or overwrite it.

The take away: if you want to create a dynamic method system that involves more than one class, use event variables instead of delegate variables.

Comments

Popular posts from this blog

Online Multiplayer Networking Solution Tutorial Using Unity and Mirror - Tutorial by: Jason Weimann

Sebastian Lague A* Tutorial Series - Path Smoothing - Pt. 08 and Pt. 09

Exporting FBX from Houdini with Color