So, how can I #include my Widget Blueprint that I made using a C++ Class I made?

What I did was creating a C++ Class using a UserWidget as its Parent Class.

In here will be the code I used for both my .h and .cpp files.

// In my .h file

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

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Components/TextBlock.h"
#include "MyHUDDisplay.generated.h"

/**
 * 
 */
UCLASS()
class TOAS_NE_CPP_API UMyHUDDisplay : public UUserWidget
{
	GENERATED_BODY()

public:
	// Crearemos esta funciĂłn para actualizar el texto mostrado
	// en el contador de puntaje.
	UFUNCTION(BlueprintCallable)
		void UpdateScoreText(int32 ScoreToUpdate);

protected:
	// Etiqueta "BindWidget" en los metadatos de nuestra variable
	// permite a Unreal conectar esta variable con algĂşn 
	// componente de widget del tipo al que pertenece esta clase
	// mientras ese componente tenga el mismo nombre que nuestra
	// variable.
	UPROPERTY(meta = (BindWidget))
		class UTextBlock* UTB_ScoreDisplay;
	
	// FunciĂłn heredada de nuestra Super Clase UserWidget.h que
	// es llamado al momento de constuir el HUD en pantalla,
	// serĂ­a como nuestro constructor especializado en Widgets.
	void NativeConstruct() override;

};
// And over here my .cpp file

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


#include "MyHUDDisplay.h"

/// <summary>
/// From this function the score is updated on screen.
/// </summary>
/// <param name="ScoreToUpdate">Score to update. By design impossible to lower.</param>
void UMyHUDDisplay::UpdateScoreText(int32 ScoreToUpdate)
{
	// From this function the score will be updated.
	UTB_ScoreDisplay->SetText(FText::FromString("SCORE : " + FString::FromInt(ScoreToUpdate)));
}

void UMyHUDDisplay::NativeConstruct()
{
	Super::NativeConstruct();

	// Constructing the display on viewport would update the score text automatically
	UpdateScoreText(0);
}

And with this setup I create a Blueprint Widget with this class as it’s Parent.

I already set it up with a TextBlock with the same name as it’s variable in the Parent Class, so all I should do is add it to the viewport.

However, to do that I need to access the static class of my Widget.
I intend to Add to the Viewport from the Game Mode like this:

UMyHUD = CreateWidget<UMyHUDDisplay>(GetWorld()->GetGameInstance(), UMyHUDDisplay::StaticClass());
// Of course, with the exception that UMyHUDDisplay should actually be something like UMyHUDFromCPP

Normally what I thought I would do is to #include the reference to use the class, but I haven’t really found a proper way to do this at all, as much as I search even using the Reference Viewer for the Widget.

Thank you everyone in advance!

If you only want to create a widget in c++, what you can do is:

.h:
UPROPERTY(EditDefaultsOnly)
TSubclassOf<UUserWidget> MyHUDDisplayClass;

.cpp:
UMyHUD = CreateWidget<UUserWidget>(GetWorld()->GetGameInstance(), MyHUDDisplayClass);

And then set its value in your blueprint that you’ve created based on this c++ class.

Or if there’s no blueprint, you can skip the UPROPERTY() line and set the value using ConstructorHelpers.

However, in either case, you won’t be able to access any functions in the widget through c++ code. If you need to do that, you’ll need a c++ widget class.

Thanks for the reply Tuerer!

I went and checked out the ConstructorHelpers, tried it out but an error was printed on screen:

Default Property warnings and errors:
Error: CDO Constructor (ToaS_NE_CPPGameModeBase): Failed to find /Game/Widgets/MyHUDFromCPP.MyHUDFromCPP

I did use the correct Widget I wanted to construct from its class, but apparently the ConstructorHelpers weren’t able to find it- unless? I did something wrong?

This is what I did to my header:

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "MyPaperCharacter.h"
#include "MyHUDDisplay.h"
// Went and #included the uses of UserWidget and ConstructorHelpers
#include "Blueprint/UserWidget.h"
#include "UObject/ConstructorHelpers.h"
#include "ToaS_NE_CPPGameModeBase.generated.h"

/**
 * 
 */
UCLASS()
class TOAS_NE_CPP_API AToaS_NE_CPPGameModeBase : public AGameModeBase
{
	GENERATED_BODY()
	
public:
	AToaS_NE_CPPGameModeBase();

	void AddPoints(uint32 uint_NewPoints);

	// Added and changed the classes to load the UUserWidget.
	TSubclassOf<class UUserWidget> UMyHUD_Class;
	UPROPERTY(EditAnywhere)
		class UUserWidget* UMyHUD;

private:
	uint32 uint_LevelPoints;

protected:
	virtual void BeginPlay() override;

};

And to my CPP file:

#include "ToaS_NE_CPPGameModeBase.h"

// To my Game Mode constructor I put the ConstructorHelpers as I was told from another source.
AToaS_NE_CPPGameModeBase::AToaS_NE_CPPGameModeBase()
{
	DefaultPawnClass = AMyPaperCharacter::StaticClass();

	ConstructorHelpers::FClassFinder<UUserWidget> WidgetClassFinder(TEXT("WidgetBlueprint'/Game/Widgets/MyHUDFromCPP.MyHUDFromCPP'"));
	if (WidgetClassFinder.Succeeded())
	{
		UMyHUD_Class = WidgetClassFinder.Class;
	}
}

void AToaS_NE_CPPGameModeBase::AddPoints(uint32 uint_NewPoints)
{
	if (uint_LevelPoints <= 255)
	{
		uint_LevelPoints += uint_NewPoints;
	}

	if (GEngine)
	{
		
	}
}

// And on BeginPlay I'd know if the Class of my Widget (with a C++ class as its parent) was found.
void AToaS_NE_CPPGameModeBase::BeginPlay()
{
	if (UMyHUD_Class != nullptr)
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("A CLASS WAS FOUND."));
		}
	}
}

Perhaps I’m doing something else wrong?

try
…
WidgetClassFinder(TEXT("/Game/Widgets/MyHUDFromCPP"));
…

1 Like

This is it! This syntax is the correct way to use, thanks @Tuerer !

ConstructorHelpers::FClassFinder<T>

So, according to this case, the solution to finding my Widget Blueprint was to use the ConstructorHelpers::FClassFinder.

In our .h file we would “include” the following:

// The class of our C++ Widget, in my case:
#include "MyHUDDisplay.h"
// Went and #included the uses of UserWidget and ConstructorHelpers
#include "Blueprint/UserWidget.h"
#include "UObject/ConstructorHelpers.h"

UCLASS()
class TOAS_NE_CPP_API AToaS_NE_CPPGameModeBase : public AGameModeBase
{
	GENERATED_BODY()
	
public:
    // Our public constructor.
	AToaS_NE_CPPGameModeBase();

    // In my case I have a function that is called by the coins in my game when they're collected by the playable character.
	void AddPoints(uint32 uint_NewPoints);

	// We add the following to our public variables, we want to find it as a UUserWidget class.
	TSubclassOf<class UUserWidget> UMyHUD_Class;
    // In this variable we will Create and Reference our widget to add to viewport.
	UPROPERTY()
		class UUserWidget* UMyHUD;

private:
    // I keep my points, using the Super Mario 64 rules of coin values (yellow = 1, red = 2, blue = 5) as they're added when they're collected with the previous function.
	uint32 uint_LevelPoints;

protected:
    // And, as usual, our BeginPlay in our protected declaration.
	virtual void BeginPlay() override;

};

And in our CPP file of our GameMode we execute the following code:

// Copyright Epic Games, Inc. All Rights Reserved.


#include "ToaS_NE_CPPGameModeBase.h"

AToaS_NE_CPPGameModeBase::AToaS_NE_CPPGameModeBase()
{
    // This is where I tell my GameMode to load the static class of our playable character, in my case it's a 2D Paper Character.
	DefaultPawnClass = AMyPaperCharacter::StaticClass();

    // Inside our constructor we will also use the ConstructorHelpers, using the FClassFinder.
    // T type should be UUserWidget so that we can track our Widget correctly.
    // Usually when we Copy the Reference to our assets in our Content source it would normally come out as something like this: WidgetBlueprint'/Game/Widgets/MyHUDFromCPP.MyHUDFromCPP'
    // To make our ConstructorHelpers work this out, just as user Tuerer has pointed out, we need to remove from our reference the WidgetBlueprint part, and also our ' ' from the string. That way the Helpers won't have trouble finding our Widget or any asset you need to find.
	ConstructorHelpers::FClassFinder<UUserWidget> WidgetClassFinder(TEXT("/Game/Widgets/MyHUDFromCPP"));
	if (WidgetClassFinder.Succeeded())
	{
        // Just to make sure that this is done when the Helpers succeed with our class I placed an if. However, once it does then our .Class will be referenced in our _Class variable.
		UMyHUD_Class = WidgetClassFinder.Class;
	}
}

// The function that is called when a coin is collected in the world.
void AToaS_NE_CPPGameModeBase::AddPoints(uint32 uint_NewPoints)
{
	if (uint_LevelPoints <= 255)
	{
		uint_LevelPoints += uint_NewPoints;
	}

   // We verify that our Widget was created and the reference is not empty
	if (UMyHUD != nullptr)
	{
    // Since I'm using a C++ Widget, which means that it's a widget that has a C++ class as a parent (which in turn has UserWidget as a parent) I cast it to the C++ class so I can access my function to update the score text.
		UMyHUDDisplay* UMyHUD_OnScreen = Cast<UMyHUDDisplay>(UMyHUD);

		if (UMyHUD_OnScreen != nullptr)
		{
			UMyHUD_OnScreen->UpdateScoreText(uint_LevelPoints);
		}
	}
}

void AToaS_NE_CPPGameModeBase::BeginPlay()
{
    // We verify that our Class reference is not empty
	if (UMyHUD_Class != nullptr)
	{
        // We will create our widget using the instance of our game as the owner of the widget, and also the _Class variable we aquired.
		UMyHUD = CreateWidget<UUserWidget>(GetWorld()->GetGameInstance(), UMyHUD_Class);

        // We then proceed to Add our Created Widget to our Viewport in our designated layer.
		UMyHUD->AddToViewport(0);
	}
}


The results in action

Once again, thank you very much @Tuerer for helping me out!

1 Like

Thank you so much! @Accel-Diamond1 and @Tuerer