How to change camera offset and keep same point of aim in third person shooter

the problem:
in third person shooter it is common to use a socket offset on the spring arm so we can see in front of the character. But when you add the offset, if you start the bullets from muzzle of gun, then the hit location is always offset from the center of the screen.

This is an often asked question with many threads that lead to no fruition. There are a few solutions out there but I did things different from how I saw so sharing my method here:

The premise is that we use a springarm with a scene component at the end which serves as a fixed reference point for where to aim.

Due to the nature of the springarm colliding with environment and adjusting dynamically, this means that up-close aiming still works as you’d expect.

Here is spring arm with a billboard serving as the aim locator:

So that provides a location for the camera to look at and it is always aligned with the pawn control rotation.

Now when spawning a projectile, I do it from a socket location and for rotation just get the look at rotation to that aim locator:

Note that the start of the look at rotation is the camera spring arm though. This is because the camera spring arm can be offset at runtime, so this ensures the rotation of the projectile accounts for the offset naturally (you dont need to write extra code to do that this way).

Now the camera offset and rotation adjustment:


result (there is a tiny discrepancy because my game has some small amount of aim wobble)


Using the springarm is not fundamentally different from using a linetrace to get a location in center of the screen. it just cuts down amount of code you have to write and then fuss with by using existing tools in a more mechanical way (good for us simpletons who get hung up on mathy stuff).

you could argue that a line trace could be toggled on and off only when needed compared to the spring arm which may have a performance impact, however then you have to make a bunch of code to know when to use the line trace and when not. Depending on how your game works this might be simple or complicated.

Anyway, hope it helps, just another way to solve a common problem.

1 Like