InventoryMetadata is a powerful system in Ultimate Grid Inventory (UGI) that allows you to add dynamic properties and behaviors to your inventory items. Unlike static properties defined in ItemDataSo scriptable objects, metadata provides runtime-specific data that can change during gameplay.
The base class that all metadata types inherit from. It provides:
A reference to the associated ItemTable
Initialization and lifecycle methods (Init, Awake, EvictLoad)
// Basic structure of the base InventoryMetadata classpublic class InventoryMetadata{ [NonSerialized] public ItemTable ItemTable; public void Init(ItemTable item) { ItemTable = item; Awake(); } public virtual void Awake() { } public virtual void EvictLoad() { }}
The StaticMetadataCreator class automatically creates and assigns the appropriate metadata type based on the item's data type:
// How metadata is created based on item typeprivate static InventoryMetadata CreateInstancedMetadata(ItemDataSo itemDataSo){ return itemDataSo switch { ItemContainerDataSo => new ContainerMetadata(), ItemStackableDataSo => new CountableMetadata(), _ => new InventoryMetadata() };}
This happens automatically when an item is created, ensuring that each item has the appropriate metadata for its type.
You can access an item's metadata through its InventoryMetadata property or using the generic GetMetadata<T>() method:
// Direct access to the metadata propertyvar metadata = itemTable.InventoryMetadata;// Using the generic GetMetadata method (recommended)var countableMetadata = itemTable.GetMetadata<CountableMetadata>();
// Example: Checking if an item can be stacked and combining stackspublic bool TryCombineItems(ItemTable targetItem, ItemTable sourceItem){ var targetMetadata = targetItem.GetMetadata<CountableMetadata>(); if (targetMetadata == null) return false; // Not a stackable item return targetMetadata.Combine(sourceItem);}// Example: Splitting a stack in halfpublic void SplitItemStack(ItemTable stackableItem){ var metadata = stackableItem.GetMetadata<CountableMetadata>(); if (metadata != null) metadata.SplitHalf();}
// Example: Getting all items from a containerpublic List<ItemTable> GetItemsFromContainer(ItemTable containerItem){ if (containerItem.InventoryMetadata is not ContainerMetadata metadata) return new List<ItemTable>(); return metadata.GetAllItems(false); // Pass false to get only direct items, or true for recursive retrieval}// Example: Adding an item to a containerpublic bool AddItemToContainer(ItemTable containerItem, ItemTable itemToAdd){ var metadata = containerItem.GetMetadata<ContainerMetadata>(); if (metadata == null) return false; var result = metadata.PlaceItemInInventory(itemToAdd); return result == GridResponse.Inserted;}