Need some help with creating a modular gun system

Hi all;

So, over the past… long time, I’ve been trying to develop a weapon system similar to the one used in Borderlands, only with interchangeable parts. I’ve sort of hit a brick wall here, though, and don’t know how to continue.

The idea is this: I have a Weapon with 9 Modules. Each Module has 5 Stats (accuracy, damage, etc.) which are used as multipliers for the Stats on the Weapon itself. I’ve developed two somewhat-working systems so far that I want to combine into one. The first system I developed took default UE4 static models in a set shape/arrangement. The ModularGun (MG) BP has 9 Static Meshes which I assigned the models to. It contains in it variables for Weapon and Module structs (every Weapon has 9 Modules, and every Module has 5 Stats, not including name; detailed below). The MG BP, on gameplay start, would break the Weapon struct then break the Module struct (since I’ve run into issues with iterating through arrays of Structs), generate a random number for each Stat, repeat 8 times for a total of 9 Modules, then assemble that back into a Weapon. The screenshot below sort of details how the finished product looks.

The second system, shown in the background of the above screenshot, works a bit differently. What I had wanted to do is for each Component imported (barrel, grip, etc.) give it set stats and have the MG BP pick from available Components to assemble a gun into the above system (as in, pick from a Heavy barrel, a Fast barrel, a Standard barrel, etc.). So far, this system takes imported fbx files, randomly picks from a for now hardcoded list, and snaps it all together using sockets. This system uses SkeletalMeshComponents in the BoneTest (BT) BluePrint.

What do you all think would be a good way to combine these blueprints? I simply cannot think of one. The MG Structs are detailed below; should I maybe add another variable to the Module so that I can put Components in there? Should it be another Struct? Should I scrap this entirely and start from scratch? The MG BP uses Static Meshes while the BT BP uses Skeletal Meshes, neither of which I can reference easily. I don’t think adding a blueprint for each Component I import would be a good idea, but it sort of seems like that’s the only way I can reference them as Actors.

I apologize for the large picture sizes, I do not know how to resize them.

Any help would be much appreciated.

I think you are over-complicating it all.
I would make single weapon blueprint that has those data structures:

  • general (base stats for gun) that hold unmodified stats,

  • resulting stats of gun after all modules are added (so you do not need to recalculate it), do it only when any module is swapped

-array of modules for gun.
each gun module would be struct that holds socket name, mesh that it needs to attach there, its material
then it will have relative gameplay values like +5% to crit -10% to range etc.

  • struct that keeps type of spawned projectile (reference to blueprint that is one). for eg. hitscan, guided missile, or physics projectile like grenade.

  • struct that keeps visual data for muzzle flash or smoke (for rockets etc), sounds that gun makes.

Now you should make some interface that lets you keep everything simple.

You need 2 functions:

  • one that reconstructs gun visuals after you swap one module, it happens quite fast so making remove and add modle is not worth time. Instead kill all modules and snap new gun from list.
  • second function will be one that goes trough all modules stats and applies them to “resulting stats” of gun.

That all is not simple, so i would start with gun that can have one module swapped. And total of 2 different modules. Each module changes single stat.
But because structs in unreal sometimes misbehave i would recommend creating those structs with all variables you need from start, this nees some carefull planning

Sounds good. Been restructuring the BP (well, making a new one) most of the day - changing the Structs I already had utterly broke the MG BP for some reason, and since I (still) haven’t learned to use source control with this, it’s irreparably destroyed.

Ah, well. I needed a fresh start anyway.

Edit: What would be the best way for me to store the imported components, with all the values? Have an array of Component Structs which has the values I’d like? As of now, I haven’t tied the systems together; I’ve currently got each of the “parts” of the gun (in the ModGun BluePrint itself) as a Skeletal Mesh Component, but that heavily limits what I can do with them. Would it be a better idea to try and use a Child Actor Component? I don’t think I’ve seen them before, so they may have been added since I last used UE (or I could have just not noticed them). I assume they’d be equivalent to “real” actors, but just local to the BP I create them in? Seems like it would also be easier to stuff values/variables into them.

Firs some advice: don’t overdo with structs in arrays of structs. Or do not push unreal to the limits, make al data structures as simple as possible. Unreal is stable with structs in arrays, but something more nested may cause weird stuff. Epic fixed a lot of it since 4.4 but it is still there, just deeper. So do not dig that deep in.

So best is “flat” struct that keeps all you data for module. Or if you plan to have different modules (same magazine for 2 different guns that have slightly different model) that have same stats, split all data into 2 structs, one for visuals one for gameplay data.

I think visual struct should have something like this:

  • name of module (so you can use this later in GUI), for eg “drum magazine MK I”
  • some unique ID, that is if you ever want to search modules array for something, or compare 2 modules, this can be enumerator. Also having this as ENUM could make life easier if you code some function that fills rest of values after you set this enum. But that would work only with C++ when you read rest of values from database or some json file.
  • socket name of gun this thing needs to snap
  • transformation relative to gun that you should apply. Scaling and moving should be done in 3d app when modelling parts, but just in case you need to tweak a abi its handy to have this.
  • material that should be applied to mesh
  • and last mesh reference

Then you need gameplay struct
here you should keep all modifiers this module will apply to gun.

  • you can add second part of name. for this part (so you can have identical models of part but with different name variation)
  • if you want same mesh model for modules that may have different stats you may want modify material, so add material override field
  • and add all your gameplay modfiers below.

Child actor components also limit some stuff, problems are similar to structs i described above, just in different places.
For eg, with structs if you want to modify how material override is applied, you change single place in blueprints.
With child actor you will have this (override material) logic in every module blueprint. Now to change it you need to fix every single blueprint.
Yes this can be avoided with inherited blueprints, but child actors with inherited blueprints messes everything even more than plain structs.

Ps. Soon I will do similar system for myself, that is why i thought about this all so much. I already tried to do this for spaceship weapons and turrets, and i tried child actor method.

About storing (and more about importing and setting up default values) this is something that probably requires some C++.
Yes you can make array of those structs, fill it all up in editor. But few times i got all that data wiped (yes it was 4.4), this may happen again.
So safest way that i think of is writting some json (or any text file format you want) parser in C++, writting all that in text file and importing as data into unreal.
Then you need C++ for reading it and filling structs. But this introduces quite big problem: acessing blueprint structs from C++, i read that this is quite messed.
So instead you coud create function in C++ that reads single struct from text data, and returns it to blueprint. Then you apply values in blueprint.

The following is what I’ve come up with so far, and I think it’s relatively “flat” if I correctly understand what you’re saying:
Module:
Module.png
Weapon:
Weapon.png
Unique ID I’ll see if I can add at some point; I’m just wanting to get a basic system working for now so I can clean it up later on.
Transform, good idea; I’ve already had some issues with the bones not importing as I thought they would.

Child actor components do seem to act differently than I had thought, don’t think I’ll be using those (at least not until I grasp better how they work).
I do think that a reason for the failure of MG is that when I added additional variables to the struct, all the other data (the 5 variables I hadn’t touched) also got wiped.

Thanks for your help so far, much appreciated; let’s see how far I can get with this.