Doing Unreal Camera Calculations Right

· Read in about 2 min · (419 Words)

What’s The Problem?

Sometimes you want to do some calculations based on the current view, such as a ray/plane intersection to figure out where the player is looking. A lot of information online will immediately tell you to “get the camera component and…”.

NO!

If you do this you’ll get some weird edge cases where the results that gives you are just plain wrong. The transform of the camera component on your pawn is NOT the current player view; even when it’s the camera you’re posessing right now.

There are several things that can render the Camera Component transform different from what you’re actually seeing, including doing a view target change with a blend, and changing camera lag settings. The interpolation can often give you slightly off results compared to what you’re actually seeing.

The Solution

The solution is to always access camera location / rotation via the APlayerCameraManager, never from the camera component directly.

A blueprint example, this code is inside a Pawn:

Blueprint example

And now in C++:

// NO!! Using the camera component directly is NOT reliable
if (auto Cam = GetCameraComponent())  
{  
    FVector Loc = Cam->GetComponentLocation();
    FVector Fwd = Cam->GetComponentQuat().GetForwardVector();
    float HitDist = FMath::RayPlaneIntersectionParam(Loc, Fwd, FloorPlane);
    return Loc + Fwd * HitDist;
} 
// YES! PlayerCameraManager is the CORRECT view
if (auto Ctrl = GetLocalViewingPlayerController())
{
    if (Ctrl->PlayerCameraManager)
    {
        FVector Loc = Ctrl->PlayerCameraManager->GetCameraLocation();
        FVector Fwd = Ctrl->PlayerCameraManager->GetCameraRotation()
            .Quaternion().GetForwardVector();
        float HitDist = FMath::RayPlaneIntersectionParam(Loc, Fwd, FloorPlane);
        return Loc + Fwd * HitDist;
    }
}

What difference can it make?

Let’s take an example of placing an object on the intersection of the camera’s ray and the floor plane. In this example, we change the camera’s lag settings when we transition from “running around” and “aiming”.

Using the Camera Component directly, there’s a weird little offset at the start of the camera settings change, then a “snap” to the centre once the transition is complete.

Bad camera

However, when we use the Player Camera Manager, the ray from the camera is correct all of the time:

OK camera

Basically anything which could be applying an offset to the view on top of the camera component will not be reflected properly if you use the camera component directly. Stick to the Player Camera Manager!

Fin

That’s it, that’s the whole post. If you find some camera calculation you’re doing become a bit glitchy under changing conditions, check that you’re not using the camera component directly. If you are, switch to the Player Camera Manager instead, and that’s very likely to fix it. 👋