SetViewTarget in multiplayer in C++

I’m having trouble with my project.
I want to attach my spring arm camera actor to my player character.
which is done great I think.

but when I set view target to my camera, unreal automatically set view target to player character.

I spawned my camera in my custom controller class’s onpossess event. (RPC through to server. And my custom camera is replicated)
And set view target in on possess event.

Is there certain place to set view target in unreal?
Or how to set view target on start?

Following is my code:

void ADefaultPlayerController::OnPossess(APawn* aPawn)
{
	Super::OnPossess(aPawn);

	Server_SpawnPlayerCamera();

	AActor *PlayerCamera = GetPlayerState<ADefaultPlayerState>()->GetPlayerCamera();
	if (PlayerCamera)
	{
		SetViewTarget(PlayerCamera);

		UE_LOG(LogTemp, Warning, TEXT("SetViewTarget Success : %s"), *GetPlayerState<ADefaultPlayerState>()->GetPlayerCamera()->GetName());
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("GetPlayerCamera Failed."));
	}
}

void ADefaultPlayerController::Server_SpawnPlayerCamera_Implementation()
{
	AActor* OutContextPlayerCamera = nullptr;

	FActorSpawnParameters SpawnInfo;
	SpawnInfo.Instigator = GetInstigator();
	SpawnInfo.ObjectFlags |= RF_Transient;

	UE_LOG(LogTemp, Warning, TEXT("SpawnPlayerCamera"));

	if (APawn* MyPawn = GetPawn())
	{
		FTransform SpawnTransform = FTransform();

		SpawnTransform.SetLocation(MyPawn->GetActorLocation());

		OutContextPlayerCamera = GetWorld()->SpawnActor<AActor>(ADefaultPlayerCamera::StaticClass(), SpawnTransform, SpawnInfo);
		if (OutContextPlayerCamera)
		{
			GetPlayerState<ADefaultPlayerState>()->SetPlayerCamera(OutContextPlayerCamera);
			OutContextPlayerCamera->AttachToActor(GetPawn(), FAttachmentTransformRules(EAttachmentRule::SnapToTarget, EAttachmentRule::KeepWorld, EAttachmentRule::KeepWorld, false));

			UE_LOG(LogTemp, Warning, TEXT("SetPlayerCamera Success : %s, %d"), *GetPlayerState<ADefaultPlayerState>()->GetPlayerCamera()->GetName(), GetPlayerState<ADefaultPlayerState>()->GetPlayerCamera());
		}
		else
		{
			UE_LOG(LogTemp, Error, TEXT("Camera Spawn Failed."));
		}
	}
}

And my code works fine on event tick:

void ADefaultPlayerController::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (HasAuthority()) { return; }
	if (!GetPlayerState<ADefaultPlayerState>()) { return; }

	AActor* PlayerCamera = GetPlayerState<ADefaultPlayerState>()->GetPlayerCamera();
	if (PlayerCamera)
	{
		SetViewTarget(PlayerCamera);

		//UE_LOG(LogTemp, Warning, TEXT("SetViewTarget Success : %s"), *GetPlayerState<ADefaultPlayerState>()->GetPlayerCamera()->GetName());
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("GetPlayerCamera Failed. %d"), GetPlayerState<ADefaultPlayerState>()->GetPlayerCamera());
	}
}

But I think it is not ideal and probably has performance issue.

Sorry for my broken English.

Why are you making the camera be another actor? Make it a component in your Pawn and then when the player controller sets it as view target, it will automatically choose that component.

You just solved my two weeks long problem in few minutes.
Thank you!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.