How do I UnPossess without affecting camera

I have a pawn that I UnPossess at some point, but I want the camera to:

  1. Stay on the pawn as it is now
  2. Then move to a new position smoothly

I created a CameraActor at the second position so that I can use PlayerController->SetViewTargetWithBlend. This all works fine as long as I don’t UnPossess the pawn. When I call UnPossess, that seems to nullify any call to SetViewTargetWithBlend in the same frame. It also resets the view to (I think) the PlayerController’s position. Setting it back to the previously possessed pawn seems to have no effect when attempted in the same frame. Has anyone encountered this before and have an idea on how to achieve what I want? Here are some things I tried.

Doesn’t work, because UnPossess takes the camera away from the pawn and the call to SetViewTargetWithBlend has no effect in the same frame:



	PC->UnPossess();
	PC->SetViewTargetWithBlend(CombatCamera, 0.6f, EViewTargetBlendFunction::VTBlend_EaseIn, 0.5f, true);


Call to SetViewTarget again has no effect:



	APawn * PreviousPawn = PC->GetPawn(); // Checked to be non-null
	...
	PC->UnPossess();
	PC->SetViewTarget(PreviousPawn);   // No effect


I would be okay with starting the SetViewTargetWithBlend 0.1 seconds after UnPossessing, but the camera still snaps away for a frame when calling UnPossess which is annoying to look at. Any suggestions?

2 Likes

Oops, managed to find it after some digging. The PlayerController has a boolean setting bAutoManageActiveCamera which is turned on by default. This setting causes the player camera to automatically use the Pawn as view target when possessing it, and use the PlayerController as view target when unpossessing. You can change the value any time before calling Possess or UnPossess if you want a custom view target or an on-going camera transition to be unaffected:



	// Start smooth camera transition
	PC->SetViewTargetWithBlend(CombatCamera, 0.6f, EViewTargetBlendFunction::VTBlend_EaseIn, 0.5f, true);

	// Unpossess the pawn
	PC->bAutoManageActiveCameraTarget = false;
	PC->UnPossess();


Note that the order of calling SetViewTarget(WithBlend) and UnPossess no longer matters because UnPossess does nothing that affects the view target.

2 Likes

After hours strugling with this problem, you saved me. THANK YOU!

Oh glad I could help you! :slight_smile:

I have a follow up question to this if anyone has any ideas, as it’s happening to me with BP with a multiplayer setup.

In my case I’m trying to send a camera from 3rd person player view to a camera in the sky at the point that my pawn is destroyed. The PC has the auto-manage camera option unchecked.

The camera has the expected results on the server machine, but clients do the jump to PC camera first before panning to the sky camera. What’s even more frustrating about this is that the camera that is in use when the unpossess occurs is separate as well, looking at the player from a different view.

Is there a BP method to untick that box? I certainly can’t find it in the variable list.

I looked at PlayerController C++ source and the bAutoManageActiveCameraTarget property is set to EditAnywhere only. It would need to have BlueprintReadWrite tag also to be editable from blueprints. I also didn’t find any function setting it by other names. So, it can’t be set from BP as of now. Unless you change the source code. I saw nothing that seemed to generate errors in case it would change during gameplay since it could be set from C++ at anytime.

If you don’t mind explaining…
I know nothing about Server and Client in Unreal (kinda new to the Engine and haven’t messed with multiplayer yet) but why does the client seem to have a property set differently from the server application? Are they separate compiles of the same game?

While you can’t make the variable itself ReadWrite without editing PlayerController, you can make a function to edit the value in your PlayerController C++ subclass. So that way you don’t need to edit the engine source. Do you know how to do that?

Game server and client run the exact same DLL. They run the exact same code, the only difference is that some code is only executed on the server (in many places) and some code is only executed on client (like HUD and simple visuals related things). Values can differ on actors on server and clients, even if they are the same actor. In fact, creating a network efficient multiplayer game involves synchronizing only the values that are necessary for a client-side experience that feels smooth and synchronized.

Here’s something that many of us may not have noticed…

The PlayerCameraManager’s Location and Rotation values are inherited from the PlayerController when you UnPossess();

This is what I used to solve my camera problem in the SideScroller sample project:


PlayerController->bAutoManageActiveCameraTarget = false;
PlayerController->SetControlRotation(FRotator(0.0f, 180.0f, 0.0f));
PlayerController->UnPossess();

Thanks a lot, this even work using blueprint (using details pannel)

1 Like