- Home /
Using enums to design an inventory system?
I've been prototyping an idea for a game lately, which would include an RTS-esque base building component. I need to set up an inventory system that would keep track of various resources (water, food, building materials, etc.) as well as things like ammo counts, weapons, armor, etc. The issue is, I'm not entirely sure how to go about that, since I'm still relatively new to the coding side of things. That said, a lot of things I've read suggest using enumerators for something like this. Is that the best way to go about this? And if so, how would I go about implementing that? Enums are something I haven't really used a whole lot. Like I said, still mostly new to serious coding.
Answer by Lo0NuhtiK · May 24, 2015 at 06:09 AM
Saw your question in the mod queue and figured I'd throw together a quick example class with some commenting in it to try to help give you and whoever else stumbles across this thread an idea or two, and try to make sense of what's going on in the scripts as well. There's inventory questions and such all over the place, but this site is becoming such a pain in the @$$ to sift through to find what you're looking for that it's no wonder why the duplicates are steadily becoming more frequent over the past few years. ...anyway... hope this helps someone before it gets lost in the pile xD ... any questions about it that the comments don't help with, just ask and I or someone else will try to explain.
 using UnityEngine ;
 using System.Collections ;
 
 [System.Serializable]
 public class Inventory
 {
     [System.Serializable]
     //class we'll use for all [amount]'s of each of our inventory items that use them
     public class Amount
     {
         //the current amount of whatever that we have (eg: .45 ammo)
         public int current ;
         //the max amount we can carry
         public int max ;
 
         /// <summary>
         /// Adds [value] to [current] and clamps current between zero and [max]
         /// </summary>
         public void AddCurrent(int value)
         {
             current = Mathf.Clamp(current + value, 0, max) ;
         }
 
         //default constructor
         public Amount(){}
         //another constructor which sets [current] and [max]
         public Amount(int current, int max)
         {
             this.max = max ;
             this.AddCurrent(current) ;
         }
     }
 
 
     [System.Serializable]
     public class BuildingMaterials
     {
         //our building material types...
         public enum Types
         {
             Wood, Iron, SomethingElse, AnotherThing
         }
         //the type of building material this is
         public Types type ;
         //the amount of this
         public Amount amount ;
 
         //default constructor
         public BuildingMaterials(){}
         //...another constructor
         public BuildingMaterials(Types type, Amount amount)
         {
             this.type = type ;
             this.amount = amount ;
         }
     }
 
     [System.Serializable]
     //same concept as the BuildingMaterials class
     public class Consumables
     {
         public enum Types
         {
             Beer, Pizza,
         }
 
         public Types type ;
         public Amount amount ;
 
         //constructors-->
         public Consumables(){}
 
         public Consumables(Types type, Amount amount)
         {
             this.type = type ;
             this.amount = amount ;
         }
 
         public Consumables(Types type)
         {
             this.type = type ;
             this.amount = new Amount() ;
         }
     }
 
     //these two variables are what will "hold/contain" all of our values
 
     //an array of building materials
     public BuildingMaterials[] buildingMaterials ;
     //array of consumables...
     public Consumables[] consumables ;
 
     /// <summary>
     /// Adds [value] to [buildingMaterials] where buildingMaterial.type = [type]
     /// </summary>
     public void AddBuildingMaterial(BuildingMaterials.Types type, int value)
     {
         for(int i = 0 ; i < this.buildingMaterials.Length ; i++)
         {
             if(this.buildingMaterials[i].type != type) continue ;
 
             this.buildingMaterials[i].amount.AddCurrent(value) ;
             break ;
         }
     }
 
     /// <summary>
     /// Adds [value] to [consumables] where consumable.type = [type] ...
     /// </summary>
     public void AddConsumable(Consumables.Types type, int value)
     {
         for(int i = 0 ; i < this.consumables.Length ; i++)
         {
             if(this.consumables[i].type != type) continue ;
             
             this.consumables[i].amount.AddCurrent(value) ;
             break ;
         }
     }
 
     /// <summary>
     /// Initializes a new instance of the <see cref="Inventory"/> class.
     /// if(populate = true) then construct this class to have one of each BuildingMaterial.Types and
     /// ---one of each Consumable.Types.
     /// else just set buildingMaterials and consumables to be new arrays of zero-length.
     /// Note : since [populate] is an optional parameter, you can leave it blank when creating a [new Inventory()]
     /// </summary>
     public Inventory(bool populate = false)
     {
         if(!populate)
         {
             this.buildingMaterials = new BuildingMaterials[0] ;
             this.consumables = new Consumables[0] ;
             return ;
         }
 
         //get the names from our BuildingMaterials.Types Enum
         string[] names = System.Enum.GetNames(typeof(BuildingMaterials.Types)) ;
         //make this array have a spot for each type
         this.buildingMaterials = new BuildingMaterials[names.Length] ;
         //loop through for each type
         for(int i = 0 ; i < names.Length ; i++)
         {
             //set each item in the array's type as one of the types, and gave it an amount value as well
             this.buildingMaterials[i] = new BuildingMaterials((BuildingMaterials.Types) i, new Amount(0, 50)) ;            
         }
 
         //same as what we just did for BuildingMaterials.Types, but now doing it for our consumables-->
         names = System.Enum.GetNames(typeof(Consumables.Types)) ;
 
         this.consumables = new Consumables[names.Length] ;
 
         for(int i = 0 ; i < names.Length ; i++)
         {
             this.consumables[i] = new Consumables((Consumables.Types) i, new Amount(7, 24)) ;
         }
     }
 }
  
  
And here's even a test GUI script to help a bit more... just slap this on some object in your scene and push 'play' ...old GUI xD
 using UnityEngine;
 using System.Collections;
 
 public class Tester_CS : MonoBehaviour
 {
     //blank inventory just to show you how it works
     public Inventory inv_1 = new Inventory() ;
     //populated inventory ... we'll use this in the GUI example below.
     public Inventory inv_2 = new Inventory(true) ;
     
     Vector2 scrollPos ;
 
     void OnGUI()
     {
         scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.MinWidth(Screen.width), GUILayout.MinHeight(Screen.height)) ;
 
         //loop through our building materials array of inv_2
         for(int i = 0 ; i < inv_2.buildingMaterials.Length ; i++)
         {
             GUILayout.BeginHorizontal() ;
             //making a label with each materials type(name) and amount values
             GUILayout.Label(inv_2.buildingMaterials[i].type.ToString() + " : " + inv_2.buildingMaterials[i].amount.current + "/"
                             + inv_2.buildingMaterials[i].amount.max) ;
             //making a couple buttons to show increasing/decreasing amount values
             GUILayout.BeginVertical(GUILayout.MaxWidth(50f), GUILayout.MinWidth(50f)) ;
             if(GUILayout.Button("+"))//add value using the Add...() method 
                 inv_2.AddBuildingMaterial(inv_2.buildingMaterials[i].type, 1) ;
             if(GUILayout.Button("-")) //add value using the AddCurrent() method of the Amount class
                 inv_2.buildingMaterials[i].amount.AddCurrent(-1) ;
             GUILayout.EndVertical() ;
             GUILayout.EndHorizontal() ;
         }
 
         //doing the same as above, but with consumables now-->
         for(int i = 0 ; i < inv_2.consumables.Length ; i++)
         {
             GUILayout.BeginHorizontal() ;
             GUILayout.Label(inv_2.consumables[i].type.ToString() + " : " + inv_2.consumables[i].amount.current + "/"
                             + inv_2.consumables[i].amount.max) ;
             GUILayout.BeginVertical(GUILayout.MaxWidth(50f), GUILayout.MinWidth(50f)) ;
             if(GUILayout.Button("+"))
                 inv_2.consumables[i].amount.AddCurrent(1) ;
             if(GUILayout.Button("-"))
                 inv_2.AddConsumable(inv_2.consumables[i].type, -1) ;
             GUILayout.EndVertical() ;
             GUILayout.EndHorizontal() ;
         }
 
         GUILayout.EndScrollView() ;
     }
 }
 
Your answer
 
 
             Follow this Question
Related Questions
check if list contains item with matching string property 2 Answers
Database error updating inventory 0 Answers
Decorator pattern for inventory item class 0 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                