Tutorial: Simple global event system + practical use in HUD

Hello,

Small foreword - I am still very much in the exploration phase of UE4 myself, and there are most likely better ways to do this, but I hope this may help someone get a better understanding of delegates and exposing events to blueprints. Many thanks to the helpful bunch of #unrealengine for helping me wade through most of this, especially cncl2. I hope that, if this is well received, I can make a few more tutorials pertaining to the different aspects of the game that I’m creating, both C++ and Blueprint. That being said, without further delay…

Setting Up The Event Handler

Due to how the game architecture is set up, the most logical place to put my global event handler was the game state. I wanted however to keep the gamestate code less cluttered so I’ve separated the whole thing into a separate header file. Both the header and the implementation code can be found below.


#pragma once

#include "GlobalEventHandler.generated.h"


UCLASS(meta = (BlueprintSpawnableComponent), Category = "Global Events")
class UGlobalEventHandler : public UActorComponent
{
	GENERATED_UCLASS_BODY()

public:
	void InitializeComponent() OVERRIDE;

	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FLevelEventDelegate_OnLevelComplete , uint8, LevelIndex);

	DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FCurrencyEventDelegate_OnGoldAmountChanged, int32, OldAmount, int32, NewAmount);

	UPROPERTY(BlueprintAssignable, Category = "Level Events")
	FLevelEventDelegate_OnLevelComplete OnLevelComplete;

	UPROPERTY(BlueprintAssignable, Category = "Currency Events")
	FCurrencyEventDelegate_OnGoldAmountChanged OnGoldAmountChanged;

};

There are a few things to note here - first off, the class derives from UActorComponent, allowing me to add it as a component to my game state, or any other object that wants to broadcast events for that matter. The first thing the code does is declare two multicast delegate types. Multicast delegates are, in layman’s terms, arrays of functions with the same signature. An object (say, the player) may register a function with a delegate (adding to the array), and when the delegate broadcasts, the player’s function, as well as any other functions that is registered with the delegate gets called.

The format is DECLARE_DYNAMIC_MULTICAST_DELEGATE, followed by an optional suffix denoting the parameter amount (The code above has _OneParam and _TwoParams, it can go up to _EightParams). Finally, within brackets, the name of your delegate type followed by the actual parameters are listed. Very important to note though is that, unlike traditional function definitions, you are required to comma separate the parameter types from the parameter names.

Once that is done, you only just created delegate types, you don’t have any actual delegates yet. This is what the two UPROPERTIES in the header file above are - two delegates of the appropriate types. Note that these aren’t functions and therefore don’t have any signatures - they’re simply delegate objects.

The implementation file below is simply the default implementation of the UActorComponent, with nothing going on.


#include "FantasyAdventure.h"
#include "GlobalEventHandler.h"



UGlobalEventHandler::UGlobalEventHandler(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{

}


void UGlobalEventHandler::InitializeComponent()
{

}

With this in place, you can now add this to your game state.


//////////////.h////////////////////


#include "Global/GlobalEventHandler.h"

//
// In the UCLASS...
//

UPROPERTY(BlueprintReadOnly, Category = "Global Events")
TSubobjectPtr<class UGlobalEventHandler> GlobalEventHandler;


//////////////.cpp//////////////////

//In the constructor...

GlobalEventHandler = PCIP.CreateDefaultSubobject<UGlobalEventHandler>(this, TEXT("EventHandler"));

And you’re done! With this setup you are now ready to register and broadcast events from both code and blueprints. In order to broadcast events, all you have to do is access the GlobalEventHandler object from the game state and broadcast the event you want, like so:


GlobalEventHandler->OnLevelComplete.Broadcast(levelIndex);

The broadcast method takes the parameters specified in the delegate.

Listening To Events From Blueprint

Listening to events from blueprint is easy. As you saw in the code above I have an OnGoldAmountChanged delegate. In my game state I have a function that adds gold, and broadcasts the OnGoldAmountChanged event in the same way as the example above. My HUD has a display which has to pop on-screen when that event fires, so I have to listen to it.


The coin pickup blueprint.

I will not go into the details of how the coin display pops in and out off the screen (I may in a separate tutorial if people are interested), only the event relevant bits. For starters, all you have to do is get a reference to your game state, which gives you access to its Event Handler component. Dragging off a handle from that, and typing in the name of the event gives you this:

021d1451ef4accc63e83ce61b5b71d6df3adfdbc.jpeg

Hitting the assign event option gives this result:

1.JPG

A few things to note - The “Bind Event to EVENTNAME” node needs to be executed BEFORE the event has to, or can fire. This is the command that adds the event to the “array” of the delegate object. The red node, the actual event, will now get triggered whenever the event is broadcast from code. It will contain the parameters passed to the broadcast as well. Here’s a snippet of my HUD blueprint where the binding can be seen:

2 Likes

Welcome to the forums!

Amazing that your 2nd post is a tutorial!

Thanks for sharing!

:slight_smile:

Rama

Thanks, I hope it’s decent :smiley:

Good tutorial, thank you. It would be cool to place it in wiki, because it’ll be lost here.

As soon as I figure out how I will put it up :stuck_out_tongue:

Sorry to resurrect this, but I’ve since put this on the Wiki and updated it for 4.7: A new, community-hosted Unreal Engine Wiki - Announcements and Releases - Unreal Engine Forums

Enjoy!

Just what I was looking for, thanks sooo much for this, I happen to be also diving into UE4.