In this lesson, you will learn how to use Multicast Delegates to notify multiple game systems of an event without requiring them to know about each other.
Why Avoid Hard References?
In our previous lessons, you might have used direct references to talk to specific Actors (like passing a PlayerController to a Widget). While that works, it creates "tight coupling." If you ever decide to delete that Actor or replace it, your entire system breaks. Multicast Delegates solve this by acting as a radio transmitter: the broadcaster sends a signal out into the air, and any number of listeners can "tune in" to receive it.
Implementing the Observer Pattern
When we use a Multicast Delegate, the broadcaster doesn't know who is listening, how many are listening, or what they do with the information. They simply declare an event and "fire" it when something happens, such as a match ending or a player scoring.
Here is how you declare and broadcast a basic event in your C++ header file:
// 1. Declare the delegate signature
DECLARE_MULTICAST_DELEGATE(FOnMatchEnded);
class AMyGameState : public AGameStateBase
{
public:
// 2. Create the delegate instance
FOnMatchEnded OnMatchEnded;
void EndMatch()
{
// 3. Broadcast to all listeners
OnMatchEnded.Broadcast();
}
};
Listening to the Broadcast
Any other class—like a UserWidget, an AudioComponent, or an AchievementManager—can now subscribe to this event without the AGameState ever needing to know they exist:
// Inside an Actor's BeginPlay
if (AMyGameState* GS = GetGameState<AMyGameState>())
{
// Bind a function to be called when the event fires
GS->OnMatchEnded.AddUObject(this, &AMyActor::HandleGameOver);
}
By decoupling your systems this way, your code becomes modular and much easier to debug. If you remove the AchievementManager later, your GameState doesn't care—it just keeps broadcasting, and your project remains stable and clean.
Key Takeaway: Multicast Delegates allow you to create a "one-to-many" communication system where the broadcaster remains completely independent of its listeners, keeping your project architecture decoupled and scalable.