GetPawn() returns NULL

I am trying tot make my game multiplayer but I can’t get it to work for the clients (it only works for the authoritative player. Unless I run dedicated in which case it obviously works for nobody). The controllers seem to have no Pawn.

This is the code in the controller class:

void APlayerEye_Controller::BeginPlay()
{
	Super::BeginPlay();

	if (IsLocalController()) // This if-check prevents our BeginPlay-code from firing multiple times in multiplayer.
	{
		SpawnAndPossessPlayerEye(this);
		if (GetPawn() == nullptr)
		{
			LOG_ERROR("THE PAWN IS NULL! How can it possibly be null after one was just spawned and possessed?")
		}
	}
}


bool APlayerEye_Controller::SpawnAndPossessPlayerEye_Validate(APlayerEye_Controller* controller) { return true; }
void APlayerEye_Controller::SpawnAndPossessPlayerEye_Implementation(APlayerEye_Controller* controller)
{
	if (controller == nullptr)
	{
		LOG_ERROR("controller is NULL.")
		return;
	}

	// Spawn the PlayerEye.
	FActorSpawnParameters spawnParams;
	spawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
	APlayerEye* newlySpawnedPlayerEye = GetWorld()->SpawnActor<APlayerEye>(APlayerEye::StaticClass(), FVector(-720.0f, -160.0f, 550.0f), FRotator::ZeroRotator, spawnParams);
	if (newlySpawnedPlayerEye != nullptr)
	{
		controller->Possess(newlySpawnedPlayerEye);
		newlySpawnedPlayerEye->AssignPlayerEyeController(controller);
// Note that the above 2 lines are always executed and a Pawn is spawned.
	}
}

I also tried moving the code out of the beginplay and calling it like this (from the GameMode):

void AMyAwesomeGameMode::PostLogin(APlayerController* NewPlayer)
{
	APlayerEye_Controller* playerEyeController = Cast<APlayerEye_Controller>(NewPlayer);
	if (playerEyeController != nullptr)
	{
		AllPlayerControllers.Add(playerEyeController);
		playerEyeController->PostLoginInitialization(); // this method will spawn and possess the pawn now instead of the BeginPlay(). But it also does not work...
	}
}

Sadly the same result. GetPawn() still returns null and no clients have a GUI either. Note that the Pawn is spawned in the map and that the possess-code and all is executed. I don’t get it.

You can handle the OnPossess event in the controller, this event triggers when the controller possesses a pawn.

You should give the server some time before you check if its null because you’re sending a request to the server using the SpawnAndPossessPlayerEye and immediately checking if its null, it might take some time before your client gets updated about the pawn being possessed.
The next step would be to handle the OnPossess event that triggers in the controller when a pawn is possessed.

Glad everything worked for you, I converted the comment to an answer.

Oh I see. But how do I correctly wait for a RPC to finish?

Thanks that did it! Maybe you could post it as an answer because I cannot mark your comments as the answer.

Solution:

void APlayerEye_Controller::Possess(APawn* InPawn)
{
	Super::Possess(InPawn);
	if (GetPawn() != nullptr) { LOG("The pawn is working!") }
}

I’ve had the exact same issue and tried out to override the OnPossess method, but for me it unfortunately did not work :frowning:

Using UE 5.3.2