Events are specialized delegates
that are useful for when you want to alert other classes
that something has happened.
In practice, you will see that events function
very similarly to public multicast delegates.
For more information on delegates,
see the lesson on delegates linked below.
An event can be thought of like a broadcast system,
any class that is interested in an event
can subscribe methods to it.
When that specific situation occurs,
like a button click, a power-up or player injury,
we invoke our event and that, in turn, calls the methods
of the subscribed classes.
We have here a Scene with two orbs in it.
One orb has a script called "Teleport Script".
while the other has a script called "Turn Color Script",
Attached to our camera is an "Event Manager" script.
An event can be made for just about any situation.
But in this example, we want to invoke an event
whenever the player clicks a button
that we are drawing to the screen.
In our EventManager, we can see that we first create
a delegate type, which we name ClickAction().
We can see that any method that wishes to subscribe to our event
must take no parameters and have a return type of void.
Next, we create our event variable.
We do this with the "event" keyword.
Note that this variable is also static, so that we
can use it outside of the class
without instatiating an object of this class.
Our event variable, which we have named OnClicked(),
is of the type of the delegate we created above.
The only other thing this class is responsible for
is calling the event whenever the appropriate situation arises.
Like we stated before, we will call this event
whenever the player clicks our button.
Therefore, this script has an OnGUI() method.
Inside the OnGUI() method, we create a button on our screen.
When the player clicks the button,
we use our event variable as if it was a function,
This, in effect, invokes our event.
Please note that, just like delegates, it causes an error
if we invoke an event with no subscribers.
Therefore, we should always make sure that the event
does not equal null before invoking it.
If you recall, the two orbs in our Scene
have two different scripts attached to them.
These two scripts will act as subscribers to this event.
Let's take a look at them now.
In the TeleportScript, we have created a method called Teleport().
This is the method that we will be subscribing
to the event that we created in the EventManager.
You will notice that the Teleport() method takes no parameters
and has a return type of void, just like our delegate.
The Teleport() method is responsible
for positioning the object randomly along the Y-axis.
Near the top of our script we have a method named OnEnable().
This is a built-in method that will be called
whenever the object that the script is attached to
is created, or enabled, in a Scene.
We will use this method to subscribe our Teleport() method
to the OnClicked event of the EventScript.
We can see that we subscribe a method
to an event by using the += operator.
By subscribing a method to an event, we ensure that
whenever the event occurs, our method will be called.
Next, we have the OnDisable() method.
Opposite of the OnEnable() method,
the OnDisable() method is called
whenever an object is disabled, or destroyed, in a Scene.
Inside the OnDisable() method,
we are unsubscribing our method from the event.
We unsubscribe a method from an event using the -= operator.
Doing so will ensure that our method is
no longer called when an event occurs.
This step is incredibly important, and failure to do so
can lead to memory leaks and errors in your game.
A good rule is that whenever you subscribe
a method to an event, you must also have a corresponding unsubscribe.
Our TurnColorScript is structured
very similarly to our TeleportScript.
In this case, we have a method called TurnColor(),
which takes no parameters and has a return type of void.
The TurnColor() method turns the object's material a random color.
Again, we have the OnEnable() and OnDisable() methods.
This time, they are subscribing and unsubscribing
our TurnColor() method from the event.
It is worth noting another time
that unsubscribing our method from the event
is paramount to using events correctly
and preventing errors in our code.
Back in Unity, we can run our Scene.
The first thing to notice is the button that appears near the top.
Clicking this button will invoke our event,
and call the Teleport() and TurnColor() methods.
We can click the button multiple times,
and each time, the subscribed-to methods will be called.
As we can see, our EventManager only needed to worry
about the event itself and the triggers for the event.
It did not need to know about the TeleportScript,
or the TurnColor script.
Likewise, the TeleportScript and TurnColorScript
didn't need to know about each other.
In this way, we're able to create
a very robust and flexible broadcast system.
You might be wondering why we used a static event variable
instead of a public delegate variable in our EventManager.
The truth is, you can achieve the exact same
functionality of events with public delegate variables.
In fact, as we stated at the beginning of this lesson,
events are just specialized delegates.
The reason we use events about the over public delegate variables
for situations like this is that events have inherent security,
where delegate variables do not.
With events, other classes
can only subscribe and unsubscribe.
If we were to use a public delegate variable instead,
other classes could invoke or override our delegate variable
to do all sorts of nefarious things.
Generally speaking, if you want to create a dynamic
method system that involves more than one class,
use event variables instead of delegate variables.