Need some inventory advice

This has most likely been asked before, but I couldn’t find the information I wanted from the forum search.

This is more of a question about how to approach a situation than a specific scripting question, but I’m putting this in the scripting section because I will post code examples of what I come up with.

ANYWAYS

I’m at that point in my game where I am trying to implement an inventory system. I got the Inventory Tutorial from some website that has functional “bags” with drag and drop icons, etc. Works great.

My question is this: I am trying to figure out the best way to store item information and use it. I don’t know if I should create a generic item class and create weapons based off that class, in code, and reference it from there. (how would be the best way to do this?)

Or, if I should create a generic “item-class” script with variables exposed in the inspector. This way seems pretty quick, because I can just drag the script on an empty game object and fill in the needed information in the inspector. Also allows for easy tweaking of values.

So what would other people suggest in this situation? How would you approach creating items in your game and then using them?(weapons, potions, etc). I am sure there are a million ways to approach this, so any information from people who have already tackled this subject would be much appreciated.

My initial thought is to create a ‘weapons’ game object, and under that have a list of empty game objects named ‘long_sword’, ‘crossbow’, etc. Then just drag the generic ‘weaponsClass’ script onto the empty game object and fill in the information. Does this sound like a valid way to approach this?

Thanks for your time.

You could purchase the QuestIt!!? addon featured in the showcase section of the forums, is great for making custom quest lines but for your needs it also has a built in Item editor which lets you create weapons potions or whatever you want. it also comes with a basic inventory tot test the stuff out with the capability of drag and dropping items back into the scene.

Hmmm interesting, I will have to check that out. Thanks for the heads up :slight_smile:

Think about “collectables”… items that can be keep into a bag, are collectables, so each one must implement an interface.
Maybe you want use “tags” instead, but i suggest you to use interfaces and keep tags for other purpose (i discourage the use of tags).

If you have any knowledge at programming, maybe you understand me.

Of course, you need to store the items you pick up, so you must to write a manager to hold that information (manager… well, a simple class; hasn’t to be a singletone).

A collectable must supply the follow information:
Properties

  • Description: string
  • Quantity: int
  • Type: maybe an enumerable.

Methods

  • addCollectable: sum or substract the quantity of type.

So your manager could be an array of collectables or maybe arrayList or something like this.

I hope you undestand anything of what i suggest you.

Thanks Kokumo for the reply.

As far as my programming experience, I would say moderate. If theres something I am not sure how to do I can usually figure it out myself (for the most part).

For some reason this has my brain stumped. I know I am going to have to store the objects in an array for the action bar, so I guess I am getting hung up on the pros and cons of each approach.

If I put empty game objects into a group, each with a script that defines their name, damage, etc, then put those into another empty game object called weapon_library, I can iterate through its children and query their values. Seems good for a visual approach.

But if I am going to be storing it in an array, I would rather just hard code the values in a script somewhere, but thats where I am getting stumped on how to iterate through the items.

For example, say I have a sword equpied, its in slot 1 of my action pallet, and I click it. Where is the information for that sword contained? I know I have an array and index 0 would read “sword”, but how can I make a connection between the word “sword” and a stored item named “sword” with attributes and functions contained inside it.

Unless I am just approaching this wrong. Can you have an array of classes in Javascript? So array[0] = swordClass()?

Would be nice to have an items array, fill out all the information of any available items you could have in your game, with each index representing an item class, then when clicking on the sword button, it would iterate through the items array, find the one with the name and excute its attack() function, or something to that effect.

I guess im just not quite making the connection of how to approach this. Still need to check out Gamerdad81’s link tho, I bet it will answer some questions.

I can´t go deep into an explanation because i am at work, but i can tell you an array can store types.
Even if they are different objects, if they implement an interface, you will be able to store information in an array (type of interface).

I will be answer you when i reach home. :smile:

Honestly, i did not thought too much about this topic because personal issues; however i consider invertory items an important topic… someday i will need to implement it, and this thread could save my day.

We are going to leave aside some point like how to get the gameObject to be store into the inventory, because the implementation could be as many as you want; for example, your character could execute a trigger, or you could obtain the data through collision, or clicking (?) on an object.
I hope you understand anything of what i wrote :smile:.

What we need?
1- see the item in the scene
2- see a thumbnails when the item is inside of tha bag, inventory or whatever.
3- know about the type of that item, quantity and description.

First thoughts
We can handle the three point above exposed (?) with an empty game object as a father, and the 3d model of the item and a thumbnail of that item, as a sons of the empty game object.
The script which contains the information about the item could be attached to the father.

The idea of having 3d model and a thumbnail:

When the item is in the scene, the 3d model must be enabled and the thumbnails disabled, whereas if the item is in the inventory, the thumbnails must be enabled and 3d model disabled.

What happens when the character picks up the item?
First of all, the character needs to have an empy game object inside of its hierachy to use it as “bag”… a place where to store all the items.
The second issue is to have a manager which manage the information about the inventory, like items, quantities, types, etc.

Then, the logic would be:
1- pick the item
2- disable 3d model
3- check if the character have at least one of that item (if the manager has an arraylist, you probably will need to iterate it). If it doesnt (or hasnt… it is late and i get confuse xD), you will need to attach it to the bag.
3- If the item can’t be sumarized or it is new, you need to store it as a new item into the array list. Well, we didn’t talk about the implementation of the manager, but i think you get the idea. If the item can be sumarized, just increase its quantity.
Of course, all the information about the item (type, description, etc) must be held by the script attached to the empty game object, father of… you know.
4- show at inventory GUI, the thumbnail of the item.
Notice that it is good idea show the items according of the arragement in the array (sorry, realy… i get complicated writing in english). So, if your manager use an arrayList or something like that… just iterate it.

Well… basically… i think it would be my approach. Your work must be find a good implementation… as abstract as you can.
Feel free to ask :smile:

I hope you understand my words and the concept of what i want to say.

Thanks Kokumo for your reply.

What you said makes sense, and I have a few ideas now which I believe could work. I will work on coming up with a working example and post my progress. Hopefully it works as good in real life as it does in my head :slight_smile: lol.

Good for you :smile:!.. and for us too :P!

Sorry for my “numeristic” mistake under “What happens when the character…”, i put two 3 (and sorry for “sumarized”, i gues is wrong too, but you got the idea).

I would like to do a little correction… may be the second 3, must be at first place, because you need to check -first- if the manager has the item. If it hasn’t or the item exist but can’t be added (for example, you can store a couple of potion in the same slot, but you can’t store more than one weapon), you must add the currently item into the array or arraylist or hashmap, and of course into the bag (see first lines under “What happens when the character…”).
If the item exist and you can add more of that item into the same slot, you just need to increase the quantity, avoiding keep the gameObject item into the bag.

i created a basic item class
it looks like this:

public class Item : MonoBehaviour {
public string Name;
public string Typ;
public string Desc;
public Vector2 Size;
public string BuffDesc;
public Vector2 RE;
public Texture Img;
public bool Useable;
public bool equipable;
public float minDmg;
public float extraDmg;
public string DmgTyp;
public int[] stats = new int[10];
public bool Quest;
public bool isBuff;
public int Slot;
public string classuse;
public int max_count;
public GameObject effekt;
	public bool use(GameObject From){
		if(equipable){
			CharController C =From.GetComponent<CharController>();
			return C.anziehen(effekt,Slot,gameObject);
		}
		if(Useable){
			GameObject GO=Instantiate(effekt,From.transform.position,From.transform.rotation) as GameObject;
			GO.transform.parent=From.transform;
			return true;
		}
		return false;
	}
}

i manage my inventory with this script at the moment.
its part of my char_controller script so i will only post extracts, which are not that important
i am adding features all the time so it changes all the time :wink:
at the moment i am working with moveable items…

	public bool Tasche_add(GameObject GO, int count,int Slot){
		if(GO!=null  count>0){
			Item i=GO.GetComponent<Item>();
			bool r=false;
			int n=0;
			while(!r  n<25){
				if(Tasche_Item[n]!=null){
					if(Tasche_Item[n].Name==i.Name  Tasche_Item_n[n]!=Tasche_Item[n].max_count){
						r=true;
					}
				}
				n++;
			}
			if(r){ // Item ist bereits in der Tasche
				if(Tasche_Item_n[n]+count>Tasche_Item[n].max_count){
					Tasche_Item_n[n]=Tasche_Item[n].max_count;
					Tasche_add(GO,count+Tasche_Item_n[n]-i.max_count,0);
				}
				else{
					Tasche_Item_n[n]+=count;
				}
				return true;
			}
			if(Slot>0  Slot<25  !r){
				if(Tasche_Item[Slot]=null){
					Tasche_Item[Slot]=i;
					Tasche_Item_n[Slot]=count;
					return true;
				}
				return false;
			}
			else{
				int m=0;
				while(m<25){
					if(Tasche_Item[m]!=null){
						if(Tasche_Item_n[m]==0){
							Tasche_Item[m]=i;
							Tasche_Item_n[m]=count;
							return true;
						}
					}
					else{
						Tasche_Item[m]=i;
						Tasche_Item_n[m]=count;
						return true;
					}
					m++;
				}
			}
		}
		return false;
	}

this code is called when i want to add an item to the inventory…
it checks if is already in my bag and if yes if the stack is smaller then the max stack…

i hope it helps you…

It’s a kind of weird read deutsch, jeje :smile:!

I have a question: why item class has “use” method?.. an item doesn’t know how to be used; this work must be implemented by other script.
For example, class X asks to the item what kind it is, to determine how to use.

i have some public bools like Quest useable and so on
those tell me if it is a potion i can use,
a sword i can equip or an quest item i have to use for quest.

so if i call the use function, it checks what it is and then instantiate the “effekt” gameobject

this is for example my potion gameobject script:

public class Heiltrank_benutzung : MonoBehaviour {
public Item H;
private float heilung=10f;
private CharController C;
private Buff_controller B;
private float i=0f;
	void Start(){
		C= gameObject.transform.parent.GetComponent<CharController>();
		B= gameObject.transform.parent.GetComponent<Buff_controller>();
		B.Add(true,gameObject,H.BuffDesc,H.RE,"HoT",H.Img);
	}

	void Update(){
		C.reg(heilung*Time.deltaTime,"HP");
		i=i+Time.deltaTime;
		if(i>=2f){
			B.Fade(true,gameObject);
		}
	}
}

B is the buff controller displaying and managing all buffs.
if a buff fades he destroys the gameobject automaticly.

The most polished and overkill RPG inventory management system has to be Neverwinter Nights’ (the game from 2002).
http://image.gamespotcdn.net/gamespot/images/2002/pc/rpg/nwn/nwn_790screen003.jpg

In a nutshell, it had:

  • A tetris-like slot system (like Diablo)
    - A simple and clean paperdoll:
  • Picking up/dropping items from the ground
  • The Trade/Shop UI as sub-inventories, making the whole thing seamless.
  • Stackable items.
  • The option to split stacks in specific amounts.
  • The option to merge stacks of similar items.
  • Gold is a special stackable item which has its own slot (the gold amount) but otherwise interacts with the inventory interface seamlessly and can be picked/dropped and split in specific amounts
  • Most commands (split stack, equip, unequip, pick up, drop, use item) were accessible through a context-sensitive radial menu (right-click), on top of the drag drop which was also context-sensitive.
  • Item representations were split in up to three separate parts (3D models each with an associated 2D icon) for customization. For example, swords were split as blade, hilt and handle.

Food for thought.

Werewraith, i guess Fishypants want to know how to manage an item at “develop” level… the logic and the way to store data, i mean.
How inventory looks, it’s another issue :smile:

Zero_Quantum, although i didn’t think too much about it, i guess you are right about the need of having a method inside of the item to execute the effect.
It would be good idea to use an interface, because looks like your items (scripting level) are different, aren’t they?
Anyway, i guess you know what you need :smile:!.

Ok guys, heres a question for you:

If I define an item class, and reference that class for all my items through code, ( fill in all the information for them, like strength, durability, cost, etc ) if I wanted to either add or remove an attribute how involved would that be? Would I have to go through each entry and do it by hand or is there a faster approach?

Right now I wrote my own inspector window that has values that I can easily fill out, then on button click it creates an empty GameObject named whatever the item is named and parents it under an Items GameObject. It then attaches an ItemScript Component to each GameObject and fills in the values.

I like this approach because I can change the original script and have it propagate through all the items that I have created. If I add a new attribute, I can have a script that automatically iterates through the children and either sets the new attribute to a default value or have it ask what value I would like to enter.

Then on Start() I can read all the items into an array and use it from there.

Any thoughts?

I guess i understand, but i need to think more about it… and i am at work, so let me reach home to answer you :smile:!

Hey Guys,
Just wanted to follow up with this thread. I have been racking my brain to try and understand how I should approach spells, items, weapons, etc and access them through a button.

Well, I believe I have come up with a pretty elegant solution. BEHOLD THE POWER OF CLASSES! lol. I have gone through many iterations and I believe this one is the most flexible, and powerful that I have come up with so far.

I basically had to write my own button from scratch because (correct me if I am wrong) Unity’s button does not have a way to check when a button is pressed, if it’s being held down and when it is released. Only upon release is the button hit registered. There is the Repeat button, but that only evaluates to true if the mouse is actually OVER the button. Not so good for dragging things.

So my system supports an adjustable sticky drag and drop, meaning that you have to click down and drag the mouse a little bit for the button to disengage from its slot. This helps to keep from accidentally dragging a button when you only wanted to click it.

It also supports item swapping, so drag an item over another and it will swap them.

But one of the features I like the most is that you can restrict which items you want in certain bars. So if you had a menu where you wanted to equip a helmet, and you only wanted helmet buttons in that slot, its pretty easy to set it to do that.

In this example, the bottom bar can accept all items, but the top bar only accepts “Action” icons, (the fist action, and smiley action).

I also setup keyboard mappings so you can either click a button or press the corresponding keyboard button.

Here is the webplayer:
http://www.mikecookportfolio.com/unitystuff/test-build.html

What do you guys think? If anyone’s interested I can post the source code. Cheers!

Creating a wiki tutorial about the spell bar now:
http://www.unifycommunity.com/wiki/index.php?title=Creating_a_Drag_and_Drop_Spell_Bar#Step_3:_Creating_the_main_HUD_script

Not finished with it yet, but all the code is there to try out.