x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to move the CameraComponent into PlayerController

Hello,

until now I added an UCameraComponent to the character class the way it was done in the TPSTemplate or in the battery tutorial, I am not sure. I just added a UCameraComponent to the character, and it was selected and used - I have absolutely no idea why, it was a local component variable I created.

Now I try to move the camera to an own PlayerController class, as it should be attached to the player, not to the character. (The possessed pawn can change and I don't want every MyCharacter instance to have a camera - it is used for npc-s as well). However I failed to activate it.

This is how I tried:

 // MyPlayerController.h
 /** Camera boom positioning the camera behind the character */
 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
 class USpringArmComponent* CameraBoom;
 
 /** Follow camera */
 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
 class UCameraComponent* FollowCamera;
 
 
 // MyPlayerController.cpp
 AMyPlayerController::AMyPlayerController()
 {
     CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
 
     FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
     FollowCamera->bUsePawnControlRotation = false;
 
 }
 
 
 void AMyPlayerController::BeginPlayingState()
 {
     CameraBoom->AttachTo(GetControlledPawn()->GetRootComponent());
     CameraBoom->TargetArmLength = 300.0f;
     CameraBoom->bUsePawnControlRotation = true;
 
     FollowCamera->AttachTo(CameraBoom, USpringArmComponent::SocketName);
     FollowCamera->bUsePawnControlRotation = false;
 
     SetViewTarget( this );
 }

If I start the game I have the same default camera I would without this extra code. Any idea what's wrong or how to achieve my goal?

Thanks,

Elathan

Product Version: UE 4.8
Tags:
more ▼

asked Jun 15 '15 at 06:02 PM in C++ Programming

avatar image

Elathan
406 22 27 59

avatar image Matthew J ♦♦ STAFF Jun 15 '15 at 07:56 PM

Hi Elathan,

I don't have much experience with this particular issue myself but by the name of the function that sets the boom's attachment (BeginPlayingState) it seems like something that is only being run once throughout the game instance. If this isn't run again after possession has changed, the camera will stay attached to the original character.

Otherwise, can you provide the rest of your game code or your blueprints to show where these functions are being called so that I can get more context surrounding the issue?

avatar image Elathan Jun 15 '15 at 08:18 PM

Thanks for your answer.

Unfortunately I am sure that BeginPlayingState is called properly after the pawn is possessed. ( It is a function defined and called by PlayerController.) I use this same thing to setup functions for input binding on the same character.

MyPlayerController header: http://pastebin.com/UqrPJqs9

MyPlayerController cpp: http://pastebin.com/mQYR03Gr

I am not even sure if the camera defined in my PlayerController is active or not. I'll try to find a way to find out that first.

Edit: modifying the camera defined in my PlayerController doesn't have any effect - I think it is not used.

avatar image Elathan Jun 15 '15 at 08:45 PM

The Possess(...) function in PlayerController will call SetViewTarget( ... ) with the possessed pawn. It was called after BeginPlayingState, so my SetViewTarget() was overwritten.

But it is still not good unfortunately - now I override the Possess function in my PlayerController, call it's parent first, then ViewTarget(this).

The position of the camera is different now, so it is called correctly, but it still doesn't use the CameraComponent I declared and defined in my PlayerController. There must be a way to bind the component and the controller, or?

I tried to find the answer in the source code, but without success so far.

According to the documentation:

"The CameraComponent allows you to add a camera perspective as a sub-object to an Actor. The CameraComponent will provide information about the camera's properties if the ViewTarget is a CameraActor or an Actor that contains a CameraComponent and has its bFindCameraComponentWhenViewTarget option set to True. "

Well, bFindCameraComponentWhenViewTarget doesn't really modify anything.

avatar image Matthew J ♦♦ STAFF Jun 15 '15 at 09:18 PM

I'm not seeing any reasons as to why this wouldn't work from the information provided. Would it be possible for you to upload the project itself? If it won't fit on Answerhub, or you wish for it to be private, you can upload it to Dropbox or another third party hosting site and link it either here or to me on the forums in a private message. If you wish to do the private message route, my forum username is matthew_clark. It would be very useful to be able to tinker around with the code and the blueprints that you're using to attempt to find the issue.

avatar image Elathan Jun 15 '15 at 09:27 PM

It seems to me that the PlayerControllers aren't compatible with CameraComponents - I did not expect that. I found the problem (but not a solution : ( ), see my answer below.

(comments are locked)
10|2000 characters needed characters left

1 answer: sort voted first

Well, the PlayerController component overwrites the function which is used by the Actor class instances to get the data from the camera component.

 void APlayerController::CalcCamera(float DeltaTime, FMinimalViewInfo& OutResult)
 {
     OutResult.Location = GetFocalLocation();
     OutResult.Rotation = GetControlRotation();
 }

An other Actor here would search for camera component if bFindCameraComponentWhenViewTarget is set. I suppose it's not a bug but a feature, but... I don't really see why can't this work in the same way it does with other actors.

I suppose there isn't a reasonable way to store a CameraComponenet in the PlayerController then.

more ▼

answered Jun 15 '15 at 09:24 PM

avatar image

Elathan
406 22 27 59

avatar image Elathan Jun 15 '15 at 10:05 PM

I can override the CalcCamera(...) in my PlayerController, and call the Actor's implementation. I am closer to the desired result, but something is still wrong (maybe with the cameraboom, I am just too close to the target, I suppose it doesn't have it's effect on it). It was enough for me for today, I'll try to fix this tomorrow.

avatar image Elathan Jun 15 '15 at 10:26 PM

I just couldn't sleep without solving this thing :P

I think the problem was the following: because the USpringArmComponent wasn't the part of the actor it detected its collision, so it went close to the center, the same way it would if the owner would be too close to a wall.

I moved the USpringArmComponent to the Character class, the camera stayed in the PlayerController class.

Also, I don't call the actor's CalcCamera - I do the same in a more efficient way, without searching for the camera instead:

 void AShPlayerController::CalcCamera(float DeltaTime, struct FMinimalViewInfo& OutResult)
 {
     FollowCamera->GetCameraView(DeltaTime, OutResult);
 }


I hope everything will work fine now and that this thread will be useful for others as well.

avatar image haimat Sep 17 '18 at 11:53 PM

I don't get it: Even with the following code in my custom player controller neither the camera's location nor rotation does change:

 void ATycoonPlayerController::BeginPlay()
 {
     SetViewTarget(this);
 }
 void ATycoonPlayerController::CalcCamera(float DeltaTime, FMinimalViewInfo& OutResult)
 {
     const FVector camLoc(-270.0f, 270.0f, 400.0f);
     const FRotator camRot(0.0f, -70.0f, 0.0f);
 
     OutResult.Location = camLoc;
     OutResult.Rotation = camRot;
     OutResult.FOV = 90.0f;
 }

What am I missing?

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question