Attaching a Camera to Pawn from Controller

In the game I am working on I want the player to be able to possess any NPC in the game. However, I’d rather not have a camera component attached to EVERY character. It clutters the scene and I’d rather the character controller attach and detach a camera component dynamically.

I tried creating the camera component on the controller and attaching it to the character when the game starts, but the view is always wrong (appearing from the groin of the character) rather than over the shoulder where it should be. I’ve tried overloading the Calculate View function on the Pawn (and the controller I think) with the same result. When I create the camera component on the Pawn however it picks it up just fine. I am currently using the Third Person tutorial setup with a spring arm that can zoom in and out of First Person mode.

You can achieve this by getting a CameraManager class that will be tied to your Controller.
This way, whatever you’ll be “possessing” you’ll keep the same viewpoint.

Hi Creasso,

I’ll look into using the CameraManager. I had miss read some information on it involving subclassing. Hopefully this will work.

I attempted to Setup the Custom Camera Manager but the concepts are a bit foreign to me. I Setup the system with three classes: CustomCharacter, CustomPlayerController, and CustomCameraManager. I then moved the camera and the camera boom onto the CustomPlayerController and set the CameraManagerClass equal to the CustomChameraManager class. At Begin Play I attached the Boom to the Root Component of the Character and overrode the function “UpdateViewTarget” to find and use the Camera attached but I am still getting the “crotch view” instead of the over the shoulder view.

I finally did figure this out and a partial solution can be found on my other post: Setup A Dynamic Camera Third Person Camera

The key to the solution was to create a new USpringArmComponent I called UAssignableSpringArmComponent which overrode the the UpdateDesiredSpringArm function to perform a sweeping trace but ignore a specifically assigned Pawn rather than the Owner of the spring arm. Because the USpringArmComponent was not owned by the Pawn, it was colliding with the pawn and changing the arm length because of the collision. The function was copied mostly from the documentation with the key line of the sweep changed to:

AActor* ignoreActor = NULL;
if(this->attachedPawn != NULL)
{
    ignoreActor = this->attachedPawn;
}
else
{
    ignoreActor = this->GetOwner();
}
FCollisionQueryParams QueryParams(TraceTagName, false, ignoreActor);

The next thing I had to do is derive a CameraManager to basically use the camera attached to the player controller instead of the pawn. I overrode the UpdateViewTarget function, changing the key segment of code as described in my answer on Setup A Dynamic Third Person Camera. Basically instead of looking for a Pawn, the UpdateViewTarget looks for the Camera on my CustomController and and if it finds it, it uses that camera, other wise it performs the default UpdateViewTarget function.

Hello I have been trying to implement your approach, and I got stuck on this line of code if(this->attachedPawn != NULL). Where do I have to initialize attachedPawn? I have a function like this

void UArmComponent::SetAttachedActor(AActor* NewAttachedActor)
{
attachedPawn = NewAttachedActor;
}

And and I do not call it. I do not know where and when.

Oh wow, I sort of forgot I tried this once.

However to answer your question I was calling SetAttachedPawn from the PlayerController::Possess(inPawn) and PlayerController::Unpossess()

I have found that in Replication/multiplayer managing camera systems is a bit tricky. Just an FYI.

Unfortunately I found some other issues with the above approach but have since figured out a much better way to achieve this (at least in my opinon). Even though the documentation says not to subclass the Camera Manager, I now subclass the camera manager. The camera manager keeps pointers to a SpringArm and A CameraComponent that is null at first. Then during play it checks if the camera system is initialized, and if it is not it builds the camera system dynamically. Now the camera manager is responsible for building and destroying the camera system, This also allows me to leverage the camera system for building different camera setups such as First Person and Third Person Perspectives with out spreading the code throughout the PlayerController and the Pawn. Just cleaner.

I also now realize I should update my old answewr :slight_smile: thanks.

You never know what is going to bite your in the a** :slight_smile: Anyway, thank you your answer has cleared some aspects. In your previous answers you said I Setup the system with three classes: CustomCharacter, CustomPlayerController, and CustomCameraManager. I then moved the camera and the camera boom onto the CustomPlayerController a specially I then moved the camera and the camera boom onto the CustomPlayerController So CustomPlayerController did not have a camera and a boom since you had moved it to The camera manager keeps pointers to a SpringArm and A CameraComponent that is null at first or The camera manager keeps only pointers as you said, and the controller keeps an instance of them?