What is the best method to program weapons into your game?

I’ve been pondering on something for a while, and I can’t really quite get the grasp on how to actually program weapons. Well, I know several ways I can do, but I’m not sure which is the best one and which is mostly use in the bigger games, for example Half-Life 2. After writing this, I’ll check on Google on how they do it.
The way I have it right now is as followed.
I have 2 classes and an Interface, a Firearm class, and a FirearmBuilder class. And an Interface called IEquipable with Equip and UnEquip functions. Later I will make an interface, and another 2 classes for throwable things. Such as handgrenades, and knifes.
Creating the weapon goes as followed, I have a list, and the list get’s initialized when the game gets launched. An example for making a weapon is this, which is happening in the GameController.

new FirearmBuilder()
                .CreateFirearm("Pistol")
                .withDamage(12.5f)
                .withFireRate(0.5f)
                .withInfiniteAmmo(true)
                .WithMaxClipOf(12)
                .withReloadTime(1.4f)
                .withStartingAmmo(0)
                .withWeaponId(1)
                .withWeaponType(FireType.SemiAutomatic)
                .withModelName("wm_pistol")
                .Build()

The List is a list of the IEquipable interface, so everything that inherits IEquipable can be put there.
This is quite an easy way of making guns, I just need models, and sounds. I can then just make an inventory in the player class, and add weapons from the IEquipable list, if I advance that code a little, I can switch through all available weapons in my current inventory.
What this system not really allows is for special types of guns, for example in Black Ops Zombies there’s a gun that blasts zombies away. This manner of making guns won’t easily allow that without writing a WHOLE bunch of extra code, to allow that. But I’d figure.
Now for the shooting, and this is really the part where I get stuck. The player can shoot with the current weapon and damage everything that has a IDamagable interface on that gameObject. If it doesn’t, it of course doesn’t damage it. That’s as far I’ve gotten. I’ve got an idea on how to apply sound effects, muzzle flashes and that bunch of stuff. But I have no idea how to make this capable with special types of weapons, throwables and some other stuff. I also don’t know how I would handle the FireType enum, which include Semi_Automatic and Automatic.
This all started making me doubt this way of making weapons, as I do not want to do anything in the inspector but everything in code this makes me even more confused on how to do it. This is kind of getting long, but I hope you put through. I’m not asking for code, I’m asking for a better way on how to actually create weapons, and doing everything in code since I prefer that.
If you help me out with that, I would really appreciate it. Thanks in advance.

Before I posted this on this forums, I’ve posted it on the Unity3D subbreddit. And I got some interesting answers, I think I liked the one that this user used, with Frankstein code (as he said it). But there may be better ways of doing this, and I’m all for a little discussion!

P.S. Please don’t hesitate if you want more explanation about what I mean. I’m quite bad at explaining things but I’ll try my best.

There isn’t really a “way” to code weapons. It can be done any number of ways and depends greatly on how complex your weapons and their application needs to be.

It sounds like you’re on the right track with how you’re approaching it. You seem to need a fairly complex system and are using the right stuff to get them done. I actually do something similar to GoGo’s idea that you reference and think its a great approach. It seems like he choose to hardcode more stuff whereas I chose to prefab orient everything so you can just drag-n-drop it into fields on the weapon and it will read it at runtime. Depends on how you want to use it, I suppose. We talked about these concepts in the Bolt Jabbr chat a few months ago actually.

Weapon Inspector:

I think the general concept that I prefer is to make each component a black box. Weapons spawn a Projectile, whatever that is, and the projectile is another standalone object which does whatever you want, so you make it as complicated as you like and the weapon doesn’t need to know (nor does it care) what the projectile does. In my case projectiles strictly do damage, but using this principle you could easily make them apply force to an area or something.

Projectile Inspector:

BergZerg arcade is doing a tutorial/codealong on the scriptable objects (it’s rpg based, but meh)…

the first 20 or so are building custom editors for the scriptable objects, but 23/24 are where he starts going into “spawning” the object into the scene and making use of what has been configured.

@LaneFox
I’ve started doubting the Builder way of making weapon, and this system of creating them completely. I’m no beginner in C#, but I’m not good either. I’m actually now starting with the more advanced things of C#, and actually understanding them. I think I’d rather have the way of the images you showed me, but I have no idea how. Could you explain that for me?

@LeftyRighty
That is a long tutorial, I’ll check it out.

The CryEngine docs have some notes on Crysis’s weapon classes - http://docs.cryengine.com/display/SDKDOC4/Weapon+System

if you’re happy with what a scriptable object is you can probably just skip to the last two and see how they’re using them (I’m kinda hoping there will be another one continuing on this week)

It’s really pretty simple, you don’t have to have really complex structure to make a stable system. I think if you clearly understand those concepts then yeah, it would be best to use some more complex interfaces but I don’t use any in my case… That may change in the future, but the approach without them works fine. For instance when the weapon is fired it checks its ammo, checks if the Projectile prefab reference is null or not, then spawns one and gives it some parent data like what player fired it. It’s just a matter of acting on data and accounting for possible exceptions.

The projectile just does its thing as a standalone instantiation. As soon as it spawns its already configured from the inspector and just uses that data to start doing whatever its supposed to. They do the same thing every time, but can be totally different if you expose enough options in the editor.

So do I and I’m on the lookout for example projects that work this way. If you happen to know any it would be much appreciated if you could reply to my thread here:
http://forum.unity3d.com/threads/im-looking-for-example-projects-of-code-focused-games.340171/

I wish I could be of help with your original question, but I’m pretty much struggling with the same things.

Maybe do a little state machine that goes something like isOperational → fire button gets pushed → isFiring → create projectile, shotsFiredSinceKeyDown + 1, timeOfLastShot = currentTime, if (mode == semi) set a variable to not fire again in the next updates, if (mode == auto) just keep comparing time since last shot with fireRate, if (mode == burst) also compare the number of shots since the key has been pressed (might want to have a special state even like firingBurst so that you can not start to reload mid-burst). Oh and if you do semi you should still compare the time since the last shot with a set fireRate or people could do crazy autofire scripts with Autohotkey and you might want to have semi-auto weapons with different enforced maximum rates of fire.

Yeah, I’ve seen some instances of that myself, since I have macro button on my mouse that.

And @LaneFox that Editor UI also looks really sweet.
Well, I think I’m going with that way but I was just wondering where to put the script. Just put it on the gun?

Actually, I can handle all that. I just want to know how you make that Inspector GUI look so damn neat, @LaneFox . Could you show me a little of that code?

I’m curious as well- I’m rather used to using Editor scripts to adjust the display of exposed members in the inspector, but the way you have it organized looks like you use a half dozen options I didn’t even know existed.

Thanks =)

The Unity Editor is basically made out legacy GUI so you can make anything you see in the Editor. It’s pretty flexible, just a lot of trial and error learning how to properly use it.

The code is for Deftly, but I’ll share a snippet I made for displaying the Impact Tag section. I guess that’s probably what you’re eyeballin’?

void DisplayCompounds()
    {
        for (int i = 0; i < _x.ImpactTagNames.Count; i++)
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUI.indentLevel = 1;
            EditorGUIUtility.labelWidth = 95;

            _x.ImpactTagNames[i] = EditorGUILayout.TextField(i + ")Tag Name", _x.ImpactTagNames[i]);

            EditorGUILayout.EndHorizontal();

            if (_x.ImpactTagNames.Count > 0)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUIUtility.labelWidth = 30;
                _x.ImpactSounds[i] = EditorGUILayout.ObjectField("♫", _x.ImpactSounds[i], typeof(AudioClip), false) as AudioClip;
                _x.ImpactEffects[i] = EditorGUILayout.ObjectField("☼", _x.ImpactEffects[i], typeof(GameObject), false) as GameObject;
                GUI.color = Color.red;
                if (GUILayout.Button(ButtonRemove, GUILayout.Width(20f)))
                {
                    _x.ImpactTagNames.RemoveAt(i);
                    _x.ImpactEffects.RemoveAt(i);
                    _x.ImpactSounds.RemoveAt(i);
                }
                GUI.color = Color.white;
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Space();
            }
        }
    }

Deftly looks really good! It looks like exactly what I need. But I won’t use it since I like to code myself. Good luck with it.
It wasn’t just the impact tag I was surprised with, but how neat and organized the whole inspector seemed. You don’t see useless text fields which only require a number with 3 digits or so, but a neatly small field with next to it another field. I’m more wondering how you did that!

Well, once again good luck with Deftly. Put Deftly in your signature or something, advertise it a little more because if you don’t, you won’t really sell it!