How to Make an Inventory System in UE5 Blueprints
An inventory is really three things wearing one name: a data model (what an item is), a container (what you’re holding), and a UI that mirrors the container. Blueprints handle all three — the trick is keeping them separate so each stays simple.
What it’s made of
Variables
An Item struct (name, icon, stack count, max stack — or a Data Table row handle so item definitions live in a table), and an array of that struct as the inventory itself, usually on a component so any actor can carry one.
Events
AddItem and RemoveItem as functions on the inventory component, an OnInventoryChanged Event Dispatcher the UI listens to, and an Interact input (or overlap) on pickup actors that calls AddItem then destroys the pickup.
The logic
AddItem: loop the array with ForEachLoop looking for a matching, non-full stack — if found, write the increased count back with Set Array Elem at that index (the loop’s element pin is a copy for struct arrays, so editing it does nothing); otherwise Add a new entry (Branch on a capacity check first). Fire OnInventoryChanged after any mutation; the widget rebuilds its grid from the array rather than tracking changes itself.
Key nodes you’ll wire
The mistake that breaks it
Building the logic inside the UI widget. The inventory must live on a component/actor — widgets get created and destroyed, and an inventory that dies with its window is a bug factory.
New to how Blueprint systems fit together? Read the anatomy of a Blueprint system first.
Or skip the wiring — generate it
BlueprintStudio builds this system from a plain-language prompt — the right nodes, exec and data pins wired, defaults set — and tells you whether it is ready to paste or what to set up first. The prompt is prefilled:
Build “Inventory System” in BlueprintStudioPrompt variations to try
Paste it into your Blueprint, or apply it with the free Cosindra desktop app (Windows & macOS).
Common questions
Why don’t my struct changes save inside a ForEachLoop?
Because the loop’s element pin hands you a copy for struct arrays — Set Members in Struct on it edits the copy and throws it away. Keep the loop’s index pin, build the modified struct, and write it back with Set Array Elem at that index. That one node is the difference between stacking that works and stacking that silently does nothing.
What do I gain from a Data Table over a plain struct for items?
Separation of definition from instance. Name, icon, and max stack belong in a Data Table so designers edit rows, not Blueprints; the inventory array then stores only instance state — a Data Table Row Handle plus a current stack count. Copy the full definition into every carried item instead, and a later icon change means touching every save file and every placed actor.
How do I refresh the inventory widget when an item is added?
Fire the OnInventoryChanged Event Dispatcher from the component after every mutation and bind to it in the widget’s Event Construct. The handler clears the grid (Clear Children on the Wrap Box or Uniform Grid Panel), then loops the array doing Create Widget + Add Child per slot. Rebuilding from data beats patching slots incrementally — it can never drift out of sync.