How can I get GetSpectatorPawn() to work?

Hello.

I have a problem with GetSpectatorPawn(). I’ve created a camera like in Strategy Game Sample, but it doesn’t work as expected. I belived it’s caused by the problem in movement component’s TickComponent() function. I obtain player pawn like in Strategy Game Sample:

ATowerDefensePlayerController* PlayerController = Cast<ATowerDefensePlayerController>(PawnOwner->GetController());
AWaveDefensePlayerPawn* PlayerPawn = Cast<AWaveDefensePlayerPawn>(PlayerController->GetSpectatorPawn());

But PlayerPawn is always NULL (Propably because PlayerController->GetSpectatorPawn() returns NULL). How to make it work? :smiley:

I had the same issue, but this forum thread cleared it up for me.

The reason GetPawn() works and GetSpectatorPawn() works is because they are dependent on the state of the PlayerController: Playing, Spectating, Inactive. Look at the comment for GetSpectatorPawn():

/** Get the Pawn used when spectating. NULL when not spectating. */

So in this case, you are currently in the “playing” state, but the pawn classes happen to be the same for both playing and spectating in your case.

By default the PC starts in the spectator state but immediately changes to playing at the start of the game. If you want to always spectate you can force it by setting it on the PlayerState using bOnlySpectator. Look at the APlayerController::Reset() function to see how that is handled (changes the bIsPlayerWaiting flag, which allows spectators to transition to playing).

This stuff probably warrants some cleanup on our end, but for now hopefully this gets you moving forward!

In short, you can fix the problem by overriding the Reset function:

void AMyPlayerController::Reset()
{
	Super::Reset();

	PlayerState->bOnlySpectator = true;
}

I’m still not clear on how this works in the strategy game sample, since it doesn’t do this, but this fix worked for me.

Just to clarify Strategy Game Sample. It works without putting player in Playing state, because they have
AStrategyGameMode::RestartPlayer override, which doesn’t call Super::RestartPlayer, and in turn AGameModeBase::RestartPlayer calls AGameModeBase::RestartPlayerAtPlayerStart and there is a logic which spawns default pawn, which happens if you don’t override RestartPlayer or do call Super::RestartPlayer, but doesn’t happend in StrategyGameMode.

I think it’s rather inconsistant example, because their PlayerState is always in bIsSpectator = false, while controller runs around rampaging with spectatorpawn :-).