Excellent - let’s start with Item, I’ll just translate most of what you had into C#:
using UnityEngine;
public class Item : MonoBehaviour
{
public string Name;
public string Description;
public ItemType ItemType;
public Rarity Rarity;
public Texture2D ItemIcon;
}
public enum ItemType
{
Weapon,
Ammo,
Medical,
Other
}
public enum Rarity
{
Uncommon,
Common,
Rare,
UltraRare
}
It seems you already have some programming knowledge/experience, so I’m going to assume most of this is self-explanatory to you. But do ask whatever questions happen to pop up, no matter how simple or inane they may seem. For now I’m just going to start honing in on your specific concern of adding a variable to an object depending on ItemType.
Technically, you can’t. There, that was simple, right? Ok, there are different ways to implement this but first let’s think a little bit about what is happening underneath the hood when we write code: Although Unity refers to the code you write as a “script”, this is a bit of a misnomer. In computer science, a script is something that is interpreted by a program during execution vs. compiled into something that can be executed (this is an oversimplification when applied to managed languages like C#, but let’s not get into that yet). When you write code you’re just writing text that isn’t really going to do anything until it’s been compiled into an executable form. And for that to happen you have to adhere to the rules of the language that the compiler itself has been programmed to follow.
I bring that up because even though it makes logical sense to say “If this item is a weapon, add a damage variable to it”, the compiler (in C# at least, JS is a funky monkey) isn’t really going to see it that way. Look at the above definition for the Item class - we’re essentially telling the compiler: “I’m defining that there’s such a thing as an Item object with these fields (given their accessibility, type, and names)” and the compiler says “Cool, I understand dat.”
But now you essentially want to add an integer field named “Damage” for items that are of a weapon type. This is a problem because an Item has already been defined, and its definition did not contain a field named “Damage”. The compiler has no way of knowing, at compile-time, that if an instance of an Item has an ItemType of Weapon it should add a new field to that Item’s definition, but not to other Item definitions - it doesn’t make sense as we’ve already defined Item for the compiler the way we did - with no field named “Damage”.
SO - we could simply add “Damage” to the Item class’ definition, which will add a “Damage” variable to all Item instances, and choose to ignore it for Items that are not of a Weapon ItemType - but that kind of practice will produce bloated and confusing code very quickly. You might still want to do that in some instances, but it shouldn’t be an actual practice. What we really want to think when we think about “adding” to an object’s definition, is an entirely new definition of an object.
Now look at this:
public class Weapon : Item
{
public int Damage;
}
We’ve now defined a new object definition called “Weapon” and are telling the compiler: “The definition for Weapon is derived from the definition for Item” or “A Weapon is a type of Item.” By deriving from something by using the “:” symbol after a class declaration, that class will inherit the fields, properties, and methods of the thing its deriving/inheriting from. Weapon instances will have the same fields as Item (like Name, Description, ItemType [which is a problem now], etc.) and “add” to it a Damage integer field.
What’s useful about this is that we can refer to a Weapon instance as an item as well. Consider the following:
public class Inventory : MonoBehaviour
{
private Item[] Items;
private void Start()
{
Items = new Item[]
{
new Item(),
new Weapon()
};
}
}
Note that in the Start method we create a new array of Item and put both a new Item and a new Weapon instance in it. This is totally allowable in the language and really cool, but don’t do this in Unity as Item is inheriting from MonoBehaviour and a MonoBehaviour should never be newed up in this way.
I know that’s alot to take in - you should have many questions at this point, yes?