Hello everyone,
I am currently making my own inventory system in Unreal Engine 5 using Blueprints. And I would like some help about a problem I encounter.
Okay, so basically, in my InventoryComponent, I have an array of structure InventoryData that represents the items held in my inventory.
InventoryData:
- Class: Type MasterItem
- Amount: Type Integer
I used polymorphism to split my items into different classes that have different attributes. For instance, my class weapon has a ‘durability’ attribute that my consumable doesn’t have.
The question that has been keeping my mind busy is: How can I change the durability of an item? Since MasterItem is the parent class and does not have the ‘durability’ variable. Also, I would prefer not having to put it in my Master class.
I thought of using an object reference in my structure instead, but I don’t think it would work since I’m destroying the actor once I interact with it.
Anyway, if any of you would be kind enough to enlighten me, I would really appreciate that ^^
Have a good day
I’d probably just add the durability value to master item class, and have a bool in the struct for “can break?” or some such. Consumables could just ignore the durability then (or instantly set it to 0 the moment it’s used before removing from inventory array). Could also use the durability for multi-use consumables, like a potion you can drink from twice before it’s empty.
Either way, you’ll want the durability value in the inventory array structure if it’s not there already, may as well use it in the parent class for consistency.
I would also add some variables to master class even though some sub item classes won’t use them. And try to use some search ID from DataTable for static information. Like item name, description, icon… Save the minimal variable required.
class MasterItem
{
int Amount; // if item is an equipment, treat this as Durability, otherwise stackAmount
int ItemID; // to read DataTable for Damage,Speed,Armor,PotionEffect...
int EffectID; // if item is an equipment, read DataTable for Enchantment
int ColorID; // if item can have different color
}
class WeaponItem : MasterItem
{
int GetDurability(){return Amount;} // treat this as Durability
int GetItemID(){return ItemID;} // search DT_Weapon for MaxDurability, Damage, AttackSpeed...
int GetEffectID(){return EffectID;} // search DT_Enchant for Damage/Speed Modifier
}
class ConsumableItem : MasterItem
{
int GetItemID(){return EffectID;} // search DataTable for potion effect
}
You can optimize this by making getters as pure function and do memory alignment base on what variables you want to keep on masterItem.
Hello,
Thank you for you answer!
I see, but I used child classes specifically to avoid doing this and not having unused variables on all of my items.
Here’s a breakdown example:
I want to save the ammunition amount in the parent Firearms class because it is relevant only for firearms (Child of MasterItem). I would not like let’s say my misc items to have a “ammo” variable or a “durability” variable.
I don’t know if I am clear enough x) Don’t hesitate to ask for more details if needed and I appreciate every bit of help I can receive!
I can think of another way to achieve what you want doing some virtual functions of Get() from the child classes. But it would not be ideal because potentially having lots of virtual table to look up would be slow at runtime.
It is a matter of memory vs process speed. Having some extra variables in masterItem really matters little in terms of memory.
Not wanting unused vars in items makes sense, but if you need your inventory to display things like durability or ammo, they’re probably gonna need the value stored in the array’s structure somewhere anyway. May as well let the item class decide what to do with the value. In my most recent inventory system, weapons, armor, and food use a float with the vague name “statmod” in the item data table which defines the damage or healing done in the code depending on the context. The value wouldn’t be needed for something like a key, but it can be ignored there.
Info like durability or ammo could likewise be repurposed as charges or whatever for other items so that the inventory has all the info it needs to display everything. And hopefully without casting to every item sub-class every time. Wasting a few bits of data for one useless stat on an item is usually going to be cheaper than casting to a dozen classes every time you look at the inventory.
TLDR; I’d advise figuring out the minimum number of values the inventory itself needs to know for displaying/sorting things, and add values for that in the parent class and the struct used by the inventory’s array or map. IF a specific item doesn’t need the stat, just ignore it in the sub-class’ bp.
Hi,
So after a few days I went back on the project and did what you recommended me and adapted it to my needs.
I added a “StatMod” float variable to my BP_MasterItem and initialised it in the constructor of relevant child classes. (In my weapons classes, “StatMod” is actually the durability).
I also added the “StatMod” variable in the structure ‘Inventory’ data.
Once we interact with an item via an interface, I can jusr decrease the durability at my wish.
It works fine and I’m verry happy of the result!