Thank you for taking the time to check out Competitive Recoil. On this page you’ll find a breakdown of each of the Blueprints contained within the project, how they’re intended to be used, and how you can integrate them into your own game.
If you have any questions or concerns you may find them addressed in the Frequently Asked Questions section at the bottom of this page. If you can’t find what you’re looking for you can reach me at firstname.lastname@example.org and in the techarthub Community Discord server.
This Widget Blueprint contains the elements that make up the Crosshair. It draws its values from a Crosshair Settings struct, making it highly customizable.
This function is intended to be fired when the Crosshair is created and added to the viewport. Its only job is to apply the values found in SCrosshairSettings to the Crosshair’s components.
You may notice that in the WBP_Crosshair Blueprint I’m using two InitializeCrosshair functions, one for the inner and one for the outer line shapes. I wanted to keep them separate just in case you needed to remove/add one. Just keeping it flexible!
UpdateCrosshair fires every Tick and is responsible for updating the position and render opacity of the different Crosshair components based on player input. If you’re firing your gun it’s this function that will expand/contract the Crosshair in response to the recoil.
A simple function that sets the size, color, and opacity of the Center Dot.
Another function that fires every Tick, UpdateCentreDot will fade the dot out when you start shooting. Makes it easier to see what you’re aiming at!
If you’re using outlines, all of their components need to be added to an array so we can reference them later. There are a lot of these, and it makes for a pretty ugly vertical Make Array node, so I hide it in here so no one needs to see it any more than they have to.
InitializeOutlines will loop through the array created in the GetOutlines function, and set the size, color, and opacity of your outlines to whatever you’ve set in your Crosshair Settings. This one just needs to be fired once alongside the other initialization functions.
The outlines won’t need updating once that initial setup is done.
Sets the Visibility of an array of Canvas Panels to Hidden.
Sets the Visibility of an array of Images to Hidden.
If you’re familiar with the vanilla FPP Template character then you’ll be right at home with BP_DemoCharacter. It includes some extra logic for shooting and swapping weapons, but it’s mostly what you’d expect. The biggest change on a component level is that I’ve added in some additional scene components to help control the camera while we’re shooting.
- ShotDirection (an Arrow Component that doesn’t really do anything, it’s just for easier debugging)
- KickbackOffset (handles the kickback part of the recoil animation)
- PatternOffset (handles the pattern part of the recoil animation)
- FullAutoSound (an Audio Component, plays a looping sound when firing on full auto)
This is probably the most important function in the Blueprint. It’s fired whenever you pull the trigger, or at intervals if your gun is set to full-auto and you’re holding the trigger down. Shoot will update the recoil pattern, draw line traces to calculate bullet trajectory, and then then pass on that information to the server to calculate the consequences.
UpdateKickback handles the animation of the gun kickback while you’re shooting. This is an additional layer of animation that will bump the camera upwards with every shot. It makes the gun feel more powerful, but doesn’t affect bullet trajectory.
This function uses a curve to determine where the next bullet should go based on your recoil pattern. It also includes some additional random spread that gets more pronounced the longer you’re firing.
UpdateMovementSpread uses the Character’s Velocity and Movement Mode to calculate shot spread. If you’re moving or jumping you’ll be less accurate!
This is a generic function that’s used a few times depending on your settings. It calculates random spread using an optional seed.
Stops playing the full auto sound, and attempts to blend it with a ‘tail’, an echoing report sound. If all goes well players won’t notice that the looping sound was suddenly cut off.
All variables have been given internal descriptions so if you’re not sure about what a specific value does, I’d check there first. If you’re still not sure, let me know!
|CrosshairSettings||Defines the size, shape, and color of your Crosshair. Includes animation options for fire/movement error.|
|GunSettings||The values for a specific gun. Includes fire rate, how many projectiles are fired per trigger pull, which curves to use for recoil, and sound effects.|
|AR_Vector||Sample recoil pattern (Assault Rifle)|
|LMG_Vector||Sample recoil pattern (Light Machine Gun)|
|SG_Vector||Sample recoil pattern (Shotgun)|
|HeavyShot_Recoil||An animation curve for heavy kickback with some oscillation|
|LightShot_Recoil||An animation curve for light kickback, best used with rapid-fire guns|
Frequently Asked Questions
Does it support multiplayer?
Absolutely. At the moment the client handles most of the recoil calculation, and will then tell the server (which will tell other clients) where to place the impact decals. If you’d like to add damage calculation or additional VFX, look for where the decals are placed and add your logic in there.
Does it work in VR?
I don’t see why not, but I’ve not tested it. If you’d like me to confirm before you purchase, let me know!
Why does my Crosshair get weird when I change my project’s DPI Scaling settings?
By default Unreal will try to scale your interface elements using a DPI Curve to ensure that their relative scale is consistent across a broad range of resolutions and aspect ratios. The weirdness you are seeing may be because your Crosshair is really thin (between 1-2 pixels) and as the engine tries to scale the Widget it is ending up being spread across ‘half’ a pixel, making things look a little lopsided.
In the demo project I’ve solved this issue by turning DPI Scaling off entirely. This is great for me, but its a global setting so it may not be desirable if you have other interface elements.
This is a tricky situation, and the solution may be to tweak the DPI Curve until your Crosshair looks as you expect. If that isn’t working out you may need to have multiple crosshairs for each of your target resolutions, or add some additional logic so WBP_Crosshair adapts to different resolutions.