As a kid, I played a good amount of Call of Duty. I was never good, and I always thought it was only because I didn't know how to setup my loadout correctly. I would find myself constantly making new classes with new weapons and/or different attachment combinations, hoping that alone would instantly make me better at the game.
As a game developer, I've always wanted to make a First-Person Shooter, as that's the game genre I had played growing up. For this project specifically, I wanted to create a weapon attachment system and a way to customise my weapon and have the different attachments affect my weapon stats in unique ways.
The way I approached this system is with Unity's Scriptable Objects. I created one for each attachment: Barrel, Grip, Mag, and Stock, each containing values used in the weapon script to affect things such as range and damage fall-off, recoil amount and return speed, ammo per magazine and reserve mag count, and weapon sway and aim down sights speed. The weapon directly references these values, meaning if we change them, the new numbers will have the weapon stats change.
I created a WeaponFullAuto script that is derived from BaseWeapon, which allows me
to support multiple weapon types (semi-auto, burst, bolt...) through virtual functions, such as Fire(). The weapon script has public references to each attachment type, allowing for easy plug-and-play of different attachments. As I
said, the values in the scriptable objects are used in the script, so updating them will allow me to easily have the weapon update its stats. The exception comes when I have my own
variables in the script, such as currentAmmoCount and reserveAmmoCount, that get set at the start of the game to equal the values in the Mag, but do not directly use the numbers all the time. The simple fix is to set their values again when we switch out the mag.
In order to change attachments, I use Unity's canvas and buttons that call my
SetNew<attachment>Type() functions, and pass in the new attachment type. The scriptable objects being passed in already have their values set, so there is no need for any additional tweaks to the parameters on the button OnClick(). In those functions, I update the values of any local variables if applicable (mag for example), update the UI name of the current attachment and the sliders, and it's done.
Comments