Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Game Development Patterns with Unity 2021 - Second Edition

You're reading from  Game Development Patterns with Unity 2021 - Second Edition

Product type Book
Published in Jul 2021
Publisher Packt
ISBN-13 9781800200814
Pages 246 pages
Edition 2nd Edition
Languages
Author (1):
David Baron David Baron
Profile icon David Baron

Table of Contents (22) Chapters

Preface 1. Sections 1: Fundamentals
2. Before We Begin 3. The Game Design Document 4. A Short Primer to Programming in Unity 5. Section 2: Core Patterns
6. Implementing a Game Manager with the Singleton 7. Managing Character States with the State Pattern 8. Managing Game Events with the Event Bus 9. Implement a Replay System with the Command Pattern 10. Optimizing with the Object Pool Pattern 11. Decoupling Components with the Observer Pattern 12. Implementing Power-Ups with the Visitor Pattern 13. Implementing a Drone with the Strategy Pattern 14. Using the Decorator to Implement a Weapon System 15. Implementing a Level Editor with Spatial Partition 16. Section 3: Alternative Patterns
17. Adapting Systems with an Adapter 18. Concealing Complexity with a Facade Pattern 19. Managing Dependencies with the Service Locator Pattern 20. About Packt 21. Other Books You May Enjoy
Managing Game Events with the Event Bus

The Event Bus acts as a central hub that manages a specific list of global events that objects can choose to subscribe to or publish. It's the most straightforward pattern related to event managing that I have in my toolbox. It reduces the process of assigning the role of subscriber or publisher to an object into a single line of code. As you can imagine, this can be beneficial when you need results quickly. But like most simple solutions, it has some drawbacks and limitations, which we will explore further on.

In the code example presented in this chapter, we will use the Event Bus to broadcast specific race events to components that need to listen for changes in the overall state of the race. But it's essential to keep in mind; I'm proposing using the Event Bus as a solution for managing global race events because of its...

Technical requirements

We will also be using the following specific Unity engine API features:

  • Static
  • UnityEvents
  • UnityActions

If you are unfamiliar with these concepts, please review Chapter 3A Short Primer to Programming in Unity.

The code files for this chapter can be found on GitHub at https://github.com/PacktPublishing/Game-Development-Patterns-with-Unity-2021-Second-Edition/tree/main/Assets/Chapters/Chapter06.

Check out the following video to see the code in action: 
https://bit.ly/2U7wrCM.

If you find yourself having problems understanding the mechanism behind delegates, keep in mind that they are similar to function pointers in C/C++. In simple terms, a delegate points to a method. And delegates are often used to implement event handlers and callbacks. An action is a type of delegate that you can use with a method that has a void return type.

Understanding the Event Bus pattern

When an event is raised by an object (publisher), it sends out a signal that other objects (subscribers) can receive. The signal is in the form of a notification that can indicate the occurrence of an action. In an event system, an object broadcasts an event. Only those objects that subscribe to it will be notified and choose how to handle it. So, we can imagine it as having a sudden burst of a radio signal that only those with antennas tuned to a specific frequency can detect.

The Event Bus pattern is a close cousin of the Messaging system and Publish-Subscribe patterns, the latter being the more accurate name for what the Event Bus does. The keyword in the title of this pattern is the term bus. In simple computing terms, a bus is a connection between components. In the context of this chapter, the components will be objects that can be publishers or listeners of events.

Hence, the Event Bus is a way to connect objects through events by using a publish...

Benefits and drawbacks of the Event Bus pattern

The benefits of the Event Bus pattern are as follows:

  • Decoupling: The main benefit of using an event system is that it decouples your objects. Objects can communicate through events instead of directly referencing each other.
  • Simplicity: The Event Bus offers simplicity by abstracting the mechanism of publishing or subscribing to an event from its clients.

The drawbacks of the Event Bus pattern are as follows:

  • Performance: Under the hood of any event system, there's a low-level mechanism that manages messaging between objects. And so there might be a slight performance cost when using an event system, but depending on your target platform, it could be minuscule.
  • Global: In this chapter, we implement the Event Bus with static methods and properties to make it easier to access from anywhere in our code. There is always a risk when using globally accessible variables and states as they can make debugging and unit...

When to use the Event Bus

I have used the Event Bus in the past for the following:

  • Rapid prototyping: I use the Event Bus pattern often when rapidly prototyping new game mechanics or features. With this pattern, I can easily have components that trigger each other's behaviors with events while keeping them decoupled. This pattern permits us to add and remove objects as subscribers or publishers with a single line of code, which is always helpful when you want to prototype something quickly and easily.
  • Production code: I use the Event Bus in production code if I can't find a justifiable reason to implement a more sophisticated approach to managing game events. It's a pattern that does the job well if you don't need to handle complex event types or structures.

I would avoid using a globally accessible Event Bus like the one presented in this chapter to manage events that don't have a "global scope." For instance, if I have a UI component in the HUD that...

Managing global race events

The project we are working on is a racing game, and most races are structured in stages. The following is a shortlist of typical racing stages: 

  • Countdown: At this stage, the bike is stopped behind the start line while a countdown timer is running down.
  • Race start: Once the clock hits zero, the green light signal is turned on, and the bike moves forward on the track.
  • Race finish: The moment the player crosses the finish line, the race is over.

In between the start and finish of the race, certain events can be triggered that could change the current state of the race:

  • Race pause: The player could pause the game while still racing.
  • Race quit: The player could quit the race at any time.
  • Race stop: The race could stop suddenly if the player is involved in a fatal crash.

So we want to broadcast a notification that signals the occurrence of each stage of the race and any other important event in between that will change the overall state of the race. This...

Implementing a Race Event Bus

We are going to implement the Race Event Bus in two easy steps:

  1. To start, we need to expose the specific race event types that we support, which we will do with the following enum:
namespace Chapter.EventBus
{
public enum RaceEventType
{
COUNTDOWN, START, RESTART, PAUSE, STOP, FINISH, QUIT
}
}

It's important to note that the preceding enum values represent specific events outlining the stages of a race, from start to finish. So we are restricting ourselves to handling events with just a global scope.

  1. The next part is the core component of the pattern, the actual game event bus class, which we will call RaceEventBus, to be more domain-specific in the naming convention of our classes:
using UnityEngine.Events;
using System.Collections.Generic;

namespace Chapter.EventBus
{
public class RaceEventBus
{
private static readonly
IDictionary<RaceEventType, UnityEvent>
Events = new Dictionary<RaceEventType...

Testing the Race Event Bus

Now that we have the core elements of the pattern in place, we can write some code to test our RaceEventBus class. For reasons of brevity, I have removed all the behavior code in each client class to focus on the use of the pattern:

  1. For starters, we are going to write a countdown timer that subscribes to the COUNTDOWN race event type. Once the COUNTDOWN event is published, it will trigger a 3-second countdown to the start of the race. And at the exact moment the count reaches its end, it will publish the START event to signal the beginning of the race:
using UnityEngine;
using System.Collections;

namespace Chapter.EventBus
{
public class CountdownTimer : MonoBehaviour
{
private float _currentTime;
private float duration = 3.0f;

void OnEnable() {
RaceEventBus.Subscribe(
RaceEventType.COUNTDOWN, StartTimer);
}

void OnDisable() {
RaceEventBus.Unsubscribe(
RaceEventType.COUNTDOWN...

Reviewing the Event Bus implementation

By using the Event Bus, we can trigger behaviors while keeping core components decoupled. It's straightforward for us to add or remove objects as subscribers or publishers. We also defined a specific list of global events that represent every stage of a race. Therefore, we can now start sequencing and triggering behaviors of core components, from the start to the end of a race, and anything in between.

In the next section, we will review some alternative solutions to the Event Bus, with each solution offering a different approach that might be a better solution depending on context.

Reviewing some alternative solutions

Event systems and patterns are a vast topic, and it's a subject matter we can't cover in depth in this book. Therefore, we have prepared a shortlist of patterns to consider when implementing an event system or mechanism, but keep in mind that there's a lot more out there, and we encourage you as a reader to continue exploring the topic beyond the limited scope of this book:

  • Observer: An oldie but goodie pattern in which an object (subject) maintains a list of objects (observers) and notifies them of an internal state change. It's a pattern to consider when you need to establish a one-to-many relationship between a group of entities.
  • Event Queue: This pattern permits us to store events generated by publishers in a queue and forward them to their subscribers at a convenient time. This approach decouples the temporal relationship between publishers and subscribers.
  • ScriptableObjects: It's possible to create an event...

Summary

In this chapter, we reviewed the Event Bus, a simple pattern that simplifies the process of publishing and subscribing to events in Unity. It's a tool that helps during rapid prototyping or when you have a defined list of global events to manage. However, it has its limits of use, and it's always wise to explore other options before committing to using a globally accessible event bus.

In the next chapter, we will implement a system that will allow us to replay player inputs. Many racing games have replay and rewind features, and with the Command pattern, we will attempt to build one from scratch.

lock icon The rest of the chapter is locked
You have been reading a chapter from
Game Development Patterns with Unity 2021 - Second Edition
Published in: Jul 2021 Publisher: Packt ISBN-13: 9781800200814
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime}