Retreiving a reference to Player Pawn/Character from C++ Player Controller

How would I retreive a non-null reference to a player character/pawn from a C++ Player Controller? I am using GameMode for possession of pawns.

I have tried using GetPawn() during both BeginPlay() and BeginPlayingState() and casted them using Cast() and I keep getting a null reference. As far as I’m aware this is because the possession of the pawn has not yet occured. Do I need to stall or use a timer or is there any specific event where I can guarantee the pawn has been possessed (assuming a valid class has been set in GameMode)?

// Copyright ©2015 Austin R. Snider and Brandon L. Snider; do not copy modify or distribute without permisson. 
#pragma once

#include "GameFramework/PlayerController.h"
#include "PlayerCharacter.h"
#include "DragonsLairPlayerController.generated.h"


/**
 * 
 */
UCLASS()
class DRAGONSLAIR_API ADragonsLairPlayerController : public APlayerController
{
	GENERATED_BODY()
private:

 //parts omitted

	void MoveForwardAxis(float AxisValue);
	void MoveSideAxis(float AxisValue);
	void LookVertical(float AxisValue);
	void LookHorizontal(float AxisValue);
	void LeftInteract(float AxisValue);
	void RightInteract(float AxisValue);

	void SwitchItem1();
	void SwitchItem2();
	void SwitchItem3();

	void SwitchPreviousItem();
	void SwitchNextItem();

	void UseItem();
	void UseShield();
	void Interact();

	APlayerCharacter* PlayerCharacterRef;
	UCameraComponent* PlayerCameraRef;

public:
	ADragonsLairPlayerController(const FObjectInitializer& ObjectInitializer);
	virtual void BeginPlayingState() override;
	virtual void SetupInputComponent() override;

	
};


// Copyright ©2015 Austin R. Snider and Brandon L. Snider; do not copy modify or distribute without permisson. 
#include "DragonsLair.h"
#include "DragonsLairPlayerController.h"
#include "Engine.h"


ADragonsLairPlayerController::ADragonsLairPlayerController(const FObjectInitializer& ObjectInitializer)
{
	
}

void ADragonsLairPlayerController::BeginPlayingState()
{
	Super::BeginPlayingState();
	
	if (Cast<APlayerCharacter>(GetPawn())) PlayerCharacterRef = Cast<APlayerCharacter>(GetPawn());
	else
	{
	}

	PlayerCameraRef = PlayerCharacterRef->PlayerCameraRef;

}

void ADragonsLairPlayerController::SetupInputComponent()
{
	Super::SetupInputComponent();
	InputComponent->BindAxis("MoveForwardAxis", this, &ADragonsLairPlayerController::MoveForwardAxis);
	InputComponent->BindAxis("MoveSideAxis", this, &ADragonsLairPlayerController::MoveSideAxis);
	InputComponent->BindAxis("LookVertical", this, &ADragonsLairPlayerController::LookVertical);
	InputComponent->BindAxis("LookHorizontal", this, &ADragonsLairPlayerController::LookHorizontal);
	InputComponent->BindAxis("LeftInteract", this, &ADragonsLairPlayerController::LeftInteract);
	InputComponent->BindAxis("RightInteract", this, &ADragonsLairPlayerController::RightInteract);
	InputComponent->BindAction("SwitchItem1", IE_Pressed, this, &ADragonsLairPlayerController::SwitchItem1);
	InputComponent->BindAction("SwitchItem2", IE_Pressed, this, &ADragonsLairPlayerController::SwitchItem2);
	InputComponent->BindAction("SwitchItem3", IE_Pressed, this, &ADragonsLairPlayerController::SwitchItem3);
	InputComponent->BindAction("SwitchPreviousItem", IE_Pressed, this, &ADragonsLairPlayerController::SwitchPreviousItem);
	InputComponent->BindAction("SwitchNextItem", IE_Pressed, this, &ADragonsLairPlayerController::SwitchNextItem);
	InputComponent->BindAction("UseItem", IE_Pressed, this, &ADragonsLairPlayerController::SwitchItem1);
	InputComponent->BindAction("UseShield", IE_Pressed, this, &ADragonsLairPlayerController::SwitchItem2);
}

void ADragonsLairPlayerController::MoveForwardAxis(float AxisValue)
{
	if (PlayerCharacterRef != nullptr)
	{
		FVector CharacterForwardVector = PlayerCharacterRef->GetActorForwardVector();
		FVector MovementInputVector = CharacterForwardVector * PlayerCharacterRef->MovementSpeed;
		PlayerCharacterRef->AddMovementInput(MovementInputVector, AxisValue);
	}
}

void ADragonsLairPlayerController::MoveSideAxis(float AxisValue)
{
	if (PlayerCharacterRef != nullptr)
	{
		FVector CharacterRightVector = PlayerCharacterRef->GetActorRightVector();
		FVector MovementInputVector = CharacterRightVector * PlayerCharacterRef->MovementSpeed;
		PlayerCharacterRef->AddMovementInput(MovementInputVector, AxisValue);
	}
}

void ADragonsLairPlayerController::LookVertical(float AxisValue)
{

	if (PlayerCharacterRef != nullptr)
	{
		FRotator DeltaRotation = FRotator(AxisValue, 0.0f, 0.0f);
		PlayerCameraRef->AddLocalRotation(DeltaRotation);
	}
}

void ADragonsLairPlayerController::LookHorizontal(float AxisValue)
{
	if (PlayerCharacterRef != nullptr)
	{
		FRotator DeltaRotation = FRotator(0.0f, AxisValue, 0.0f);
		PlayerCharacterRef->AddActorLocalRotation(DeltaRotation);
	}
	else 
	{
		PlayerCharacterRef = Cast<APlayerCharacter>(GetPawn()); 
	}
}

AYourCharacter* Pawn = Cast(GetCharacter());

GetCharacter() not GetPawn(), it will work :)))

AYourCharacter* Pawn = Cast(GetCharacter());

GetCharacter() not GetPawn(), it will work :)))

Already tried it, still doesn’t work. I think my problem may be elsewhere because a spectator keeps being spawned by the GameMode instead of my an instance of PlayerCharacter (meaning Q and E raise and lower the camera even though I haven’t defined and Q and E inputs in my project). Any ideas what can cause this?

Yes if you have a function or call to spawn the spectator on death or after death as this is not normally inherited and should not be caused by your player controller.

Again unless you specified your player controller to spawn a pawn again.

UGameplayStatics::GetPlayerChracter(const UObject * WorldContextObject, int32 PlayerIndex);

where WorldContextObject is usually this (a pointer to object it is called from) and PlayerIndex is usually 0. It will work if player posesses a APlayer or child class object, and not a Pawn.

You put 2 times this answer.