How to use APlayerController::GetHUD? It always return null

Here is my code.

void AFpsCharacter::ClientRPCInitializeHud_Implementation()
{
	AFpsPlayerController* PlayerController = (AFpsPlayerController*)GetOwner();
	if (IsValid(PlayerController))
	{
		AFpsPlayerState* State = PlayerController->GetPlayerState<AFpsPlayerState>();
		UE_LOG(LogTemp, Log, TEXT("PlayerController now on %s"), *State->GetPlayerName());
		HUD = (AFpsHud*)PlayerController->GetHUD(); //AHUD* HUD in AFpsCharacter.
		//HUD = Cast<AFpsHud>(PlayerController->GetHUD());
		if (!IsValid(HUD))
		{
			UE_LOG(LogTemp, Log, TEXT("AFpsCharacter::InitializeHud() : HUD is not valid"));
		}
	}
	else
	{
		UE_LOG(LogTemp, Log, TEXT("PlayerController is not exist"));
	}
}

The function ClientRPCInitializeHud() is run when the character is spawned and PlayerController possess it. My problem is the pointer HUD has invalid value. Of course i checked default HUD of GameMode. What can i do for get valid value of APlayerController::GetHUD?

I just follow the step below to run ClientRPCInitializeHud.

  1. Run PlayerController’s function on button event in Widget Blueprint .
  2. Run ServerRPCSpawnAsPlayableCharacter function
  3. Run ClientRPCInitializeHud function after call APlayerController::Possess(SpawnedCharacter).

Here is the code.

void AFpsPlayerController::OnSelectedTeam(EPlayerTeam team, TSubclassOf<class AFpsCharacter> CharacterClass, FTransform SpawnTransform)
{
	ServerRPCSetTeam(team);
	ServerRPCSpawnAsPlayableCharacter(CharacterClass, SpawnTransform);
}

void AFpsPlayerController::ServerRPCSpawnAsPlayableCharacter_Implementation(TSubclassOf<AFpsCharacter> CharacterClass, FTransform SpawnTransform)
{
	FActorSpawnParameters SpawnParameters;
	AFpsCharacter *SpawnedCharacter = GetWorld()->SpawnActor<AFpsCharacter>(CharacterClass, SpawnTransform.GetLocation(), SpawnTransform.GetRotation().Rotator(), SpawnParameters);
	SpawnedCharacter->SetSpawnTransform(SpawnTransform);
	Possess(SpawnedCharacter);
	SpawnedCharacter->OnPossess();
}

void AFpsCharacter::OnPossess()
{
	ClientRPCInitializeHud();
}

I tried to check GetPlayerController(0)->GetHUD is valid or not if is called at Level Blueprint or Widget Blueprint but it is also invalid.

AFpsPlayerController* PlayerController = (AFpsPlayerController*)GetOwner();

Maybe try GetController() instead?

I tried all for getting PlayerController and it’s always vaild. I can see the log “AFpsCharacter::InitializeHud() : HUD is not valid” and it is with if(IsValid(PlayerController)).

turn your cast into

if (auto PC = Cast<AFpsPlayerController>(GetController()) {

}

To see if it is proper class. IsValid only checks pointer validity.

I already tried it. Other function of PlayerCharacter is working well. Of course it’s the same result with my code. And the problem is still happend. APlayerController::GetHUD doesn’t work. I can check the same problem at both that i use Cast<AFpsPlayerController>(GetOwner()) or (AFpsPlayerController*)GetOwner().

GetOwner() != GetController()

But if you are so stubborn to keep using GetOwner() then I won’t help you anymore.

I think you don’t understand my comment. Maybe because of my English skill. I said i tried. And i said the problem is still happend. It means i tried using GetController(). And it means i also tried Cast<AFpsPlayerController>(GetController()) and (AFpsPlayerController*)GetController(). Of course i tried exactly the same code with your code. Thank you for your comment. By the way i think you don’t need to be rude. So stubborn? Is here the Colosseum or what.

I guess the problem is the default HUD instance isn’t created by default HUD class of GameMode. I don’t know well why it is happened even i checked default HUD class in GameMode. So i choose temporary solution. Using APlayerController::ClientSetHUD(TSubclass<AHUD>). In my case, each ACharacter has TSubclassOf<AHUD> and run APlayerController::ClientSetHUD(TSubclass<AHUD>) at APlayerController::OnPossess(APawn* InPawn).