Global Messenger Subsystem
Global Messenger Subsystem is our new way of communicating between any (supports more than one) UObjects, Actors , Components, UMG and absolutely anything within Unreal (including Third-Party plugins) without even knowing each other.
For example, please take a look at the below video from one of our Viewport World preview.
Here, neither terminal nor the terminal command is aware of the secondary game world. The moment the terminal command is executed, Global Messenger Subsystem will broadcast the event with a specific tag and anything that is listening to that tag will execute the connected function. Here the game world will start listening to the specific tag so when terminal command is executed, the associated event (which is to spawn the bouncing ball) will run.
Global Messenger Subsystem inherits from World Subsystem which is auto instanced and is guaranteed to exist throughout the world. There are only three main functions in this and they are as follows.
- Broadcast Message - Broadcasts a message and is sent to all listeners that are currently registered to receive messages with the specified tag.
- Listen to Message - Listens for global messages that match the specified tag.
- Remove Listener - Stop listening and removes the listener.
Blueprint​
Let's take a look at how to setup using Blueprints. First open any Blueprint Graph, right click on an empty area and search for Global Message.
You can then select Get GlobalMessageSubsystem
node.
Broadcasting​
From the Global Message Subsystem node, drag a wire, search for Broadcast and add the Broadcast Message
node. Filter Tag
specifies the tag it should broacast.
Think of this as channel ID where you can broadcast on multiple channels if you want to.
NOTE: If no tag is specified, ALL listeners regardless of their tag will run their functions.
Payload determines what data you want to send through. This can be UObject, Actor, Component, Texture, Material or anything that inherits from UObject class. If you don't want anything then simply don't connect. This is an optional parameter. For example: Imagine a scenario where the player interacts with a switch and based on some condition it should either load a fantasy world or standard world behind a door. You can set the parameter in the door actor and then when the event is triggered, you can simply get the information and do the logic accordingly.
Based on the aforementioned example scenario, this could be a typical Blueprint setup.
Listening​
In the same way you added Broadcast node, you can add Listen to Message
node. Filter tag
specifies which tag it should listen to and Callback
specifies
the event that should run when the specific tag event is broadcasted. Continuing from the previous example, you can setup the Listen to Message like this:
Stop Listening​
Finally if you want to stop listening, simply call the Remove Listener
node with the object you want to stop listening. Under the hood, the Listen to Message
node adds the calling object
as listener automatically so following the previous example we want to remove the door as listener the moment the event is triggered and to achieve that, modify the graph like below.
C++​
To use Global Messenger Subsystem in C++, you must add the module in your Build.cs
file including GameplayTags
module.
Example:
PrivateDependencyModuleNames.AddRange(new string[] { "GlobalMessenger", "GameplayTags" });
To get the subsystem, you can call the static Get
function from UGlobalMessageSubsystem
.
The static Get
function expects a reference to UWorld instead of a pointer so make sure the World you are passing as parameter is valid
and you can dereference it using asterisk.
Broadcasting​
#include "GlobalMessageSubsystem.h"
// Get the subsystem.
const auto GlobalMessageSubsystem = UGlobalMessageSubsystem::Get(*GetWorld());
// Now call broadcast with your tag and optional payload.
GlobalMessageSubsystem->BroadcastMessage(SomeGameplayTag, nullptr);
// Optionally if you want to broadcast to *all* listeners regardless of their tag, broadcast with an empty tag.
// GlobalMessageSubsystem->BroadcastMessage({}, nullptr);
Listening​
In header file (.h)
// UFUNCTION macro is required.
UFUNCTION()
void SomeFunction(UObject* Payload);
In source file (.cpp):
#include "GlobalMessageSubsystem.h"
// Get the subsystem.
const auto GlobalMessageSubsystem = UGlobalMessageSubsystem::Get(*GetWorld());
// Create the delegate.
FGlobalMessageReceiveDelegate CallbackDelegate;
// Bind the delegate to the new function.
CallbackDelegate.BindDynamic(this, &ThisClass::SomeFunction);
// Now start listening.
// Here we are passing 'this' as our listener where as in Blueprint it was done automatically.
GlobalMessageSubsystem->ListenToMessage(this, SomeGameplayTag, CallbackDelegate);
Stop Listening​
#include "GlobalMessageSubsystem.h"
// Get the subsystem.
const auto GlobalMessageSubsystem = UGlobalMessageSubsystem::Get(*GetWorld());
// Stop listening
GlobalMessageSubsystem->RemoveListener(this);