I have a playercontroller that cycles through some states on a dedicated server, as below:
.h
UENUM()
enum class PlayState
{
None,
Frontend,
Playing,
GameOver
};
UCLASS()
class ASTEROIDS_API AMyPlayerController : public APlayerController
{
GENERATED_BODY()
public:
AMyPlayerController();
virtual void BeginPlay() override;
void SetPlayState(PlayState newState);
PlayState GetPlayState() { return CurrentState; }
UFUNCTION()
void OnRep_PlayState();
protected:
UPROPERTY(Replicated, ReplicatedUsing = OnRep_PlayState)
PlayState CurrentState;
}
.cpp
void AMyPlayerController::BeginPlay()
{
Super::BeginPlay();
//[Server]
if (Role == ROLE_Authority)
{
// Server sets state, which is then replicated to clients
SetPlayState(PlayState::Frontend);
}
}
void AMyPlayerController::SetPlayState(PlayState newState)
{
if (Role < ROLE_Authority)
{
// [All Clients]
// HUD only on clients
AMyHUD *pHUD = Cast<AMyHUD>(GetHUD()); // <- NULLPTR on client on first call
if (pHUD)
{
// Change hud
}
}
CurrentState = newState;
}
void AMyPlayerController::OnRep_PlayState()
{
SetPlayState(CurrentState);
}
void AMyPlayerController::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyPlayerController, CurrentState);
}
Essentially, it sets the state on the server side (in BeginPlay), and then replicates to the clients via void AMyPlayerController::OnRep_PlayState();
This works fine, however, when the first call to change the HUD in SetPlayState(PlayState newState) always returns a nullptr for the HUD.
As a test I added a Tick(float dt) func:-
void AMyPlayerController::Tick(float deltaTime)
{
Super::Tick(deltaTime);
if (Role == ROLE_Authority)
{
if(GetPlayState() != PlayState::Playing)
SetPlayState(PlayState::Playing);
}
}
To test subsequent state changes, and then a valid HUD pointer is returned and the HUD appears.
Is there some delay in HUD creation? I would have expected it to be valid at BeginPlay(), but doesn’t appear to be.
Is there a better hook point to set the initial state when the HUD ptr within the playercontroller (client side) is valid?
(Hope that makes sense) :S