Delegates allow you to create robust and complex
behaviors in your scripts. A delegate can be
thought of simply as as a container for a function that can be passed around
or used like a variable. Just like variables, delegates can
have values assigned to them and these values can
be changed at run-time. The difference is that, while
variables contain data, delegates contain functions. Here we have a Scene
with a GameObject in it. The GameObject has a
Delegate Script attached to it. We will be mo
nitoring the output
of the Scene in the Console view. In the DelegateScript,
the first thing we do is declare our delegate template. This template will dictate
exactly what types of methods we can
assign to our delegate. We create a delegate with
the "delegate" keyword. What follows the delegate keyword is the delegate's signature. Just like a function,
our delegate has a return type, a name, and a parameter list. In this example, we
can see that in order for a method to be
assigned to this dele
gate, it must have a return type of void and take a single
integer parameter. After we create our delegate type, we then declare a member variable. This member variable has the type of the delegate we just created. At the bottom of our
script, we have two methods: PrintNum(), and DoubleNum(). We can see that
each of these methods has a return type
of void, and takes a single integer parameter,
just like our delegate. Additionally, each of these methods does something slightly different
with the
integer data passed in. Now it's time for us to see
exactly what delegates do. In the Start() method, you can
see that we assign the name of our PrintNum() method
to the myDelegate() variable. We then use the myDelegate()
variable as if it was a function. And we pass in the value of 50. We then assign the name
of the DoubleNum() method to the myDelegate() variable. Again we call it
just like a function. Let's take a look
at this code in action. Back in Unity, we can run our Scene
and look at the
Console view. We can see that
we are able to call two different methods using
the same delegate variable. This gives us a lot of power
to dynamically control which functions
get called in our games. Delegates also have the
ability to be multicast. Multicasting allows a
single delegate variable to represent multiple
methods at the same time. Here we have a Scene
with an orb in it. The orb has a script called
"Multicast Script" attached to it. In our Multicast Script,
we can see that we have crea
ted a delegate template. This template defines a delegate
named MultiDelegate(), which takes no parameters and
has a return type of void. Next we create a member
variable named myMultiDelegate, that is of the type of the
delegate template we just created. At the bottom of our script,
we have two methods named PowerUp() and TurnRed(). Both of these methods
take no parameters, and have a return type of void, just like our delegate type. The PowerUp() method prints "Orb is powering up" to the scre
en. The TurnRed() method changes
the color of the object to red. In the Start() method, we will
multicast our delegate variable. We do this by assigning
both the PowerUp() method and the TurnRed() method to
the same delegate variable, using the += operator. In this way, the variable,
myMultiDelegate, contains both the PowerUp()
and TurnRed() method. We then call the variable,
myMultiDelegate(), as if it were a function. If we go back into Unity
and run our Scene, we can see that multicasting
our
delegate variable allowed it to call both
the PowerUp() and the TurnRed() methods
with a single call. In this manner, we were
able to stack functionality. If we want to remove a method
from a delegate variable, we can do so using the -= operator in conjunction with
the method's name. One thing we must be careful of is attempting to call
a delegate variable like a function before we
have assigned anything to it. Doing so will cause an error,
and we like to avoid those. Any delegate variable that
doesn't currently have a method assigned to it
will have a value of null. Therefore, it is a good idea
to always check to make sure delegate does not equal
null before using it.
Comments