informa
/
2 MIN READ
Blogs

UE4Cookery CPP002: Static delegate trick

Topic: Static delegate trick Source for UE4.23: https://github.com/klauth86/UE4Cookery/tree/main/CPP002

Sometimes we need to implement interaction between classes from different layers. For example, let's take a look at Player class and it's interaction with some UI Widget. Let it be UI Widget for Game Menu with floating Show/Hide mechanic. The main thing - how can we pass some signal from Player to UI Widget. One approach - to include all stuff, use UGameplayStatics to get Player instance and so on. However, this approach make it a little bit too coupled. One trick, that can be used here - static delegate. Let's make it through step by step.

First of all, lets create namespace, that will hold all UI Delegates. Also we add forward declaration for Player class. So that will be

 

UIDelegates.h

#pragma once

#include "Delegates/DelegateCombinations.h"

class AMyDefaultPawn;

namespace UIDelegates {

	DECLARE_MULTICAST_DELEGATE_OneParam(FToggleMenuEvent, AMyDefaultPawn*);

	extern FToggleMenuEvent OnToggleMenu;
};

 

and don't forget to add definition for extern thing in CPP

 

UIDelegates.cpp

#include "UIDelegates.h"

UIDelegates::FToggleMenuEvent UIDelegates::OnToggleMenu;

 

Ok, now we need to see Player class that will use it

 

MyDefaultPawn.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/DefaultPawn.h"
#include "MyDefaultPawn.generated.h"

UCLASS()
class CPP002_API AMyDefaultPawn : public ADefaultPawn {

	GENERATED_BODY()

protected:

	virtual void SetupPlayerInputComponent(UInputComponent* InInputComponent) override;

	void ToggleMenu();
};

 

MyDefaultPawn.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "MyDefaultPawn.h"
#include "Components/InputComponent.h"
#include "UIDelegates.h"

void AMyDefaultPawn::SetupPlayerInputComponent(UInputComponent* InInputComponent) {
	Super::SetupPlayerInputComponent(InInputComponent);

	InInputComponent->BindAction("ToggleMenu", IE_Pressed, this, &AMyDefaultPawn::ToggleMenu);
}

void AMyDefaultPawn::ToggleMenu() { UIDelegates::OnToggleMenu.Broadcast(this); }

 

And what about UI Widget? It can be very simple, just like this

 

GameMenuWidget.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Blueprint/UserWidget.h"
#include "GameMenuWidget.generated.h"

class AMyDefaultPawn;

UCLASS()
class CPP002_API UGameMenuWidget : public UUserWidget {

	GENERATED_BODY()

public:

	UFUNCTION(BlueprintImplementableEvent, category = "Game Menu Widget")
	void OnToggleMenu(AMyDefaultPawn* pawn);

protected:

	virtual void NativeConstruct();

	virtual void NativeDestruct();
};

 

GameMenuWidget.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "GameMenuWidget.h"
#include "UIDelegates.h"

void UGameMenuWidget::NativeConstruct() {
	Super::NativeConstruct();
	UIDelegates::OnToggleMenu.AddUObject(this, &UGameMenuWidget::OnToggleMenu);
}

void UGameMenuWidget::NativeDestruct() {
	UIDelegates::OnToggleMenu.RemoveAll(this);
	Super::NativeDestruct();
}

 

Note, that all subscriptions are operated in NativeConstruct and NativeDestruct methods. The first one is called just before Widget is added to Display hierarchy and the second - when it is removed from hierarchy. As for BlueprintImplementableEvent - they are used to implement some logic in BPs for things that have hard dependencies with visual elements.

 

So, let's do the last things - create BP around our UI Widget and put some visual logic to it:

 

BP_GameMenuWidget_Designer

BP in Designer

 

BP_GameMenuWidget_Graph

BP Graph

 

And that's it! And here is raw result

Result

 

So, static delegates can be really helpful in the sense of accessing objects (when it is a problem to access them directly) and resolving class dependencies and coupling...

Latest Jobs

Treyarch

Vancouver, BC, Canada
5.8.23
Producer

Bladework games

Remote (United States)
5.18.23
Senior Gameplay Engineer

University of Canterbury

Christchurch, Canterbury, New Zealand
5.17.23
Academic in Game Arts and Animation

Fred Rogers Productions

Hybrid (424 South 27th Street, Pittsburgh, PA, USA
5.19.23
Producer - Games & Websites
More Jobs   

CONNECT WITH US

Explore the
Advertise with
Follow us

Game Developer Job Board

Game Developer

@gamedevdotcom

Explore the

Game Developer Job Board

Browse open positions across the game industry or recruit new talent for your studio

Browse
Advertise with

Game Developer

Engage game professionals and drive sales using an array of Game Developer media solutions to meet your objectives.

Learn More
Follow us

@gamedevdotcom

Follow us @gamedevdotcom to stay up-to-date with the latest news & insider information about events & more