Inventory

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…

For Events on the Inventory component check out the EventNames.cs file. To learn how to use those events please refer to the events page.

Get All Items
// Get all the items in the inventory (includes all the item collections except the ignored ones 'Hide' and 'Loadout')
var allItems = inventory.AllItemInfos;
Add and Remove by name
// 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);
Check if the inventory has an item
// Check if the inventory has an item. by using an item definition amount
m_Inventory.HasItem( (1, itemDefinition) );
Create items from item definitions
//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 an ItemInfo from an item

The commands above a very simple, but they are also quite limited. Some times more control is necessary. Especially when using unique items and or Multi Stack Item Collections.

//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));
Add and Remove using ItemInfo
//The line above is equivalent to adding an item directly to the main item collection.
inventory.MainItemCollection.AddItem((ItemInfo) (1, myItem));
Get an Item Collection

It is recommended to define item collections by unique names. You can use the name to get the item collection from the inventory.

// Get an Item Collection by name.
var itemCollection = m_Inventory.GetItemCollection("Item Collection Name");
// if your item collection is of a specific type simply cast it
var itemSlotCollection = m_Inventory.GetItemCollection("Equipment") as ItemSlotCollection;
Check if an item can be added

When using Item Restrictions you can restrict items and prevent them from being added to the inventory.

The return nullable Item Info can either be null if the amount cannot be added, or it will have the amount that can be added. In some cases the amount may be different thant the item to add since some of the amount might fit but not all of it.

//create the Item Info you plan to add.
var itemInfoToAdd = (ItemInfo)(5, myItem);
var itemCollectionToAddTheItemTo = inventory.GetItemCollection(ItemCollectionPurpose.Equipped);

// Check if the item can be added, the return type is a ItemInfo? (The ? means it is NULLABLE).
var canAddItemResult = itemCollectionToAddTheItemTo.CanAddItem(itemInfoToAdd);
if(canAddItemResult.HasValue){
	if(canAddItemResult.Value.Amount == itemInfoToAdd.Amount ){
		// The Item Amount can be fully added.
	}else{
		// The Item can be added but only partially.
	}
}else{
	// The item cannot be added.
}
Get an Item Icollection from the inventory
// If you wish to add an item to another item collection you can get it index, purpose or name.
var myItemCollection = inventory.GetItemCollection("MyItemCollectionName");
// Some ItemCollections may have a custom type. Simply cast it to the known type
var equippedItemCollection = inventory.GetItemCollection(ItemCollectionPurpose.Equipped) as ItemSlotCollection;
// Then you can add item directly to that collection.
equippedItemCollection.AddItem((ItemInfo) (1, myItem));
Get an Item Info from the inventory
//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.
}
When removing items get the reference to the Item Stack where the item was removed from.
//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) );
Get a list of items within the inventory using a filter
//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.