Inventories are a set of Item Collection objects. This makes more sense with an example. Let’s say that a character can have items in their bag, in their pocket, or even equipped with their hand. In this situation there would be three Item Collections: Bag, Pocket, and Equipped. When you create an Inventory you can set as many Item Collections as you want and you can name and can give them a purpose by flagging them. The Item Collection names need to be unique and an Inventory must have at least one Item Collection.

In the inspector you can create new Item Collections and change their type. The Item Collection page contains more details about how Item Collection objects work. When an Item Collection is selected in the Inventory a list containing the Item Amounts within the collection will be shown. Selecting an Item Amount allows you to edit it. Press the “Change” button to select a new item. You can edit the Item Attributes directly in the Inventory inspector.

When selecting an item in the list field it is useful to know about the search and sort options. The list has a search and sort fields which allows you to quickly find the item you are looking for. There are even special tokens you can write in the search field to filter by category or attribute name:

Example

  • “a:MyAttribute”: Fetch all items which have the “MyAttribute” attribute.
  • “c:MyCategory”: Fetch all items that inherit the category “MyCategory”.
  • “str c:Weapon a:Attack”: Fetch all items that contain the substring “str” in their name, inherit the “Weapon” category and have the “Attack” attribute.

The Inventory will show you the items in your Item Collections in real time. This makes debugging easier as you can quickly check where items are located. You can even change item attribute values (no event is sent when an attribute is changed in the inspector).

The Inventory class is a MonoBehaviors so you can add it on any GameObject. It is used in many different cases:

  • Character inventory.
  • Enemy inventory.
  • Shop inventory.
  • Chest inventory.
  • Storage Inventory.
  • Pickup inventory.
  • And many more.

We recommend that you use the Inventory component for any use case that requires a collection of items.

Inventory API

Once you have an Inventory you may add/remove and retrieve the items stored in it. When using inventories we use item infos a lot as they contain more information about the item such as its amount, its item stack, item collection inventory, etc…

// Get all the items in the inventory (includes all the item collections except the ignored ones 'Hide' and 'Loadout')
var allItems = inventory.AllItemInfos;

// Add an item to an inventory by name.
m_Inventory.AddItem("potion", 5);
// Remove an item to an inventory by name.
m_Inventory.RemoveItem("potion", 3);

//The commands above a very simple, but there may be times where you wish to have control on where the item is added/removed.

//Find your item definition.
var myItemDefinition = InventorySystemManager.GetItemDefinition("MyItemDefinition");
//Create an item from that definition.
var myItem = InventorySystemManager.CreateItem(myItemDefinition);

//Or you can directly create an item from the item definition name.
var myOtherItem = InventorySystemManager.CreateItem("MyOtherItemDefinition");

//Make your item Info, Note double (( )) the (1,myItem) is an itemAmount.
//Note: ItemInfos can have a reference to the item stack and the itemcollection/inventory where the item comes from.
var myItemInfo = new ItemInfo( (1,myItem) );
inventory.AddItem(myItemInfo);

//Alternatively you can directly cast the item amount to an item info both are structs not classes.
//Note: It returns the item info added, this allows you to know the amount of item added and in which stack it was added to. 
var itemInfoActuallyAdded = inventory.AddItem((ItemInfo) (1, myItem));

//The line above is equivalent to adding an item directly to the main item collection.
inventory.MainItemCollection.AddItem((ItemInfo) (1, myItem));

//If you wish to add an item to another item collection you can get it index, purpose or name.
inventory.GetItemCollection(ItemCollectionPurpose.Equipped).AddItem((ItemInfo) (1, myItem));

//You can get the first matching item stack to an item.
var retrievedItemInfo = inventory.GetItemInfo(myItem);
if (retrievedItemInfo.HasValue == false) {
    //No item stack with that description was found in the inventory.
}

//We can remove items from an inventory and it returns the item info that was actually removed.
var itemInfoRemoved = inventory.RemoveItem((ItemInfo)(1,myItem));

//Specifying an item info that has a reference to an item stack will remove from that stack first, if possible.
inventory.RemoveItem(retrievedItemInfo.Value);

//We could have chosen to remove a different amount, than the amount retrieved.
inventory.RemoveItem( (1,retrievedItemInfo.Value) );

//You can get multiple items from your item collections
//You'll need an array to store your item infos.
var array = new ItemInfo[0];
//You can use a pooled array instead of creating a new array each time. IMPORTANT: make sure to return the pooled array once you finished using it.
var pooledArray = GenericObjectPool.Get<ItemInfo[]>();

//Set your filter and sort parameters, for this example we'll filter by category.
var filterParameter = InventorySystemManager.GetItemCategory("MyCategory");

//Item info list slice will have all the itemInfos in the inventory that contain inherits the category.
//You can set whatever filter parameter you want.
var itemInfoListSlice = inventory.GetItemInfos(ref pooledArray, filterParameter,
    //Specify your filter
    (candidateItemInfo, category) => { return category.InherentlyContains(candidateItemInfo.Item); }
);

//IMPORTANT: Don't forget to return the pooled array once you finished using the array.
GenericObjectPool.Return(pooledArray);

You can filter and sort the items retrieved with the GetItemInfos function:

ListSlice<ItemInfo> GetItemInfos<T>(ref ItemInfo[] itemAmounts, T filterSortParam,
    Func<ItemInfo, T, bool> filterFunc, Func<T, Comparer<ItemInfo>> sortComparer, int startIndex = 0)

This function is generic so you can set the exact filter parameters you want no matter the type.