Weapon leveling suggestions...

In my game, I have a bunch of weapons that can be upgraded. The weapons don’t have xp or anything, think more of a clash of clans style weapon upgrade (when you have enough money you purchase the upgrade). My question is: what is the best way to change the stats?

If it were a player with xp, I would just create a function levelUp() and inside I would put attack+=2, defense+=3, etc. But I want to be precise and have control over each weapons’ stats for each level. This is mostly for balancing reasons, but I also think it will be easier to prevent hacking if I keep close track of weapon stats like this.

If I did a levelUp() function, I’d have a bunch of if statements for each level. Is this unavoidable? Is there a better way?

put the stats into a serialized class, give the weapons a list or those stats such that the index is the “level” those stats apply to. Then you just need a “currentLevel” int.

1 Like

that’s a whole different question… what are you making?

Ok I’ve never heard of a serialized class can you give a quick example?

It’s a multiplayer game I recently began making (don’t want to give away too much because what if I don’t follow through? lol) and I thought if I need to do server-side checks or whatever, that it would be easier if I had something to check against. Although I’ll admit that I’m very far from any of that stuff yet.

[Serializable]
public class WeaponStats
{
    public float attackStrength;
    public float defenceStrength;
}

public class Weapon : Monobehaviour
{
    public List<WeaponStats> weaponStats;
    public int currentLevel;
   
    void SomeFunction()
    {
        float bishbashbosh = weaponStats[currentLevel].attackStrength; // kapowie! kurrunch!! krrrtinkletinkle!!! :P
    }
}

without the “Serializable” decoration you might not see the list elements in the inspector to set them…

Oh that’s a lot more simple than I thought. Cool, I will go ahead and do this thanks!

@LeftyRighty it turned out to be more complicated. On one weapon object, I have two scripts attached (maybe more in the future): Gun.cs and Health.cs. The way you have the List in Gun.cs, I don’t see how I can give different health values at different levels, and at the same time keep Health.cs variables public so I can edit in the inspector. Unless you have an elegant solution I think I will just go ahead and make a prefab for each level of each weapon? I think this would total between 150-200 prefabs. That doesn’t seem bad (right?).

I have another question about this…would it be better to store this data in a database? If so how would I even go about doing that?

ok… why do guns have a health script? they blow up?

If you want to stick with the pattern you would probably want to split it into a script for holding and handling the most recent stats and have the other scripts reference the weapon’s stat script to receive the correct current values.

might want to look at scriptable objects, and maybe a little editor scripting

I don’t think I would start splitting up the weapon into multiple scripts. Keep all its data in one script, and if you need to have other objects access it add functions to let them get data, or possibly set it. Like this:

[Serializable]
public class WeaponStats
{
    public float attackStrength;
    public float defenceStrength;
    public float maxHealth;
}
public class Weapon : Monobehaviour
{
    public List<WeaponStats> weaponStats;
    public int currentLevel;
    public int currentHP;

    void SomeFunction()
    {
        float bishbashbosh = weaponStats[currentLevel].attackStrength; // kapowie! kurrunch!! krrrtinkletinkle!!! :P
    }

    public void GunTakesDamage(int dmg)
    {
             currentHp-= dmg;
              //  One way if the gun is in charge of blowing itself up
             if (currentHP <0)
                      BlowGunUp();

              //  or change the return type from void to int
              // and just return the currentHP and let the caller handle it
    }

   // we can call this internally, or have some GameManger tell us to level up
    public void LevelUp()
    {
               currentLevel++;
               // lets reset our gun health to max if we level up
                currentHealth = weaponStats[currentLevel].maxHealth;
     }

    // Maybe there are objects that repair our gun.  We could have outside scripts call this
    public void RepairGun( int hp)
     {
                currentHp += hp;
                if (currentHp > weaponStats[currentLevel].maxHealth)
                        currentHp = weaponStats[currentLevel].maxHealth;
      }
}

In my opinion, you should be making 1 prefab per gun type. If your doing more than that you should rethink your design. You’ll save a lot of time in the long run.

at this point it’s probably worth pointing out Interfaces: https://unity3d.com/learn/tutorials/topics/scripting/interfaces?playlist=17117

one script implementing a “weapon”, “levelable”, “repairable” and “damagable” interfaces might make sense… that approach can really come into it’s own, for example something like highlighting things in an inventory that can be repaired etc. (loads of other usages, just the one that came to mind)

The reason I don’t do that is because I want to pop Health.cs on anything I need to have health. Also it encompasses lots more than just a health int, for example invincibility, resistances, regen, etc.

The way you do it you have levelUp() as part of the Gun class. But if I make a bunch of prefabs for each level I can get rid of it altogether and, upon the purchase of the upgrade, swap prefabs in the player’s inventory.

Lol my guns have health since that’s just my game. Think a tank that has a bunch of weapons you can add on, and the tanks attack each other. I’ve thought about making a script for holding the stats. In that case, I would have a new script for each kind of gun. I’ve thought about interfaces, but I’ve been doing fine with just tags…and I don’t see how interfaces would solve this particular problem. And finally…I’ll look at scriptable objects and come back when I figure out what that is.