Let’s Build a Custom Event System in Unity3D

Akshay Arora
XRPractices
Published in
5 min readMay 3, 2020

Before jumping into what is an event system and how to make it, let’s first discuss why is it useful to have an event system?

In Unity, you will be relying on one of the two things listed below to get the data or dependencies from another class.

You either

Bunch your public or serialized properties in a Monobehaviour to be able to assign it from the inspector to get the references.

Or

Use the Singleton pattern in your code to get the data you need.

If you are not already aware of the Singletons design pattern, it is a software design pattern that restricts the instantiation of a class to one single instance. This is useful when exactly one object is needed to coordinate actions across the system.

If another object in the code needs data from that object, we call the singleton instance to refer to it. Singletons are very useful to refer to the classes which you know are going to need only one instance of it.

Regardless of what approach you use to get the dependencies, you will face issues when tweaking a small thing or refactoring the code, especially if working on a very large project.

Let’s alleviate the dependencies!

Custom Event System

Event systems help modularize your code by sending messages between classes that do not directly know about each other. They allow things to respond to a change in a state without constantly monitoring it in an update loop. It is a form of Observer pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling their methods.

Let’s understand this by an example of a magazine subscription.

  • A magazine publisher(subject) is in the business and publishes magazines (data).
  • If you(user of data/observer) are interested in the magazine you subscribe(register), and if a new edition is published it gets delivered to you.
  • If you unsubscribe(unregister) you stop getting new editions.
  • Publisher doesn’t know who you are and how you use the magazine, it just delivers it to you because you are a subscriber(loose coupling).

How to design the Event System?

I have a scene in which we have a ThirdPersonController player(say Mr. X), a maze, and some doors. Now, let’s say Mr. X wants to reach the exit of the maze but there are some doors in between which can be opened as soon as Mr. X reaches close to them.

The doors have trigger box collider that triggers the other collider involved in this collision.

Let’s implement this using an event system.

Let’s start by adding a GameObject in the scene and adding a new script called EventsManager.cs

Our first events will be the ones that will fire when our player enters or exits the trigger area of the door.

For that, In EventsManager.cs class, create two event actions DoorTriggerEnter and DoorTriggerExit, also, methods that can invoke the respective event action. Also, create a static singleton reference for the class.

Now, we need objects which can fire and subscribe to these events. For that create two classes, one for the door, DoorController.cs, and one for the door’s trigger area, DoorTrigger.cs.

In the DoorController.cs, create two methods that can listen when someone fires DoorTriggerEnter or DoorTriggerExit events and perform their tasks. In the Start method of the DoorController, access the events from the EventsManager class by using the static instance, and subscribe to its respective method.

Now, our events are ready and subscribers are listening to these events. So, in the DoorTrigger class, we just need to fire those events in the OnTriggerEnter method.

Okay.. so let’s attach DoorController and DoorTrigger script to each door and trigger area respectively and play the scene.

Uhh Ohh! There’s one problem...

Our EventManager is a singleton class and every door trigger is invoking the event and every door controller is listening and responding to that same event. We need to pass some unique id while invoking the event so that only the door which has the same id will listen to that event.
In our particular case, triggers and door’s parent object are the same. So, we can pass the instance id of the parent’s gameobject.

Let’s play the scene..

Yeahhh.. it's working as expected now.

Make sure to unsubscribe these events as they may lead you to some unwanted errors. For example, if you destroy your door at runtime, etc.

So, that’s how we can make our simple event system.

That’s all for now folks... Happy Coding! :)

Source code: https://github.com/akshaytw/eventsysteminunity

--

--