UE4 C++ - Getting a nullptr in Playercontroller for a variable that is in BeginPlay() and works with variables used by BindAction but not if function is called from another class

Hello all

I have a pointer called “HUDPtr” to a HUD I created in the PlayerController.h. Then I added the “HUDPtr” in the BeginPlay() of the PlayerController.cpp. If I use the SetupInputComponent Keys I have defined and the relative functions the pointer works. But if I call a function from a different class, I see that the function gets executed (I see it in UE_LOGs I used to debug) but in this case I get a nullptr for the “HUDPtr” pointer and the game crashes. Nullptr is shown when I run the game from VS2019 / Debug / Start Debugging.

So summarizing why does the same public “HUDPtr” in the same PlayerController.cpp work in a function when I press a InputKey but not if the function in PlayerController.cpp is called from another class? My understanding would be that if it was in the PlayerController at BeginPlay() the pointer should be valid for all te functions, what am I missing?

Support would be greatly appreciated, thank you!

/** MyPlayerController.h */
#include "MyHUD.h"

UCLASS()
class MyGame_API AMyPlayerController : public APlayerController
{
	GENERATED_BODY()

public:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HUD")
		AMy_HUD* HUDPtr;

	UFUNCTION(BlueprintCallable)
		void BuildingPreview();

protected:
	UFUNCTION()
		void SelectionPressed();
}



/** MyPlayerController.cpp */
void AMyPlayerController::BeginPlay()
{
	if (!HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
	{
		HUDPtr = Cast<MyHUD>(GetWorld()->GetFirstPlayerController()->GetHUD()); // WORKS
	}
}

void AMyPlayerController::SetupInputComponent()
{
	Super::SetupInputComponent();
	InputComponent->BindAction("Select", IE_Pressed, this, AMyPlayerController::SelectionPressed);
}

// THIS WORKS AND “HUDPtr” IS NO NULLPTR!
void AMyPlayerController::SelectionPressed()
{
	if (HUDPtr != nullptr)
	{
		HUDPtr->InitialPoint = HUDPtr->GetMousePos2D();
		HUDPtr->bStartSelecting = true;
	}
}

// THIS DOES NOT WORK AND “HUDPtr” IS A NULLPTR Function is called from below UMyUserWidget.cpp class
void AMyPlayerController::BuildingPreview()
{
	// UE_LOG Works here so I know that the function gets called

	if (HUDPtr != nullptr) // HERE IS WHERE IT CRASHES BUT IT IS NAMED THE SAME AS IN ABOVE FUNCTION “SelectionPressed()”, where it works
	{
		// Do something
	}
}


// THIS IS THE OTHER CLASS FROM WHERE I CALL THE FUNCTION FROM and it works as I see it in the UE_LOG of the “void AMyPlayerController::BuildingPreview()”
/** UMyUserWidget.cpp */
void UMyUserWidget::Button1_Clicked()
{
	if (MyPlayerController != nullptr)
	{
		MyPlayerController->BuildingPreview();
	}
}

HUDPtr = Cast<MyHUD>(GetWorld()->GetFirstPlayerController()->GetHUD());

I’m not sure if this is your issue, but why are you grabbing a different player controller’s HUD here? Each player controller should get a reference to it’s own player controller. Even for a single player game, you should just call GetHUD()

Hello dachora1

Thank you for your reply!
I agree that this does not make a lot of sense since I’m already in the PlayerController.
Unfortunately changing the code to what is shown below, does not change that I get the nullptr lateron.

HUDPtr = Cast(GetHUD());