I’m trying to call a function for attaching an already created camera to the calling pawn, but I can’t even find the camera in the scene. The UCameraComponent is a static member of the MyPlayerController class.
This is what I do in the constructor:
PlayerCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("PlayerCamera"));
And this is the function that is called by the pawn (after the pawn’s BeginPlay() method is called):
void AMyPlayerController::SetCurrentPawn(AMyPawn* Pawn)
{
if (PlayerCamera && Pawn && Pawn->CameraSpringArm)
{
CurrentPawn = Pawn;
PlayerCamera->AttachTo(Pawn->CameraSpringArm);
//UCameraComponent* C = CreateDefaultSubobject<UCameraComponent>(TEXT("asdf"));
//C->AttachTo(Pawn->CameraSpringArm);
UE_LOG(MyLog, Warning, TEXT("playercamera->attachment %s"), PlayerCamera->GetAttachParent() == NULL? TEXT("NULL") : TEXT("NOT NULL"));
}
}
I get the output “NOT NULL”, so I’d assume that the camera was actually attached to the pawn. When I look in the editor, that’s apparently not the case. The editor crashes if I try to run the outcommented code.
What might be the problem?
edit: also the engine crashes when I try to access a UCameraComponent Pointer that was declared in the MyPawn class, instead of usind a local variable.
I think you overthinking this I think you not aware of fact that PlayerController can do what you trying to do, which i assuming is switching pawn possession and switching camera
First you can switch pawn attached to controller using Possess function:
Then from controller you can access possess Pawn from GetPawn() as well all PlayerController function will cooperate with that pawn (like input controls)
2nd, the camera. Camera system in UE4 is actor focus based, you set actor that will be View Target for PlayerController with this function:
When camera menager has view target set, it will ask view target (which is actor) on every frame for camera position by calling CalcCamera in view target actor:
In default code in CalcCamera (which oyu can override) it picks first camera component in actor and uses it’s coordinates for camera (yes CameraComponent is not really needed for camera to work, but it’s helpful).
Here you got default code from engine source code:
void AActor::CalcCamera(float DeltaTime, FMinimalViewInfo& OutResult)
{
if (bFindCameraComponentWhenViewTarget)
{
// Look for the first active camera component and use that for the view
TInlineComponentArray<UCameraComponent*> Cameras;
GetComponents<UCameraComponent>(/*out*/ Cameras);
for (UCameraComponent* CameraComponent : Cameras)
{
if (CameraComponent->bIsActive)
{
CameraComponent->GetCameraView(DeltaTime, OutResult);
return;
}
}
}
GetActorEyesViewPoint(OutResult.Location, OutResult.Rotation);
}
As you can see it all about setting OutResult which contains camera attributes.You can freely override this function, if you have 2 or more camera components in actor you need to use this function to select one of them accprding to some conditions
Also keep in mind that when you possess pawn, by default it’s automatically becomes view target. You can disable this behavior by setting bAutoManageActiveCameraTarget to false in your PlayerController
The engine also crashed when I try to use the possess function:
AController* PlayerController = ()->GetFirstPlayerController();
PlayerController->Possess((APawn*)this);
Why are you casting? where do you place that code? If it’s a class that is not related with APawn you will have a crash, only Pawns can be possesed. If class is related to APawn, you don’t need to cast at all
I don’t get it, so why it is different when adding camera inside character from calling it from controller ? Why we should override CalcCamera in controller, but it’s fine if we just put it in a character ?
You can do either, any you can pick any actor as view target (including non-physical actors like AControllers and AGameModes) and each actor can be coded to deal with camera differently. However you do it’s you to decide.
Also lets go to your quastion with this disscussion so we won’t talk in 2 diffrent quastions