How to properly create UMG UButton in C++ in UE5

I read some similar topics in the forum but nothing works form me. So I have following GameModeBase.h file:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "Blueprint/UserWidget.h"
#include "BattlefieldGameModeBase.generated.h"

UCLASS()
class MODULEBATTLE_API ABattlefieldGameModeBase : public AGameModeBase
{
	GENERATED_BODY()
	
public:
    UFUNCTION(BlueprintCallable, Category="Battlefield")
    void CreateBattlefield();

protected:
    virtual void BeginPlay() override;

    UPROPERTY()
    UUserWidget* CurrentBattlefield;
};

and GameModeBase.cpp file:

#include "BattlefieldGameModeBase.h"
#include "Components/Button.h"


void ABattlefieldGameModeBase::BeginPlay()
{
	Super::BeginPlay();
}

void ABattlefieldGameModeBase::CreateBattlefield()
{
    if (CurrentBattlefield != nullptr)
    {
        CurrentBattlefield->RemoveFromViewport();
        CurrentBattlefield = nullptr;
    }
    
    TSubclassOf<class UUserWidget> ButtonClass = UButton::StaticClass();
    UE_LOG(LogTemp, Warning, TEXT("=>: World=%p,  UButtonClass=%p"), GetWorld(), ButtonClass);
    CurrentBattlefield = CreateWidget<UUserWidget>(GetWorld(), ButtonClass);
    UE_LOG(LogTemp, Warning, TEXT("CurrentBattlefield=%p"), CurrentBattlefield);
    if (CurrentBattlefield != nullptr)
    {
        CurrentBattlefield->AddToViewport();
    }

    GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("Createbattlefield"));
}

The code compiles properly. Function CreateBattlefield() is called from BeginPlay of Level Blueprint but the button is not being created (function returns nullptr). Between two UE_LOGs surrounding CreateWidget function in logs is thrown:

CreateWidget called with a null class.

From logs I see that both GetWorld() and ButtonClass are not null. Where is the problem?

Because as weird as this may sound, Button is not a UserWidget.

This means that even though you are assigning something to ButtonClass, when Get is called TSubclassOf returns nullptr because the type is wrong.

It would be great if there were a runtime or compile time error when assigning to TSubclassOf, but here we are.

After a few days of struggling with code I have managed to create UMG button in c++ and handle it’s on click event. As it is not straightforward I wrote short tutorial demonstrating how to do it for those who are in need. The tutorial is here: ue5-umg-button-creation-and-onclick-handler-in-cpp

1 Like