At this point is more viable to just simple ask about it, so…here I go (it’s a really long post, but I would like explain what I’ve tried so far):
A few months ago, I started designing (and programming) my own weapon system. The approach was this: a system capable of creating from an axe to a submachine gun; extendable and scalable. Yeah, sounds a little extreme. The idea originally came up as just a “simple” system to create any gun I wanted (a pistol, shotgun, submachine, etc), and at that moment I decided to make it possible through Scriptable Objects. I just simple created different data objects, each with different settings, and then select the “weapon profile” I wanted to use.
Since every weapon in my game had the same behavior (shoot, reload, is it empty? does it have bullets left?, etc), I could use one script just to “load” the data from the “weapon profile”, and make the weapon act according to those values (fire rate, magazine limit, bullets left, auto, semi, and some other properties), while executing its respective methods (Shoot, Reload).
That system was good, I really liked it. However, it wasn’t scalable. As the project grew up, the system was getting messier, and harder to work with; to maintain it. Also, it was only limited to guns, or anything that has a fire rate and shoots something, and has limited ammo (a bow, maybe? lol). Also, my requirements changed, I needed to add an axe. So, I had to redesign the entire system.
The next I tried was to create an abstract weapon definition, so I could create different weapon implementations. I designed that based on the next assumption: you can attack and create damage with all weapons, but not all weapons need to be reloaded, nor get empty. We can safely say that all weapons need and Attack() method, but not all of them (like an axe), need a Reload() one.
So, a pistol has the Attack() method, plus the Reload() method. An axe just implements the Attack() one. It seems like the way to go but I was definitely missing something. This system was still using Scriptable Objects for some general properties (fire rate, magazine limit, etc).
I didn’t like it, still. It has pretty much the same issues that the other one. Maybe I just simply made a bad implementation. I honestly believe it was poorly designed since the beginning.
Last approach was Event/Component-based. Pretty sure those aren’t the terms…but anyway. Basically, I separate every task conforming the weapon into many different “behaviors”. Shoot, behavior, raycast behavior, reload behavior, this behavior, that behavior. Working side-by-side with an event system based on Scriptable Objects, I gotta say it was pretty neat. Using Unity Events, there was no necessity to directly reference a lot of stuff into all the behaviors from above. A lot of things could happen simultaneously every time a Unity Event got called (I had Shoot event, Reload event, and ADS event). This system allowed me to practically “build” a weapon, adding or removing certain behaviors, as I pleased. It was kind of modular I guess? This system was also using Scriptable Objects again, for general properties/values (fire rate, etc).
Now, with that system I was able to “build” an axe, and a pistol, and a shotgun, and well, lots of weapons! But…I wasn’t satisfied. It just wasn’t perfect. And apparently it wasn’t just for one thing…
Unity Events, in conjunction with the new input system, were only called once per-input trigger/started/performed. Almost perfect…but because of that flaw, I wasn’t able to made automatic guns. For that, I would need to call the OnShoot event continuously, while I press certain key. I didn’t found any way to achieve that behavior, so my guess is that by design, Unity Events can’t do that. I still think that maybe there is a way to do it, like changing something on the input itself, but before I start to experiment with a lot of random stuff, I decided to just simply come here and ask for some help.
Why? Well, let’s remember that this entire system is based on the assumption: you can attack and create damage with all weapons, but not all weapons need to be reloaded, nor get empty. Perhaps this assumption is the problem and the issue with my designs are merely a logic one.
The next uhhmm…sketches, are a visual guide of what I’m trying to achieve:
My design could be very wrong, and that’s why I need some help. If, theoretically speaking, there’s nothing wrong with my design, then:
- I already know that I need a “component based” system, something similar to how Unity works. Kind of modular.
- Those components are basically “behaviors”. Every weapon has different behaviors (event though both axe and pistol can attack, they perform a different attack).
Looking through the internet, I found the strategy pattern (I really liked this[Strategy (refactoring.guru)] post about it). In a reddit post ((1) Which is better for multiple weapons system: have 1 Input per weapon scripts or have multiple/all weapons in 1 script? : Unity3D (reddit.com)), someone in the comments mentions it, and that user precisely uses it for a weapon system.
But, yeah…I honestly find myself quite lost, and I don’t know what decision to make, or rather what decision would be right. Should I stick to my last design? Should I try again with another system?
Keep in mind that I also tried inheritance and interfaces, but I couldn’t figure it out how to apply it to my system.
Thanks in advance!

