Weapon Recoil, Spread & Spray Patterns

Key Components

What is weapon recoil

Weapon recoil is a great way to give firearms their own personality. In essence, this means to recreate the jerking motion from the forces generated when firing a projectile in real life. In gaming, weapon recoil serves as a means to enhance immersion by mimicking the motions associated with firing a real firearm. This implementation of recoil is can introduce more intricate gunplay and greatly affect combat mechanics.


Typically, recoil is implemented as predictable and recognizable bullet hit pattern, often called a Spray Pattern. These patterns give weapons their own distinctive behaviors and traits, directly influencing their effectiveness in the game. Additionally, they allow players the to discover and specialize in weapons that align with their playstyle of choice.

Static recoil

In a game featuring static recoil. When the player fires their weapon, the camera is tilted back to simulate the weapon punch. The player has to compensate by counteracting the movement. This type of recoil has become less prevalent in favor of dynamic recoil systems.

They still see some use in tactical shooters but have been replaced by dynamic recoil systems in large.

Dynamic Recoil

Dynamic recoil, for lack of a better term, displaces the aim point while shooting and subsequently returns it back to its origin when you stop shooting. 

This means players can still counteract recoil by moving their aim in the opposite direction. But they don't require the same level of mechanical control to maintain accuracy.

Dynamic recoil has several benefits, for gamepads, less micro adjustments and for keyboard and mouse players less vertical space required for mouse movement. Without sacrificing the mastering ability that comes from learning recoil patterns.

Creating a dynamic recoil system

Defining Recoil Patterns

The system in this article is heavily inspired by the recoil system found in Counter-Strike: Global Offensive. But can easily be adapted to suit any kind of modern FPS.


This is not a step by step code example, rather it's a guide to the general concepts of implementing a recoil model. Your approach should be based on your needs. Different classes and data structures might be better suited when working with networked gameplay. The same concepts should still apply.

What makes up recoil

A typical weapon recoil system consists of two parts:

Camera Recoil

A rotation offset applied to the player camera to simulate the forces of the weapon kick absorbed by the characters body.

Projectile Offset

An offset we apply when spawning or tracing our projectile relative to the player camera. These simulate the weapon moving in the characters hands.

Combining these two makes up the foundation of the recoil pattern. 

Creating a predictable spray pattern

To create a basic spray pattern, a weapon needs a data set to define movement.

Vertical recoil

This defines how much the barrel climbs when fired. 

Horizontal Recoil

This defines how much the weapon jumps side to side when firing.

Visualization of bullet traces. The offset is also used inside the animation controller to follow the spray pattern and frame the bullets even in ADS mode.
Horizontal and Vertical spread sequence.The crosshair represents the 0 value on each track.

Using float curves

In UE5 we can manage this easily by storing both the horizontal and vertical curves as separate Float Curve objects.

We can get the current recoil value by tracking how many bullets we have fired in sequence. 

We can do this by creating a separate variable called BulletsInSequence that we increment whenever we fire a bullet, we use this as our getter value for our float curves.

The large benefit of storing these patterns as curves is how easy they are to read and edit. Especially when dealing with a larger weapon base or handing over behavior to the design team.

Vector curves

An alternative to separate float curves is to instead use Vector curves. Vector curves have 3 axes by default. X,Y, & Z. Storing the recoil values on the X and Y axis for example allows you to edit and keep both curves inside the same asset. 

The final Z axis can then be used when implementing weapon spread. Another important mechanic which is covered later in this article.

How getting the recoil value could look in blueprints

Resetting the recoil

Whenever we want to reset our recoil pattern we just have to set our tracked BulletsInSequence variable back to zero.

To avoid players spamming the fire button to avoid weapon recoil, we add a slight delay between when we stop shooting and resetting the spray pattern. 

As a game mechanic this is known as "Resetting the spray" and prevalent in many first person shooters.

Reset Timer

Any time we fire a bullet we also set a timer. This timer has one purpose, to reset the bullet sequence when we stop shooting. 

I find that resetting the counter to zero after elapsing makes for the most consistent feeling gunplay.

A range of 0.2 - 0.35 is a good starting point, as most weapons have a higher rate of fire.

You could do some sort of interpolation though I would strongly advise against it.

Timers aren't frame perfect. Meaning that they may not be the best suited for hyper competitive games where milliseconds can make a big difference.

Accumulating and applying recoil

Tracking accumulated recoil is as simple as adding and storing these values in a separate variable. In the following example note that "Add Control Pitch" is additive and takes the current curve value and not the accumulated value.

The Accumulated recoil value is used to restore the camera to it's original location by subtracting the accumulated recoil over time. 

Accumulated recoil can also be used as input for our animation controller to give us better visual feedback on our current recoil state. As seen in my article about Procedural Weapon Animation

the "Add Controller Pitch/Yaw Input" routs input parameters to the Player Controller. When applying input: Make sure not to include control sensitivity scaling as that will make your game dependent on user settings.

This example is set up inside of the Player Character which is a subclass of the Pawn. It's always good to consider where your code will be used/re-used. And if the class context is suitable for networked gameplay. Consider maybe housing parts of this logic within the Player Controller.

Re-Centering the aim

We use the accumulated recoil values to track and subtract vertical and horizontal offset, until both are back to 0.0. How much we subtract is a defining  aspect of the gun feel. The example below uses a hard set interp speed when calculating the recovery value. This works as long as your weapons don't overshoot the view angles of your character controller. 

When using an additive recoil system, you must also account for a weapons rate of fire when scaling the vertical recoil. otherwise you risk recoil climbing outside player view. Increasing the interpolation speed the further you get from the center can be an efficient way to soft clamp the recoil while at the same time avoiding the feeling of "hitting a hard ceiling"

Just like when we added the recoil, we take the subtracted value and apply it to our camera or controller.

Simplified version of the reset structure for vertical offset. This should be done on per frame basis because it interacts with player input.

Weapon Spread

If you have played Counter-Strike you might have noticed that no matter how much you practice recoil control there is always a small deviation to where the bullet lands. 

This happens due to weapon spread. Weapon spread is a random offset applied when shooting a weapon.

Just like recoil, weapon spread is often a scaling variable. Each shot fired in sequence often deviates more from the defined spray pattern than the last. This often makes burst firing a more reliable option than shooting full auto.

Spread is also a means to define the speed of gameplay. Firing while on the move is often penalized by an additional layer of random spread. This is to avoid players flying through the map to land fast kills.

This is known as movement spread or movement accuracy. Movement speed and accuracy are often a major balancing point. In some cases spread is a constant. Instead, movement speed penalties are introduced when aiming down sights to take more accurate shots.

There is usually some degree of weapon spread present even when aiming down sights, as this is an important part of a weapons identity.

This pistol is barely affected by recoil due to a low rate of fire. Instead most of the bullet offset comes from spread. 
This is what applying spread to a weapon trace could look like

Implementing spread

Just like the recoil curves. Spread can also benefit being implemented as Curves.

As opposed to the recoil curves. Spread doesn't have to be additive.

And just like the recoil curves, we can use the same BulletInSequence variable to fetc our spread values.

First shot accuracy

In most competitive shooters there is a very slight amount of spread applied even to the first bullet on all weapons. This is known as first shot accuracy. It has big impact on a weapons effective range. Making sure you can't efficiently play sniper with pistols or rifles even if you are considered to have great aim.

Movement Spread

In Counter-Strike movement spread penalties applies as soon as a character exceeds a set threshold (about 150 source units). Players moving below this threshold won't suffer any accuracy penalty based on movement.

This is why stopping before you shoot is such an important mechanic in counter strike. It even has it's own name "Counter Stepping"

Counter Stepping is an advanced mechanic where a player quickly taps their movement keys in the opposite direction of their current velocity. Doing so let's you cancel out your current movement velocity, putting you below the movement accuracy threshold. Players who master this can shoot accurately while moving at seemingly high speeds.

Unreal comes with this nifty node that can apply a random offset to a pre defined directional vector. In case you don't want to do the calculation on your own.
As an example, the inner circle is the spread applied to the first bullet in a series, the first bullet will never deviate more than this. Subsequent shots with applied spread scaling can land anywhere within the larger circle.
Spread projected on to the previous pattern example. Where circles overlap are the easiest places to land hits when spraying.
Example of an activation function for movement spread

Additive Camera Recoil Spread

A less talked about mechanic that is probably one of the defining parts of the counter strike spray pattern model is something I call additive camera recoil spread.


Not only do bullets follow a pre-defined spray pattern, they also maintain an offset between our camera and our aim point origin.

This is also one of the more advanced dynamics of Counter Strikes gunplay, and a key element when resetting the spray.







This pistol is assigned exaggerated recoil values. There is no spread applied in this gif. Only vertical and horizontal recoil.
In the above model. The bullet trace offset from the crosshair is the same as the distance between the current camera rotation offset from the aimpoint origin.
The dotted blue lines mark the bullet trace offset which is where the bullets will land based on the camera offset(red) from the aimpoint origin(black). After which spread is applied.

Loop Points

Lastly. Let's talk about loop points. 

Loop points wont directly impact your weapon behavior. Rather, they make sure you don't have to manually create infinite data points for your recoil and spread values. This is especially useful when dealing with weapons that have large magazines or in the case a game features infinite ammo.

Counter Strike features a weapon called Negev. A belt fed light machine gun that has 150 bullets. The Negev is has a rapid rate of fire. What's unique about the Negev is that it's first 10 bullets have significant recoil. After sustained fire, the weapon concentrates to a tight beam of bullets making it great for suppressive fire.

To avoid modeling 150 unique data points. We can instead define a pattern where the first 1-10 bullets have a significant recoil offset and spread. Then instead of modeling another 140 data points, we give bullet 11-20 a tighter recoil concentration and reduced bullet spread. Now all we need is a Loop start and Loop End

Not only does it make your weapons handle large ammo counts, it also simplifies the process of defining a weapons identity.

In this case the rifles Loop start is set to 15 and its Loop end set to 30.

After shooting 30 bullets in sequence, the recoil curves start looping between bullet 15-30.

Continue Reading

This article features pointers on how I recommend setting up a first person character. Includes the topics of True First Person setups, Field Of View and setting up a blender scene to create base poses for weapon animations. 

This next article is about combining the recoil model
with the player character and game input to create
responsive and dynamic weapon animations