- Home /
Item database with override functions
Hi. What is the best way of creatin item database, which supports "Individual items"?
For example, I was using scriptable object for quite time. You can create an item struct and change values of them. But what if item has not only different stats, but also different function?
For example:
public class ItemConsumable{
public string name;
public virtual void consume()
{
Debug.Log("You have consumed:" + name);
}
}
//Alchogol
public class alchogol : ItemConsumable
{
public alchogol()
{
name = "Alchogol";
}
public override void consume()
{
base.consume();
Debug.Log("You go drunk");
}
}
As you can see, the alchogol class overrides ItemConsumable's "consume" function. What is the best way to "Store" items of that type? Can theese classes somehow be added to an array of classes? Thanks.
Derive all your item types from your base class, but remember you are misusing OOP if you create a separate class for each item, ins$$anonymous$$d create re-usable item types that inherit from your master type. If you need to define small amounts of extra data, it may be better to create an enum, like so
public enum ConsumableType
{
Potions,
Alcohol,
StrongAlcohol,
Water
}
Afterwards you can store any number of items in arrays, lists, etc, based solely on the base class. For example:
public ConsumableType consumableType;
public List<ItemConsumable> items;
public int effectLevel;
public void AddItem(ItemConsumable item)
{
items.Add(item);
}
// THIS IS AN EXA$$anonymous$$PLE, NOT A SUGGESTED USAGE
public void AddAlcohol()
{
AddItem(new Alcohol());
}
And for the enum example
public override void consume()
{
base.consume();
if (consumableType == ConsumableType.Alcohol)
{
Debug.Log("Drank alcohol");
someClass.DrunkEffect(effectLevel);
}
else if (consumableType == ConsumableType.Potion)
{
Debug.Log("Drank Potion");
someClass.HealEffect(effectLevel);
}
}
But what if there are a lot of individual objects, and each of them has an override for base function? Creating that much enums would be such a mess.
I assume that it can be much easier with "itemStorage[n].use" or so, but is it possible to somehow add all of the classes declared into some sort of an array - the itemDatabase?
Define what you mean by "store". If you want to store and use them at runtime in a generic manner the answer is "Yes". If you mean by "store" to store them on disk / inside a savegame file it gets way more complicated. The point of inheritance is to provide a general interface for all derived objects and each object might implement it's own logic.
If you have a List or array of type "ItemConsumable" you can store any derived object in that array and you can use all the methods that the base class provides. So in case of your "consume" method it would work just fine.
ItemConsumable[] itemArray;
itemArray[1].consume();
Here we use the general interface that the base class provides. We don't have to know what actual class is stored at index 1. So based on what object is stored there you might execute different code automatically. That's why we call it polymorphism
Yes. I mean storing them as classes for further usage. For example
public class $$anonymous$$agical Chest : $$anonymous$$onoBehaviour
{
GameObject preciousLoot = Instantiate(**ItemGameobject, take a look below**)
itemObject = preciousLoot.addComponent<ItemObject>();
itemObject.itemReference = **This one! That "Individual" item class**;
}
Now, the item object:
public class itemObject : $$anonymous$$onoBehaviour
{
public itemClass item;
public void onUse(Gameobject Consumer)
{
item.consume(Consumer);
}
}
Now you can see what am I trying to reach. The "base" is nothing but a empty gameobject, which contains only blank functions that are redirected to functions of a referenced item. If you call "Use" on this - it will warn the "itemClass" variable (Which can be a special item that I mentioned in my previous posts) and then, in the class of that object magic happens.
$$anonymous$$AIN PROBLE$$anonymous$$. THE REASON WHY I HAVE CREATED THE TOPIC:
The main problem is - I don't know how to GET the classes from item classes script and put them into itemClass variable.
Short answer? You have to write editor extensions for creating and editing data. Really writing editor extensions should be common practice for all Unity devs. The editor is by nature, limited to specific things, it is up to us to extend its capabilities to fit our needs.
Your answer
Follow this Question
Related Questions
Problem accessing enum from other class 1 Answer
Inventory Management Issue 2 Answers
A question about creating items using scriptable objects 1 Answer
Managing Item Types 1 Answer
About Classes in js 2 Answers