Inventory Manager

6 min read

Updated on November 26, 2025

Introduction

This component handles the Global Storage Solution and also the inventory UI. This is also a required component for the system to work, so one must be placed under a Canvas.

Setting up

There is a prefab Inventory_UI located in /prefabs/UI.

Setting up without the prefab otherwise is a little more complicated, as it would involve creating all the working parts of the inventory. The two main working parts are the InventoryItemSlots and the ItemAmountInfoPanel.

You can find prefabs for the two individual components in /prefabs/UI called InventorySlots and ItemAmountInfoPanel. If you decide you do not want slots or the ItemAmountInfoPanel then you do not need to have them. The only required part is this component itself.

This component should be placed under a Canvas.

Global Storage Solution

Think of this as a sorting depot, it recieves the ItemAmounts it needs to store, and then figures out which ItemContainer it should be placed in based on the chosen settings.

All ItemContainers by default are set to be included in this solution, but on ItemContainer there is an option for ‘Include In Global Inventory’ which is enabled by default. By disabling this, the Inventory will not use this ItemContainer.

Settings

All Items
All Item Scriptable Objects should be added into this List to ensure correct Item finding.

Selection Method
There are 4 methods, each will order the ItemContainers based on these and return the best fit for the Selection Method chosen.

Priority – On each ItemContainer there is a ‘Priority’ setting. Selection will pick higher numbers first. So if you had for example a specific ItemContainer that needed filling first, you could given that Priority 10, while the others could just be the default value.

Distance – Selection is made based on where the ItemAmount has come from (ResourceNode or Crafter transform) to the nearest ItemContainer.

Random – Selection is made completly randomly.

Default – You can assign some default containers, and selection will simply go through this list in order of the ItemContainers in the list.

Default Containers
The default containers to use for the Default Selection Method.

Display Type
This describes how the ItemAmounts are displayed in the Inventory UI panels.

Consolidated – All ItemAmounts will appear in the same stack. For example, if you had 5 x Log in one ItemContainer and 7 x Log in another, then the Inventory UI would simply show 1 InventoryItemSlot with 12 x Log.

Item Stack Size – All ItemAmounts are broken up into there respective stack sizes. Using the example above – If Log had a stack size of 5, you would see 3 InventoryItemSlot’s with 2 of them containing 5, and the other containing 2.

Inventory Panel
Assign the Inventory Panel to open and close when Inventory Input is triggered.

Item Amount Info Panel
Assign the ItemAmountInfoPanel gameobject. This is basically the ItemAmount info screen. On here you can see various things like amount, value, stack size, and also the option to sell the ItemAmount via a slider.

Slots
These are the InventoryItemSlots needed to display the UI ItemAmounts in the Inventory Panel. You should assign a reasonable amount to never run out of slots. (Make enough for your max inventory size).

Close Btn
The Button component to assign to close the Inventory UI window.

Event

Sell Item Amount Event
Triggers when an ItemAmount is sold via the Item Amount Info Panel.

Scripting

//Action

//Triggers when an ItemAmount is sold via the Item Amount Info Panel
public Action<double> SellItemAmountAction;

//Example 
public void Start 
{
    Inventory.Instance.SellItemAmountAction += (currency) => AddToPlayerMoney(currency);
}

/// <summary>
/// Return the Item Scriptable Object from a given ID
/// </summary>
/// <param name="id">The ID of the Item</param>
/// <returns>The Item Scriptable Object</returns>
public Item GetItemByID(int id)

/// <summary>
/// Stores an ItemAmount across all available containers based on Selection Method
/// </summary>
/// <param name="itemAmount">The ItemAmount to store</param>
/// <param name="sourcePosition">The position of where the ItemAmount came from - best used with the Distance Selection Method</param>
/// <returns>The remainder not stored, 0 if fully stored</returns>
public double AddItem(ItemAmount itemAmount, Vector3? sourcePosition = null)

/// <summary>
/// Removes an ItemAmount across all available containers based on Selection Method
/// </summary>
/// <param name="itemAmount">The ItemAmount to remove</param>
/// <param name="sourcePosition">The position of where the ItemAmount is - best used with the Distance Selection Method</param>
public void RemoveItem(ItemAmount itemAmount, Vector3? sourcePosition = null)

/// <summary>
/// Registers an ItemContainers to be used by the Inventory Manager
/// </summary>
/// <param name="itemContainer">The ItemContainer to register</param>
public void RegisterItemContainer(ItemContainer itemContainer)

/// <summary>
/// Removes an ItemContainer from the Inventory Manager list
/// </summary>
/// <param name="itemContainer">The ItemContainer to remove</param>
public void UnRegisterItemContainer(ItemContainer itemContainer)

/// <summary>
/// Get a List<ItemAmount> of all stored ItemAmounts in all ItemContainers that are registered
/// </summary>
/// <param name="itemContainer">The ItemContainer that will be checked if specified</param>
/// <returns>The ItemAmount List of all ItemContainers</returns>
public List<ItemAmount> GetAllStoredItemsList(ItemContainer itemContainer = null)

/// <summary>
/// Get a Dictionary<Item, double> of all stored Items and there amounts in all ItemContainers that are registered
/// </summary>
/// <returns>A dictionary containing all owned Items and there amounts</returns>
public Dictionary<Item, double> GetAllStoredItemsDictionary()

/// <summary>
/// Get a Dictionary<Item, double> of all stored Items and there amounts in a specified ItemContainer
/// </summary>
/// <param name="itemContainer">The ItemContainer that will be checked</param>
/// <returns>A dictionary containing Items and there amounts in the given ItemContainer</returns>
public Dictionary<Item, double> GetAllStoredItemsDictionary(ItemContainer itemContainer)

/// <summary>
/// Do all of the registered ItemContainers contain at least or more of each of the blueprint materials
/// </summary>
/// <param name="blueprint">The blueprint for which the materials are checked against</param>
/// <returns>Whether the Inventory System has enough materials for the blueprint</returns>
public bool CanFulfillMaterials(Blueprint blueprint)

/// <summary>
/// Removes all materials using the Inventory Manager storage system based on the Selection Method
/// </summary>
/// <param name="blueprint">The blueprint for which the materials are checked against</param>
/// <param name="sourcePosition">The position of where the blueprint came from - best used with the Distance Selection Method</param>
public void TakeMaterials(Blueprint blueprint, Vector3? sourcePosition = null)

/// <summary>
/// Get an ItemContainer can that store ALL of the given ItemAmount
/// </summary>
/// <param name="itemAmount">The ItemAmount to be stored</param>
/// <param name="sourcePosition">The position of where the ItemAmount came from - best used with the Distance Selection Method</param>
/// <returns>The ItemContainer that can store the ItemAmount, returns null if none are possible</returns>
public ItemContainer GetStorableItemContainer(ItemAmount itemAmount, Vector3? sourcePosition = null)

/// <summary>
/// Sell an ItemAmount and trigger the SellItemAmountAction<double> - Hook into this to return the sold value - Currency = itemAmount.amount * itemAmount.item._value
/// </summary>
/// <param name="itemAmount">The ItemAmount to sell</param>
public void SellItemAmount(ItemAmount itemAmount)

/// <summary>
/// Open the Item Amount Info Panel with the given InventoryItemSlot
/// </summary>
/// <param name="inventoryItemSlot">The InventoryItemSlot to use to display</param>
public void OpenItemAmountInfoPanel(InventoryItemSlot inventoryItemSlot)

/// <summary>
/// Refresh the Inventory without any parameters
/// </summary>
public void RefreshUIGlobal()

/// <summary>
/// Update the Inventory UI display based on the Display Type
/// </summary>
public void RefreshInventoryUI(ItemContainer itemContainer = null)

/// <summary>
/// Open or close the Inventory panel
/// </summary>
/// <param name="visible"></param>
public void SetInventoryPanelVisible(bool visible)

/// <summary>
/// Is the Inventory open
/// </summary>
/// <returns>true for open</returns>
public bool IsInventoryOpen()

/// <summary>
/// Toggle the Inventory panel depending on its current active state
/// </summary>
public void ToggleInventoryPanelVisible()