We’re going to take a short break from adding new features to our game to clean up some of the existing code. When we set up the Restart functionality with our refactor of the new Input System implementation, we made note that we created an
OnPlayerDeath() function in 3 different components so far.
Seems like a lot of repetition and it puts a lot of responsibility on the Player object. We’re manually running multiple functions from different components at a certain point that just happens to be when the player has lost all their lives. Wouldn’t it be great if there was a system that we could make that would run these functions because the player died? Yes, yes it would, and that’s where delegates and events come in.
This is a basic implementation of a delegate and an event. When breaking down what we’re attempting to do here, it’s good to have at least a conceptual understanding of what events and delegates do.
A delegate can be thought of as a variable that stores a series of methods that we want to run whenever something specific happens.
An event is basically the trigger that tells our delegate to run all the methods that are subscribed to it. We can set a series of functions from different components to subscribe to an event.
So we’ve got our Player object creating a delegate and an event. Fantastic! Now we need have our components subscribe to this delegate with their functions. We’ve got a handy reference for where we need to subscribe in our
Damage() method in Player.cs.
SpawnManager, UIManager, and InputManager all call their own
OnPlayerDeath() functions from here. We want to subscribe to our event in each of these components. Using
OnEnable() , we add our component’s
OnPlayerDeath() method to the event. We’ll also unsubscribe from them in
OnDisable() to be tidy and ensure we’re safeguarding against weird bugs later.
We’ve successfully created a delegate with a coordinating event and give it a different function from each of our 3 components that are going to be affected when our player dies. Now we just need to actually trigger the event.
The player dies when their
_lives variable is less than 1, so this is a fine spot to trigger our
onPlayerDeath event. Delete the 3 lines calling each individual function and replace it like in the image above. The question mark is called a null conditional operator. This syntax will null check the
onPlayerDeath event and then Invoke (or trigger) the event. Your 3 components are actively listening for this to happen, and when it does, they’ll fire off their subscribed methods accordingly.