Inventory with Upgradable Items and Varying Stats

Hello,

I created an inventory system following this tutorial series: Items & Inventory in Unity (pt.1) - Start Simple - YouTube

The problem with this tutorial, as well as all the other inventory tutorials I’ve been able to find, use scriptable objects as the items. This is fine for items that have stats that don’t change, but for my game, the equipable items will be generated with a range of random stats (similar to Diablo) and players will also be able to upgrade these items multiple times to increase its stats. So using scriptable objects for this won’t really work since the stats change.

I tried creating a GameObject and having a MonoBehaviour on that object for storing the current stats, etc., but I can’t store that into the inventory because it wants an Item class. It also doesn’t seem like a good idea to store GameObjects because then I would need to use GetComponent() on each GameObject every time I want to retrieve the item’s stats. There has to be a better way to do this, but I’m having trouble finding what that is. The creator of that tutorial series hasn’t been answering people’s questions, so I’m not sure how he would handle this issue.

The design is really nice in that I can easily create multiple inventories/bank and different item types, but what I really need is something that can also store items with dynamic stats. Anyone know a good way to convert this inventory system to be able to do that? Thanks in advance.

Hello, @Arithan!

Everything depends on how you make scriptable object for items!

If you make it as item object - then yes, its not fit you. But you can make it as 'template" for item and then use it in separate class.

I mean, in scriptable object you can set min and max damage, sprite, item color, or a set of colors, which will depends on item “level”. If item is level 0, then it has min damage, if item is level 1, it has min + 5 damage and so on.

After you will make your “template” scriptable object, you can create a new pure class (without mono behaviour and etc)

and use that new class instead of scriptable object! You also can access Scriptable object from Item class, if needed (to show image or something else)

I made small example, where TemplateItem is a scriptable object.

example of Item class, I made two constructors, to show how it can be used:

public class Item
{
   public float damage;
   public float cost;
   public float mass;

    public TemplateItem item { get; private set; }

   public Item(TemplateItem tempItem)
   { //tempItem is your scriptable object template
      this.item = tempItem;
      this.damage = tempItem.minDamage + Random.value *
 (tempItem.maxDamage - tempItem.minDamage);
      this.cost = tempItem.baseCost + Random.value * tempItem.randCost;
      this.mass = tempItem.mass;
   }

   public Item(TemplateItem tempItem, int level)
   { //tempItem is your scriptable object template
      this.damage = tempItem.minDamage + level * tempItem.lvlDamage;
      this.cost = tempItem.baseCost + level * tempItem.lvlCost;
      this.mass = tempItem.mass + level * tempItem.lvlMass;
   }
}

Can’t you just make a new scriptable object for the randomly generated items using the normal scriptable object as the base?

1.) Spawn new scriptable object
2.) Set its stats equal to the base stats of the randomized object
3.) Add randomness to the new scriptable object

I don’t remember how to make a new scriptable object off the top of my head but something like

new ScriptableObject RNGHammer;
RNGHammer = NormalHammer;
RNGHammer.attack += Random.Range(0, 10);