C++ GetPawn before Input checks

Hello community.
I am new at Unreal Engine with C++. So I got a newbie question for you.

I Am trying to make my character move in multiplayer and I got this function:

void ACMyPlayerController::OnPossess(APawn* InPawn)
{
	Super::OnPossess(InPawn);

	if (InPawn)
	{
		MyPawn = Cast<ACMyCharacter>(InPawn);
		if (!MyPawn)
		{
			UE_LOG(LogTemp, Warning, TEXT("Possessed pawn is not of type ACMyCharacter"));
		}
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("InPawn is null in OnPossess"));
	}
}

void ACMyPlayerController::EnhancedInputMovement(const FInputActionInstance& Instance)
{
	// My code for movement
	const FRotator ControlRot = FRotator(0,GetControlRotation().Yaw,0);

	const FVector RightMovement = UKismetMathLibrary::GetRightVector(ControlRot);
	const FVector ForwardMovement = UKismetMathLibrary::GetForwardVector(ControlRot);

	const FVector2d inputVector = Instance.GetValue().Get<FVector2d>();

	if(MyPawn)
	{
		MyPawn->AddMovementInput(RightMovement, inputVector.X);
		MyPawn->AddMovementInput(ForwardMovement, inputVector.Y);
	}
}

It does not work unless I change MyPawn for GetPawn() like this:

void ACMyPlayerController::EnhancedInputMovement(const FInputActionInstance& Instance)
{
	// My code for movement
	const FRotator ControlRot = FRotator(0,GetControlRotation().Yaw,0);

	const FVector RightMovement = UKismetMathLibrary::GetRightVector(ControlRot);
	const FVector ForwardMovement = UKismetMathLibrary::GetForwardVector(ControlRot);

	const FVector2d inputVector = Instance.GetValue().Get<FVector2d>();


	GetPawn()->AddMovementInput(RightMovement, inputVector.X);
	GetPawn()->AddMovementInput(ForwardMovement, inputVector.Y);
}

I am trying to get the Pawn outside the input, because isnt it inefficient to call GetPawn() every frame in the input?
I mean getting the pawn from OnPossess works for the server but not for the clients.

I also have this functions if you want more info.

// This function is Reliable and Server side
void ACMyPlayerController::SR_SpawnPlayer_Implementation(ACMyPlayerController* playerController)
{
	if (HasAuthority())
	{
		ACMyGameModeBase* myGameMode = Cast<ACMyGameModeBase>(GetWorld()->GetAuthGameMode());
		if (myGameMode)
		{
			myGameMode->SpawnPlayer(playerController);
		}
	}
}

void ACMyGameModeBase::SpawnPlayer(ACMyPlayerController* PlayerController)
{
	if (!PlayerController)
	{
		UE_LOG(LogTemp, Error, TEXT("PlayerController is null in SpawnPlayer"));
		return;
	}
	
	if (AActor* Pawn = PlayerController->GetPawn())
	{
		PlayerController->UnPossess();
		Pawn->Destroy();
	}

	if (BPPlayerPawn)
	{
		UClass* BPClass = Cast<UClass>(BPPlayerPawn);
		if (BPClass && BPClass->IsChildOf(APawn::StaticClass()))
		{
			if (APlayerStart* RandomPlayerStart = FindRandomPlayerStart())
			{
				FTransform Transform = RandomPlayerStart->GetActorTransform();

				if (APawn* PlayerPawn = GetWorld()->SpawnActor<APawn>(BPClass, Transform))
				{
					PlayerController->Possess(PlayerPawn);
				}
			}
		}
	}
}

Hi, I’m not sure why MyPawn doesn’t work for you, maybe a cast fails there?
But generally you can use GetPawn() if it works for you as this is an inline getter, it doesn’t do any calculations, so it’s pretty much the same as using a variable.

1 Like