| Engine | Unity 2022.3 LTS or newer |
|---|---|
| Language | C# |
| Pattern | ScriptableObject items + inventory + slot |
| Time to run | ~4 minutes |
| Level | Intermediate |
| Output | Item SO + Inventory + InventorySlot (~130 lines) |
| Dependencies | None. |
The prompt
Open a fresh chat at claude.ai/new, paste, and send.
$ Build me a Unity 2022.3+ inventory system in C# using ScriptableObjects for items. // item definition - An Item ScriptableObject with [CreateAssetMenu]: string id, string displayName, Sprite icon, int maxStack (default 99), [TextArea] description. // slot - A serializable InventorySlot class: Item item, int count. Helpers IsEmpty and CanStack(Item). // inventory - An Inventory class (MonoBehaviour or plain C# with [Serializable]), [SerializeField] int size (default 20), a List/array of InventorySlot. - Add(Item item, int amount): fill existing non-full stacks of the same item up to maxStack first, then use empty slots; return the amount that did NOT fit. - Remove(Item item, int amount): remove across stacks, clear emptied slots; return the amount actually removed. - Count(Item item): total across stacks. - An event Action OnChanged invoked whenever the contents change. // constraints - No UI code. The UI subscribes to OnChanged and reads the slots. - Respect maxStack everywhere. - No magic numbers. size and defaults are inspector-visible. // return format - Three types (Item, InventorySlot, Inventory). No prose before or after the code. - Brief comments only on the fill-existing-then-empty add logic.
What this gets you
A clean spine for items you can build a whole game on. Designers make new items as assets with no code. Adding, stacking and removing are handled correctly, including the fiddly bit where a pickup partially fills one stack and spills into another. And because it fires an event on change, the UI never has to poll, it just redraws when told.
No UI is baked in on purpose, so it drops into any project and you wire it to whatever inventory screen you want.
Why it matters
Items as assets, not enums
The moment you have more than a handful of items, hard-coding them as enums or prefabs becomes a chore and a merge-conflict magnet. ScriptableObject items are editable data assets, so content scales without code changes and without touching scenes.
Correct stacking is deceptively fiddly
Add has to fill partial stacks of the same item first, then spill into empty slots, and report the overflow that did not fit. Most first attempts either lose items or ignore maxStack. Spelling this out is what makes the prompt worth using.
Event-driven UI
An OnChanged event means the inventory and its display are decoupled. The inventory knows nothing about the UI, and the UI just listens. That separation is what keeps the system reusable and testable.
What good output looks like
- Item is a ScriptableObject with CreateAssetMenu. You should be able to right-click in the Project window and create an Item asset. If Item is a plain class or MonoBehaviour, that is the wrong shape here.
- Add fills partial stacks first. The logic should top up existing same-item stacks before using empty slots, and return the leftover that did not fit. A version that always uses a new slot is wrong.
- maxStack is respected everywhere. No slot count should ever exceed the item's maxStack, not on add, not on merge.
- OnChanged fires on every mutation. Add and Remove should both invoke the event once the contents actually change, so the UI updates.
How to wire it up
- Save the three types (
Item.cs,InventorySlot.cs,Inventory.cs). - Right-click in the Project window › Create › your Item menu, and make a few item assets with names, icons and max stacks.
- Put the
Inventoryon the player (or hold it as a field) and set the size. - On pickup, call
inventory.Add(itemAsset, 1)and destroy the world pickup if it all fit. - In your UI, subscribe to
OnChangedand redraw the slots from the inventory.
Common gotchas
Picked-up items vanish or duplicate
The Add overflow handling is wrong. Add must return what did not fit so the caller knows whether to remove the world pickup, and it must not both fill a stack and consume an empty slot for the same units.
Stacks exceed the max
A merge path is not clamping to maxStack. Every place that increases a count must clamp to the item's maxStack and carry the remainder.
The UI does not update
The UI is reading once instead of subscribing, or OnChanged is not invoked. Fire OnChanged at the end of any method that changes contents, and have the UI redraw on it.
Where to go next
- Item types. Subclass Item (Weapon, Consumable) or add an enum and an effect hook for use actions.
- Drag and drop. Build a slot UI that moves and splits stacks between slots.
- Persistence. Save item ids and counts, rebuild by id on load. The JSON save prompt covers the pattern.
Use it however you want
The prompt is CC0, paste it, modify it, ship a game with it. The output Claude gives you is yours. A link back to pixeldex.dev in your project's README helps the next solo dev find this stuff.