Download

3rd Person Spectate ShooterGame

I’m trying to implement 3rd person spectating where the spectator can pan around the character while keeping them in the center of their view/orbit.

Looking at ShooterGame’s AShooterPlayerControll I see I could use ClientSetSpectatorCamera(CameraLocation, CameraRotation); to set the raw location/Rotation values. Should I capture the mouse movement and calculate the camera’s new location and rotation and set it with this function or might there be a better way using a boom or something?

There is a component (SpringArm) you can use, it can help you, but I think you must create the rotation code (which should be easy).
Simply make a connection vector between the camera and the character, rotate it along the axes your mouse says you should and convert it back to a roll-less rotation again.

Hey thanks for that. I ended up lifting the CameraBoom code from the Third Person template. My AShooterSpectatorPawn is pasted below

Now, if I want to spectate a ShooterCharacter in 3rd person, I’ll set the location of my SpectatorPawn to that of a ShooterCharacter and change the CameraBoom length to 300.0f. I also had to make sure that Camera collision was ignored for both the BotPawn and PlayerPawn in the ShooterGame blueprints for this to work correctly. If the client exits third person spectate and goes back to free roam I set the CameraBoom length back to 0.0f.



// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.


#include "ShooterGame.h"
#include "ShooterSpectatorPawn.h"

AShooterSpectatorPawn::AShooterSpectatorPawn(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{	
	// set our turn rates for input
	BaseTurnRate = 45.f;
	BaseLookUpRate = 45.f;

	// Don't rotate when the controller rotates. Let that just affect the camera.
	bUseControllerRotationPitch = false;
	bUseControllerRotationYaw = false;
	bUseControllerRotationRoll = false;

	// Create a camera boom (pulls in towards the player if there is a collision)
	CameraBoom = PCIP.CreateDefaultSubobject<USpringArmComponent>(this, TEXT("CameraBoom"));
	CameraBoom->AttachTo(RootComponent);
	CameraBoom->TargetArmLength = 0.0f; // The camera follows at this distance behind the character	
	CameraBoom->bUseControllerViewRotation = true; // Rotate the arm based on the controller

	// Create a follow camera
	FollowCamera = PCIP.CreateDefaultSubobject<UCameraComponent>(this, TEXT("FollowCamera"));
	FollowCamera->AttachTo(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
	FollowCamera->bUseControllerViewRotation = false; // Camera does not rotate relative to arm
}

void AShooterSpectatorPawn::SetupPlayerInputComponent(UInputComponent* InputComponent)
{
	check(InputComponent);
	
	InputComponent->BindAxis("MoveForward", this, &ADefaultPawn::MoveForward);
	InputComponent->BindAxis("MoveRight", this, &ADefaultPawn::MoveRight);
	InputComponent->BindAxis("MoveUp", this, &ADefaultPawn::MoveUp_World);
	InputComponent->BindAxis("Turn", this, &AShooterSpectatorPawn::AddControllerYawInput);
	InputComponent->BindAxis("TurnRate", this, &AShooterSpectatorPawn::TurnAtRate);
	InputComponent->BindAxis("LookUp", this, &AShooterSpectatorPawn::AddControllerPitchInput);
	InputComponent->BindAxis("LookUpRate", this, &AShooterSpectatorPawn::LookUpAtRate);
}

void AShooterSpectatorPawn::SwitchToThirdPerson()
{
	CameraBoom->TargetArmLength = 300.0f;
}

void AShooterSpectatorPawn::SwitchToFreeRoam()
{
	CameraBoom->TargetArmLength = 0.0f;
}

void AShooterSpectatorPawn::TurnAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
}

void AShooterSpectatorPawn::LookUpAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}