Player Camera Manager
The PlayerCameraManager is an important aspect of Unreal Engine and good documentation around it is somewhat sparse. This page exists to try and remedy that.
An incredibly important class in Unreal Engine is the PlayerCameraManager
class, and your game is using this class whether you realize it or not. In fact, it's kind of a tragedy how few people do know about this class given what's possible by understanding how it works.
Effectively, this is the class in charge of determining where the player's point of view is and it does so through a variety of techniques. If we look at what the docs have to say about this page:
A PlayerCameraManager is responsible for managing the camera for a particular player. It defines the final view properties used by other systems (e.g. the renderer), meaning you can think of it as your virtual eyeball in the world. It can compute the final camera properties directly, or it can arbitrate/blend between other objects or actors that influence the camera (e.g. blending from one CameraActor to another).
Benefits of Using PlayerCameraManager
Directly
One of the coolest things about working with this class directly is the level of control that you can have over your player's point of view in your game. Rather than dealing with rigid or restrictive transforms on a CameraComponent
that are trying to maintain a relative offset to its parent actor, we can just tell the camera manager where we want to be.
As an example, this can make things like switching between first and third person view points a rather trivial procedure. Rather than switching between two CameraComponent
s or trying to manually move a CameraComponent
between two positions, we can just provide the desired transform(s) directly.
Another benefit is the fact that we can reduce the number of CameraComponent
s in our scene or add spectator support from the point of view of an NPC or actor that doesn't have a camera of its own. This can even have performance benefits, especially in cases where you need to have many actors that can operate as the point of view for the player (for example, if you wanted to possess a specific unit in an real-time strategy game).
Using a Custom PlayerCameraManager
Class
The PlayerCameraManager
class is instantiated and maintained by the PlayerController
. Creating a custom subclass is as easy as extending it via C++ or Blueprint and then assigning it via the PlayerCameraManagerClass
property in the PlayerController
class defaults.
If you're trying to assign a custom class via C++, you can do it via your custom controller's constructor.
ACustomPlayerController::ACustomPlayerController()
{
PlayerCameraManagerClass = ACustomPlayerCameraManager::StaticClass();
}
How PlayerCameraManager
Calculates Point of View
The order of operations listed here is based on speculative observation of the source code for the engine. If anyone has done testing or has a more definitive answer that can be used to correct this, they should feel free to update it accordingly.
Base Determination of Location, Rotation, etc...
The manager class will first attempt to determine a collection of settings using the associated PlayerController
and any pawns that are currently being possessed.
An example of this can be seen in APlayerCameraManager::ProcessViewRotation
, which determines an initial rotation for the POV
and is called by the owning controller's APlayerController::UpdateRotation
. The UpdateRotation
method is called during the controller's own tick, but may be called by other components if they affect, wish to affect and update the player controller's rotation (see UCharacterMovementComponent
for an example).
View Target Overrides
If a valid view target is set with an AActor
target, then it will invoke AActor::CalcCamera
to determine the POV
settings to use. This will override the assumptions that were made by the. UNLESS the camera manager class is extended via Blueprint, in which case the BlueprintUpdateCamera
takes precedence over the call to CalcCamera
if it returns true
.
If you're looking for a way to handle custom camera modifications on a per-actor basis, overriding CalcCamera
may be a great place to do it. In fact, this method looks through the actor for an attached CameraComponent
and then handles the translation of said component to override the previously derived POV
settings.
UpdateCamera
and Camera Modifiers
Once the base location + rotation for the point of view has been calculated, the class' UpdateCamera
method is called during its tick. This appears to be an ideal place for derived classes to add custom calculations for the camera after the initial POV
calculations have been performed.
In fact, you can see the Shooter Project's custom implementation of the camera manager class use this to modify the camera' field of view and to adjust the rotation of the character's first-person mesh.
(Over generalization) Finally, any camera modifiers that have been added to the camera manager are executed. This includes things like post-processing effects and camera shakes.
What is a "View Target"?
As the name implies, the "view target" is an object that we want the camera to follow. In the case of a third-person game, this is likely the player character that we're following. For a first-person title, this may be the actor whose eyes we want to look through.
The actual ViewTarget
is a property found in APlayerCameraManager
and is a custom struct type called FTViewTarget
. This struct contains 2 important public properties: the actual Target
(a pointer to an AActor
) and POV
(an instance of FMinimalViewInfo
), which contains the current location, rotation, field of view, aspect ratio, and more.
ViewTarget
is set via the manager's UpdateViewTarget
class and it will immediately begin setting up the POV
when called. Additionally, this is where CameraStyle
(another aspect of the PlayerCameraManager
) appears to have its largest impact on the end result.