Camera management in C++

Like you, I wanted a floating camera as seen in the StrategyGame example. I also looked at the Top Down Shooter example as well and I managed to get something working before moving on. It’s something I need to go back and have a proper look at along with my HUD and viewport in general. I think I could only get it to work with a CameraBoom but you can try the following for now: -

SpectatorPawn.cpp Constructor


	YourCameraComponent = ObjectInitializer.CreateDefaultSubobject<UYourCameraComponent>(this, TEXT("YourCameraComponent"));
	// Create a camera boom...
	CameraBoom = ObjectInitializer.CreateDefaultSubobject<USpringArmComponent>(this, TEXT("CameraBoom"));
	CameraBoom->AttachTo(RootComponent);
	CameraBoom->bAbsoluteRotation = true; // Don't want arm to rotate when character does
	CameraBoom->TargetArmLength = 0.0f
	CameraBoom->bDoCollisionTest = false; // Don't want to pull camera in when it collides with level

	// Create a camera...
	YourCameraComponent->AttachTo(CameraBoom, USpringArmComponent::SocketName);


YourCameraComponent.cpp


void UYourCameraComponent::GetCameraView(float DeltaTime, FMinimalViewInfo& OutResult)
{
	APlayerController* Controller = GetPlayerController();
	if (Controller)
	{
		if (bRotateCameraEnabled)
		{
			Controller->GetInputMouseDelta(DeltaX, DeltaY);
			CameraAngle.Add(DeltaY*RotateSpeed, DeltaX*RotateSpeed, 0.0f);
		}
		OutResult.FOV = 30.f;
		const float CurrentOffset = MinCameraOffset + ZoomAlpha * (MaxCameraOffset - MinCameraOffset);
		FVector Pos2 = Controller->GetFocalLocation();
		OutResult.Location = Controller->GetFocalLocation() - CameraAngle.Vector() * CurrentOffset;
		OutResult.Rotation = CameraAngle;
	}
}


The extra item I added was the ability to rotate the camera whenever the MMB was pressed which triggers the bRotateCameraEnabled flag. The other thing I modified was the MoveForward function within the SpectatorPawn class by zeroing the Z-axis to stop the camera moving “forward” into the ground: -


void AYourSpectatorPawn::MoveForward(float Val)
{
	APlayerController* Controller = GetPlayerController();
	if (Controller != NULL)
	{
		if (Val != 0.f)
		{
			// Find camera angle
			const FRotationMatrix R(Controller->PlayerCameraManager->GetCameraRotation());
			// Get a vector relative to the camera angle
			FVector WorldSpaceAccel = R.GetScaledAxis(EAxis::X) * 100.0f;
			// We only want the X and Y values and not change the camera height
			WorldSpaceAccel[2] = 0.0f;
			// Transform to world space and add it
			AddMovementInput(WorldSpaceAccel, Val);
		}
	}
}


One of the things I do need to add at some point is boundaries to stop the camera going below the ground or “over the top”. This is probably not the best way, but it seems to work for me for now using the WASD to move around, mouse wheel to zoom, and MMB to rotate… I’ll be interested in seeing other people’s methods for doing this.