c++unreal-engine4

UE4 C++ APlayerController::GetHUD 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.


Solution

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