x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

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.

Product Version: UE 4.20
Tags:
more ▼

asked Aug 15 '18 at 05:34 PM in C++ Programming

avatar image

xeal1084
6 1 1 3

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

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

more ▼

answered Aug 15 '18 at 07:33 PM

avatar image

ekicam2
56 2 4 7

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

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).

  5. 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.");


more ▼

answered Aug 16 '18 at 06:38 AM

avatar image

Amneri
131 3 6 15

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question