Widget Reference always Null when using CreateWidget

I created a UObject class named MasterHUD to deal with every UI in the game. It’s a multiplayer game so this is created locally on the client using the character. I’m calling a function that Initialize the HUD. Problem is, everytime I execute CreateWidget, the widget reference always end up in a ACCESS_VIOLATION Error.

[2018.08.15-15.04.45:673][ 35]LogWindows: Error: Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x000000a8
[2018.08.15-15.04.45:673][ 35]LogWindows: Error: 
[2018.08.15-15.04.45:673][ 35]LogWindows: Error: [Callstack] 0x00007ffa75b3bec2 UE4Editor-CoreUObject.dll!UnknownFunction []
[2018.08.15-15.04.45:673][ 35]LogWindows: Error: [Callstack] 0x00007ffac83888e8 UE4Editor-Netherworld-2270.dll!FSoftObjectPtr::LoadSynchronous() [c:\program files\epic games\ue_4.20\engine\source\runtime\coreuobject\public\uobject\softobjectptr.h:51]
[2018.08.15-15.04.45:673][ 35]LogWindows: Error: [Callstack] 0x00007ffac83885cc UE4Editor-Netherworld-2270.dll!UMasterHUD::InitHUD() [c:\users\alexa\documents\netherworld\source\netherworld\masterhud.cpp:35]
[2018.08.15-15.04.45:673][ 35]LogWindows: Error: [Callstack] 0x00007ffac838ab33 UE4Editor-Netherworld-2270.dll!AMyGameCharacter::CreateHUD() [c:\users\alexa\documents\netherworld\source\netherworld\netherworldcharacter.cpp:94]

I tried so many things and it has been 2 days now that I’m working on this little feature of a UI Manager. Here is my code:

MasterHUD.h

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "Blueprint/UserWidget.h"
#include "Components/WidgetComponent.h"
#include "MasterHUD.generated.h"

/**
 * 
 */

USTRUCT(BlueprintType)
struct FPlayerUI {

	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	APlayerController* playerController = NULL;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	class UUserWidget* PauseMenu = NULL;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	class UUserWidget* InventoryMenu = NULL;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	class UUserWidget* InGameHUD = NULL;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	bool displayingPauseMenu = false;
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	bool displayingInventoryMenu = false;

	FPlayerUI()
	{
		playerController = NULL;
		PauseMenu = NULL;
		InventoryMenu = NULL;
		InGameHUD = NULL;
		bool displayingPauseMenu = false;
		bool displayingInventoryMenu = false;
	}

	FPlayerUI(APlayerController* pc, UUserWidget* pm, UUserWidget* im, UUserWidget* hud)
	{
		playerController = pc;
		PauseMenu = pm;
		InventoryMenu = im;
		InGameHUD = hud;
		bool displayingPauseMenu = false;
		bool displayingInventoryMenu = false;
	}
};



UCLASS(Blueprintable, BlueprintType)
class NETHERWORLD_API UMasterHUD : public UObject
{
	GENERATED_UCLASS_BODY()
	
public:

	UMasterHUD();

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = HUD)
	TAssetSubclassOf<class UUserWidget> refPauseMenu;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = HUD)
	TAssetSubclassOf<class UUserWidget> refInventoryMenu;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = HUD)
	TAssetSubclassOf<class UUserWidget> refInGameHUD;

	UFUNCTION(BlueprintCallable, Category = Game)
	void InitHUD(APlayerController* playerController);

	UFUNCTION(BlueprintCallable, Category = Game)
	void DisplayPauseMenu(APlayerController* playerController);

	UFUNCTION(BlueprintCallable, Category = Game)
	bool DisplayInventoryMenu(APlayerController* playerController);

private:

	TArray<FPlayerUI*> playerUIs = TArray<FPlayerUI*>();

	void DisplayMenu(class UUserWidget* widget, bool display);

	FPlayerUI* FindPlayerUI(APlayerController* playerController);
};

MasterHUD.cpp

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

#include "MasterHUD.h"
#include "Logger.h"
#include "Runtime/CoreUObject/Public/UObject/ConstructorHelpers.h"

UMasterHUD::UMasterHUD(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	ConstructorHelpers::FClassFinder<UUserWidget> newInGameHUDClassRef(TEXT("/Game/UI/InGameHUD"));
	if (newInGameHUDClassRef.Class) {
		refInGameHUD = newInGameHUDClassRef.Class;
	}

	ConstructorHelpers::FClassFinder<UUserWidget> newInventoryClassRef(TEXT("/Game/UI/Inventory"));
	if (newInventoryClassRef.Class) {
		refInventoryMenu = newInventoryClassRef.Class;
	}

	ConstructorHelpers::FClassFinder<UUserWidget> newPauseMenuClassRef(TEXT("/Game/UI/PauseMenu"));
	if (newPauseMenuClassRef.Class) {
		refPauseMenu = newPauseMenuClassRef.Class;
	}
}

void UMasterHUD::InitHUD(APlayerController* pc)
{
	if (!pc) 
	{
		ULogger::LogMessage("Error, trying to init a HUD of a null player controller");
		return;
	}

	// CREATING MENUS

	FPlayerUI* newPlayerUI = new FPlayerUI(pc,CreateWidget<UUserWidget, APlayerController>(pc, refPauseMenu.LoadSynchronous()),
										CreateWidget<UUserWidget, APlayerController>(pc, refInventoryMenu.LoadSynchronous()),
										CreateWidget<UUserWidget, APlayerController>(pc, refInGameHUD.LoadSynchronous()));

	// SET DISPLAY OPTIONS PAUSE MENU

	newPlayerUI->PauseMenu->AddToViewport(3);
	newPlayerUI->PauseMenu->SetVisibility(ESlateVisibility::Hidden);
	newPlayerUI->displayingPauseMenu = false;

	// SET DISPLAY OPTIONS INVENTORY MENU

	newPlayerUI->InventoryMenu->AddToViewport(2);
	newPlayerUI->InventoryMenu->SetVisibility(ESlateVisibility::Hidden);
	newPlayerUI->displayingInventoryMenu = false;

	// SET DISPLAY OPTIONS IN GAME HUD

	newPlayerUI->InGameHUD->AddToViewport(1);
	newPlayerUI->InGameHUD->SetVisibility(ESlateVisibility::Visible);

	playerUIs.Add(newPlayerUI);

	ULogger::LogMessage("HUD Initialised");
}

void UMasterHUD::DisplayPauseMenu(APlayerController* playerController)
{
	FPlayerUI* currentPlayerUI = FindPlayerUI(playerController);
	if (currentPlayerUI->displayingPauseMenu)
	{
		DisplayMenu(currentPlayerUI->PauseMenu,false);
		currentPlayerUI->displayingPauseMenu = false;
	}
	else 
	{
		DisplayMenu(currentPlayerUI->PauseMenu,true);
		currentPlayerUI->displayingPauseMenu = true;
	}
}

bool UMasterHUD::DisplayInventoryMenu(APlayerController* playerController)
{
	FPlayerUI* currentPlayerUI = FindPlayerUI(playerController);
	if (currentPlayerUI->displayingInventoryMenu)
	{
		DisplayMenu(currentPlayerUI->InventoryMenu,false);
		currentPlayerUI->displayingInventoryMenu = false;
	}
	else 
	{
		if (currentPlayerUI->displayingPauseMenu)
			return false;

		DisplayMenu(currentPlayerUI->InventoryMenu, true);
		currentPlayerUI->displayingInventoryMenu = true;
	}
	return true;
}

void UMasterHUD::DisplayMenu(UUserWidget* widget, bool display)
{
	if (display)
		widget->SetVisibility(ESlateVisibility::Visible);
	else
		widget->SetVisibility(ESlateVisibility::Hidden);
}

FPlayerUI* UMasterHUD::FindPlayerUI(APlayerController * playerController)
{
	for (size_t i = 0; i < playerUIs.Num(); i++)
	{
		if (playerUIs[i]->playerController == playerController)
			return playerUIs[i];
	}
	return new FPlayerUI();
}

Here is the function that calls the creation of the manager and the Init Function

void AMyGameCharacter::CreateHUD()
{
	FStringAssetReference bpRef = "Blueprint'/Game/Blueprint/MasterHUD_BP.MasterHUD_BP'";

	UObject* bpInstance = bpRef.ResolveObject();

	UBlueprint* result = Cast<UBlueprint>(bpInstance);

	FActorSpawnParameters SpawnInfo;

	hud = GetWorld()->SpawnActor<UMasterHUD>(result->GetClass(), SpawnInfo);

	hud->InitHUD(localPlayerController);
}

I’ll try to be more specific. The problem is on my variables similar to refPauseMenu. Whatever I do, the reference is not right. Everything crashes instantly when I used it. At the start the reference was set in the child blueprint, now I set it in the constructor…still crashes.

maybe instead of TAssetSubclassOf try TSubclassOf

TSubclassOf<UUserWidget> RefToWidgetBP;
// and then simply
if(auto NewlyCreatedWidget = CreateWidget(pc, RefToWidgetBP))
{
          // Do something with NewlyCreatedWidget 
}

that’s all a widget will be created

Your code have several problems :

  1. In your constructor, you define and initialize a variable instead of initiliazing your members. bool displayingInventoryMenu = false; should be displayingInventoryMenu = false;.
  2. You are using new but doesn’t have even 1 delete → awful memory leaks.
  3. Why are you using pointers with your struct anyway? FPlayerUI newPlayerUI = FPlayerUI(...) is cleaner.
  4. You should use GENERATED_BODY instead of GENERATED_USTRUCT_BODY() (minor).

Problem is, everytime I execute CreateWidget, the widget reference [it is pointer… - ed] always end up in a ACCESS_VIOLATION Error.

Try :

auto* const PauseMenu = CreateWidget<UUserWidget, APlayerController>(pc, refPauseMenu.LoadSynchronous());
if (!PauseMenu)
{
	ULogger::LogMessage("I was wrong, Pause Menu is nullptr.");
	return;
}

auto* const InventoryMenu = CreateWidget<UUserWidget, APlayerController>(pc, refInventoryMenu.LoadSynchronous());
if (!InventoryMenu )
{
	ULogger::LogMessage("I was wrong, Inventory Menu is nullptr.");
	return;
}

auto* const GameHUD = CreateWidget<UUserWidget, APlayerController>(pc, refInGameHUD.LoadSynchronous());
if (!GameHUD )
{
	ULogger::LogMessage("I was wrong, Game HUD is nullptr.");
	return;
}

ULogger::LogMessage("I was wrong, CreateWidget() doesn't crash.");

FPlayerUI* newPlayerUI = new FPlayerUI(pc, PauseMenu, InvetoryMenu, GameHUD);
 ULogger::LogMessage("If I don't see this line, the previous line crashed.");