Camera and Spring Arm component within PlayerController?

Hi all,

I currently have many actors on screen, only one of which can be controller by the player. As such, I am trying to move away from the default model, which is built upon the topdown template, by moving the camera and spring arm components onto my controller which is derived from Playercontroller. This should improve performance as I no longer have dozens of unused cameras!

Has anyone been able to achieve this? I have currently simply moved the two components, the camera and the spring arm, into my playercontroller rather than the character. Unfortunately this didnt work. When I boot the game, the camera seems to be embedded within my character. The camera faces the correct direction, but it is as though the spring arm has a permanent length of zero. The moving works, but i cannot zoom out.

What is the correct method of initializing these components so that i can keep them entirely within the controller?

Here is my current way within my controller:

void ARoguelikePlayerController::BeginPlay()
{
 APlayerController::BeginPlay();

 ARoguelikeCharacter* character =  Cast<ARoguelikeCharacter>(this->GetCharacter());

 CameraBoom = NewObject<USpringArmComponent>(character, TEXT("CameraBoom"));
 CameraBoom->bAbsoluteRotation = true;
 CameraBoom->TargetArmLength = 950;
 CameraBoom->RelativeRotation = FRotator(-60.f, 0.f, 0.f);
 CameraBoom->bDoCollisionTest = false;
 CameraBoom->AttachTo(character->GetRootComponent());
 CameraBoom->Activate();

 TopDownCameraComponent = NewObject<UCameraComponent>(character, TEXT("TopDownCamera"));
 TopDownCameraComponent->bUseControllerViewRotation = false; 
 TopDownCameraComponent->AttachTo(CameraBoom, USpringArmComponent::SocketName);
 TopDownCameraComponent->Activate();

 SetViewTarget(character);
}

If you want to look through the camera of your player controller, you will have to know this about how the player controller manages the active camera.

First of all, a player controller at all times has a “view target”. This is the actor that will be used to look from. Default behavior makes the currently possessed pawn the view target, and the player controller itself if its not controlling any pawn at the moment. This behavior can be turned off if you uncheck the player controller variable bAutoManageActiveCameraTarget in your player controller BP or C++ class.

Secondly, the camera that will be used given a view target. If an actor has one or more camera components, the first active one will be used to look from. If none is available, the actor’s origin and rotation will be used as camera orientation.

In your case, I assume bAutoManageActiveCameraTarget is still checked because its the default value. So what happens then is your pawn becomes the view target. Since it has no camera component (you removed it), you’ll look from the actor’s origin. I believe if you uncheck bAutoManageActiveCameraTarget, the view target will stay the player controller even after possessing the pawn. If the player controller has a camera, then that will dictate the view orientation. Be sure to check the player controller’s bAttachToPawn setting too, otherwise your controller will stay at (0, 0, 0) and not follow the pawn.

Thanks for the swift response Zhi. I will try out the AttachToPawn bool when home later. However, the AutoManageActiveCameraTarget bool is already set to false in the constructor for the controller.

It would appear the camera mostly works. It moves when i move the character, and I can rotate it. The issue is that it is always inside the character - the same result you would see if you set the spring arms’ length to 0, hence I assume the spring arm is the issue? If i put a break point on at any time, i can see the length is not 0 and is correct, but that doesnt seem to fix the issue.

Looking at your code again, it seems I misinterpreted the way you want to set your camera up, sorry. I assumed you wanted to use your player controller as a view target, but I see now that you still want your character as view target, but set the camera up from inside the player controller code. Then the controller’s bAttachToPawn value is irrelevant, so is bAutoManageActiveCameraTarget, because in the end you want your character to be the view target anyway.

Perhaps this would help you debug your issue. Just start play in editor, then press Pause and Eject so that you can use the editor viewport for editing. Select your character and then select the CameraBoom or TopDownCamera to see if the camera is positioned correctly. Specifically check if the arm (red line) is where you expect it to be and whether the camera is at the end of it. That may give some new info.

Hi Zhi, I’ve just managed to take another look. When I pause and eject, I cannot seem to find my camera in the scene. Within code it is there and exists, but selecting the character reveals no camera nor arm, and I can’t find either in the list of scene objects

Apologies - I can see it in the object tree if I select my character - but it is not visible within the actual scene

Hey uh did you ever find a solution to this? I am facing the exact same problem XD

I just found my solution: attach the springarm to the new pawn, but do not call SetViewTarget