- 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