It’s funny to think that only seven chapters ago, you might have fired up Unity for the first time, and now you’re about to put final touches on your first game! At this point, gameplay is pretty much set, sounds are properly mixed and the assets are pretty much launched.
What’s left to do? Ship it!

Actually, no. This game isn’t early access! We’re going to ship this completed. (Followed by a massive Day One patch. ;])
Currently, Bobblehead Wars doesn’t provide a winning or losing condition. After a bit of time, the aliens stop spawning, leaving the space marine to ponder existence with nothing more than a loaded weapon in an empty arena.
In this chapter, you’ll provide a winning and losing condition and add some realism. In the process, you’ll learn about UnityEvents, the Unity particle system, and some additional animation features.
Of course, before you even think about game endings, you need to squash a rather big bug that you might not have noticed.
Note: This tutorial is part of a collection that teaches Unity development from the ground up. You can read the entire series over here. This series is free and does not require any account creation. All assets are provided. If you find it useful, feel free to buy me a coffee.
Learning Unity events
As the hero shoots aliens, the game takes them off the screen, but the GameManager knows nothing of their deaths. Why is this important?
For one thing, the GameManager may want to send condolence cards to the families. :] Secondly, the manager must know how many aliens are on the screen and when to end the game. Without that information, the space marine enjoys too much down time.
Thankfully, it’s not an insurmountable problem. Instead of counting the alien population, you’ll make it so that the GameManager gets notification of each death.
You’ll do this by using UnityEvent. C# also has an event system, but UnityEvent is built right into the engine.
Open your project in progress, or you can download the starter project here:
https://drive.google.com/file/d/1rKJfz5acQzFp6b5iTQPahHnBR5vQ3SjG/view?usp=drive_link
Open the Alien script in your code editor. Add the following underneath the existing using
statements:
using UnityEngine.Events;
This allows you to access UnityEvent in code. Next, add the following instance variable inside the class:
public UnityEvent OnDestroy;
The UnityEvent
is a custom event type that you can configure in the Inspector. In this case, you’re creating an OnDestroy
event. The OnDestroy
event will occur with each call to an alien.
Defining an event is only part of the equation. It’s kind of like planning a party. No matter how well you plan, it’s not a party if there are no guests.
Just as parties need guests, events need listeners, which do the job of taking notifications when something has happened. In the case of Bobblehead Wars, the GameManager needs to know when an alien dies. Hence, the GameManager needs to subscribe to the OnDestroy
event.
Subscribing to a UnityEvent
Save and head back to Unity. In the Project window, select the Alien in the Prefabs folder. The Inspector for the Alien component now displays the OnDestroy
event.

Before you can add GameManager to this list, you need to create a public method to subscribe to the event. Open the GameManager script and add the following at the bottom of the file, just before the closing brace:
public void AlienDestroyed()
{
Debug.Log("dead alien");
}
This prints a simple message to the console to let you know that the GameManager got a notification. Save and switch to Unity.
In the Project window, select the Alien in the Prefabs folder again. Find and select OnDestroy in the Inspector and click the + to add a new event.

This is where you add event listeners. You’ll notice a drop-down that reads Runtime Only, which means the events will run in Play mode.
Click the circle next to where it says None, and a Select Object pop-up will appear. Scroll through, and you’ll notice that the GameManager GameObject does not appear in the list (the script does, but not the GameManager object itself). What gives?
There’s a logical explanation for this: A prefab can’t contain a reference to a GameObject in the Hierarchy because that object may not be around when the game instantiates the prefab. When you link the two together, you’re introducing a potential error. For example, you could create another scene with aliens in it, but that scene may not have a GameManager in the other scene.
You can workaround this restriction with scripting.
Accessing scripts in code
Click the minus button to remove the entry in the OnDestroy()
list you added a second ago, then open the GameManager script, and find newAlien.transform.LookAt(targetRotation);
in Update(). Add the following after it:
alienScript.OnDestroy.AddListener(AlienDestroyed);
Here, you call AddListener
on the event and pass in the method to call whenever that event occurs — in this case, AlienDestroyed
. In short, every time this event occurs, the GameManager gets a notification.
Now, you need to generate the event. Save your changes and open the Alien script in the editor. Add the following method:
public void Die()
{
Destroy(gameObject);
}
This destroys the alien. In OnTriggerEnter()
, replace the line Destroy(gameObject);
with:
Die();
Here, you’ve refactored the destroy code into another method. It allows other objects to trigger the death behavior.
In Die()
, add the following before the Destroy()
statement:
OnDestroy.Invoke();
This notifies all listeners, including the GameManager, of the alien’s tragic death. Save, play the game and shoot some aliens. You’ll see a barrage of log messages.

Unsubscribing from an event
When an object that has an event is destroyed, the best practice is to remove all listeners from that event. Otherwise, you may create a memory leak by having a reference cycle. After OnDestroy.Invoke();
add the following:
OnDestroy.RemoveAllListeners();
This removes any listeners that are listening to the event. Now you need to update the GameManager. Open GameManager in your code editor, and replace AlienDestroyed()
with the following:
public void AlienDestroyed()
{
aliensOnScreen -= 1;
totalAliens -= 1;
}
This officially decreases the number of aliens on screen. Save your work and see how what you did works:
- The Alien script contains a UnityEvent called
OnDestroy
. - The GameManager script periodically spawns aliens. Each time it spawns an alien, it adds itself as a listener to the
OnDestroy
event. - When the alien collides with something and is about to die, it invokes its
OnDestroy
event. This has the effect of notifying the GameManager. - The GameManager updates the count of aliens on the screen, as well as the total number of aliens.
- The alien removes all listeners and destroys itself.
Now take a breather — you just squashed that bug with a mega-size fly swatter. On to more important matters.
Where to go from here
Unity events are a great way to send messages between GameObjects. You can also pass events using C# events as well. There are also lots of additional design patterns that you can employ.
That said, there’s still work to do. Your game needs to have a losing condition. Should your space marine take too many hits, his head will pop off. You’ll do this in the next tutorial.
Discover more from Jezner Blog
Subscribe to get the latest posts sent to your email.