In this lesson, you will learn how to create a centralized Global Event Bus that allows disparate game systems to communicate without holding direct references to one another.
The Problem: Tight Coupling
As your game scales, you often run into "spaghetti code" where your PlayerController needs to talk to the UIManager, the SoundManager, and the QuestTracker. If you manually link these via the Inspector or GetComponent, you create a nightmare of dependencies where changing one class breaks three others.
The Solution: The Global Event Bus
A Global Event Bus acts as a post office. Systems that need to announce something "post" an event to the bus, and systems interested in that information "subscribe" to it. Neither party knows the other exists; they only know about the bus.
We can achieve this using static C# Action delegates. Here is a simple implementation:
using System;
using System.Collections.Generic;
public static class EventBus
{
// A dictionary to store events by their unique type or key
public static event Action OnPlayerDeath;
public static void PublishPlayerDeath()
{
OnPlayerDeath?.Invoke();
}
}
How It Works
- Publishing: When the
Playerhealth reaches zero, it callsEventBus.PublishPlayerDeath(). It doesn't care who is listening. - Subscribing: The
UIManagersubscribes to the bus in itsOnEnablemethod (EventBus.OnPlayerDeath += ShowGameOverScreen;) and unsubscribes inOnDisableto prevent memory leaks. - Decoupling: You can add a
SoundManagerthat plays a "Sad Trombone" sound on the same event without ever modifying thePlayerorUIManagerscripts.
By routing communication through this static intermediary, your systems remain lean and modular. You adhere to the Open-Closed Principle because you can add new listeners to an event without changing the code that triggers the event.
Key Takeaway: The Global Event Bus eliminates direct dependencies between classes by acting as a universal messenger, allowing systems to communicate solely through shared event contracts.