Hello guys! In this video, I will show you how to create
Events using Scriptable Objects. This is a bit more advanced topic but when
you master it, it can be very useful. Let's quickly see why would you even use Events. Imagine that a player dies, you would need
to do a lot of follow-up actions. You would need to disable input controls,
maybe show some UI, stop or change music, notify enemies that the player is dead, and
so on. Managing all of that from a single script
can be difficult. You would need to connect the PlayerHealt
class with all other classes. Connecting scripts in such a way creates unnecessary
dependencies and it's not managable in real projects. This would quickly become a spaghetti mess. So how to avoid those connections? You have only one guess, Events. In this tutorial, I will use Scriptable Objects
to create Event System. If you want to learn more about Events without
Scriptable objects, I have another great tutorial, so check it out if you want. In this case, we will choose another approach
and use Scriptable Objects. Let me show you what we will create. When the player dies, I will disable controls
and show some UI text using Scriptable Object Events. This is just one example, possibilities are
endless. To create this system we need two scripts:
"GameEvent" and "GameEventListener." GameEvent needs to be a Scriptable Object. To easily create Scriptable Objects in Unity
Editor we need to use the attribute "CreateAssetMenu." Then let's create a list of "GameEventListener"
objects. Next, we need a public function to register
a listener. Just add it to the list. Of course, we also need a function that will
remove the listener from the list. Now let's go to the "GameEventListener" script. Notice that this class is MonoBehavior, which
means we will need to attach this script to a game object. Here, we will use Unity Events, so let's include
the "Events" namespace. We need one public "GameEvent" scriptable
object. Call it "Event." Then we need a public "UnityEvent" which I
call "Response." "UnityEvent" Response will determine what
will happen when Scriptable Object GameEvent is raised. So, this "GameEventListener" will listen for
the GameEvent, and when it is raised or fired, then activate Response. We need to register this listener to the list. Inside "OnEnable" let's use "Event.RegisterListener"
and pass this class. Remember, this is the function that will add
a listener to the list. And inside "OnDisable" we will remove the
listener from the list. We need one more public void function "OnEventRaised." It will invoke "UnityEvent," so write "Response.Invoke." Let's go back to the "GameEvent" scriptable
object. Here we need to add a public void "Raise"
function. It will use the "for" loop to go through the
list of listeners. It's important to go through the list from
behind to avoid errors. You can get errors if you start from 0, and
remove listeners from the list. The index will go out of range. Then for every listener, we call "OnEventRaised." That function will invoke Unity Event Response. Let's go to Unity. With right-click, create, we can create GameEvent
Scriptable Objects. Let's call this "EndGame." In the same way, we can create more scriptable
objects that will represent some events. For example, this can be: "StartFirstCutscene"
event. We will use "EndGame." The next step is to introduce listeners which
will listen to that event. You can place the listener on any game object. Sometimes it's a good idea to use one empty
game object. So add the "GameEventListener" script. This listener will listen to "EndGame." Drag the scriptable object. Then determine what will be the response. First, drag in the "Player." On the "PlayerControls" script I have a function
that will disable controls. Make sure that you set the event to "Runtime"
only. Then we can add another response. Drag in the UI text. It's disabled by default, and here we will
enable it. Just note that you can have more listeners
for one Event if you need it. The last thing we need to do is to raise the
event. We want to do it when the player dies. So I will go to the "PlayerHealth" script. Include the "Events" namespace. Create a public "UnityEvent" which I call
"DeathEvent." When the health is zero or below, invoke that
event. In Unity, make sure that event is set to "Runtime",
then drag the Scriptable Object "EndGame." We want to use the "Raise" function that will
notify all listeners. Let's try it. The player will die, I can't move anymore
and you can see the UI text. And that is how you can combine UnityEvents
and Scriptable Objects. Have a nice day and see you in the next video.