Inventory & Hotbar

Inventory Component

The Inventory component lives on the player and manages:

  • Slots: an array of InventorySlot
  • Hotbar size and total inventory size
  • Currently selected hotbar index
  • Events when data changes

A typical layout:

  • hotbarSize = 8
  • inventorySize = 32
  • Total internal slots = 8 (hotbar) + 32 (main inventory)

InventorySlot

Each InventorySlot holds either a block or a tool:

  • BlockData block
  • ToolData tool
  • int count

Constraints:

  • A slot can contain either a block or a tool (not both at once).
  • IsEmpty returns true if neither block nor tool is assigned, or count <= 0.

Adding Items

Common methods on Inventory:

  • AddBlock(BlockData block, int amount)
  • Stacks onto existing stacks of that block if possible.
  • Otherwise, puts it in the first empty slot.

  • AddTool(ToolData tool, int amount)

  • Similar idea for tools. You can choose to allow stacking or keep them at 1.

These functions call NotifyChanged(), which raises the OnInventoryChanged event so the UI can refresh.

Consuming Items

  • ConsumeFromSlot(int index, int amount)
  • Decreases count on a given slot.
  • Clears the slot when count <= 0.
  • Triggers NotifyChanged().

  • ConsumeFromSelectedHotbar(int amount)

  • Convenience method that consumes from the currently selected hotbar slot.

When placing a block, BlockInteractor typically calls:

inventory.ConsumeFromSelectedHotbar(1);

to remove one item from the slot used for placement.

CurrentHotbarBlock & CurrentHotbarTool

The inventory exposes convenience properties:

  • CurrentHotbarBlock
  • CurrentHotbarTool

They:

  • Validate selectedHotbarIndex
  • Check that the index is within slots bounds
  • Return the BlockData or ToolData from that slot if it is not empty

These are used by:

  • BlockInteractor (to decide what block can be placed)
  • HeldItemRenderer (to decide which model should be held in hand)

Inventory UI

InventoryUI

InventoryUI is a MonoBehaviour responsible for:

  • Holding references to:
  • The Inventory component
  • The main Canvas
  • Arrays of InventorySlotUI for hotbar and main inventory
  • Subscribing to Inventory.OnInventoryChanged
  • Calling RefreshAll() to update all slot UIs

Typical pattern:

  • Hotbar slots are bound to indices [0 .. hotbarSize-1].
  • Main inventory slots are bound to [hotbarSize .. hotbarSize + inventorySize-1].

InventorySlotUI

Each InventorySlotUI:

  • Shows:
  • The correct icon (block.icon or tool.icon)
  • The stack count (if > 1)
  • Handles:
  • Click to select slot (hotbar selection)
  • Drag & drop to reorder items between slots

Opening / Closing Inventory

A common pattern:

  • Hotbar is always visible.
  • Full inventory grid is toggled with a key (e.g. I):
  • When open:
    • Enable the inventory panel GameObject.
    • Disable FPS movement and block interaction.
    • Unlock and show the cursor.
  • When closed:
    • Hide the panel.
    • Re-enable player control.
    • Lock and hide the cursor.