# Item Example — MedKit (Consumable) **Item Type:** `Consumable` **Complexity:** Low **Systems Used:** `DA_ItemData`, `BP_ItemPickup`, `BPC_InventorySystem`, `BPC_ConsumableSystem`, `BPC_HealthSystem` **What You Learn:** Consumable Data Asset, pickup actor, health restore, stackable item, quick-slot use --- ## 1. Create the DA_ItemData ### 1.1 — Create the Data Asset ``` Content Browser → Game/Items/ Right-click → Miscellaneous → Data Asset Class: DA_ItemData Name: DA_Item_MedKit ``` ### 1.2 — Fill Core Properties | Property | Value | Notes | |----------|-------|-------| | `Item Tag` | `Framework.Item.Consumable.MedKit` | Unique identity | | `Display Name` | "MedKit" | Player sees this | | `Description` | "A standard medical kit. Restores 25 health." | Shown in inventory | | `Icon` | `T_MedKit_Icon` | Any red/white cross texture for prototype | | `World Mesh` | `SM_MedKit` | Soft reference — Construction Script resolves it | | `Weight` | `1.0` | Light carry weight | | `Stack Limit` | `5` | Can carry up to 5 in one stack | | `Item Type` | `Consumable` | Triggers Consumable Data panel | ### 1.3 — Fill Consumable Data When `ItemType == Consumable`, the `Consumable Data` panel appears: | Field | Value | Notes | |-------|-------|-------| | `Health Restore` | `25.0` | How much HP to restore (0-100 clamp) | | `Stress Reduce` | `0.0` | Optional stress relief | | `Use Duration` | `2.0` | Seconds to consume (animation time) | | `bConsumedOnUse` | ✓ (true) | Item is removed from inventory after use | ### 1.4 — Save The Data Asset is ready. No other config needed for a simple consumable. --- ## 2. Create the BP_Pickup_MedKit Follow the same pattern as the flashlight pickup, but simpler — no active-use actor needed. ### 2.1 — Create Blueprint ``` Content Browser → Game/Pickups/ Right-click → Blueprint Class → Actor Name: BP_Pickup_MedKit ``` ### 2.2 — Add Components | # | Component | Name | Purpose | |---|-----------|------|---------| | 1 | `StaticMeshComponent` | `Mesh` | Renders the medkit model | | 2 | `SphereComponent` | `PickupTrigger` | Interaction radius (Sphere Radius → 150) | Select `PickupTrigger` → Details → Collision Presets → `OverlapOnlyPawn` ### 2.3 — Create ItemData Variable **+ Variable** → Name: `ItemData` → Type: `DA_ItemData → Object Reference` Select the variable → Details: - **Instance Editable** → ✓ - **Category** → `Pickup` ### 2.4 — Wire Construction Script ``` [Construction Script] │ ├─ ItemData → Is Valid? → Branch │ ├─ True: │ │ ├─ ItemData → Get World Mesh → Load Synchronous → Set Static Mesh (Mesh) │ │ └─ ItemData → Get Display Name → Set Actor Label │ └─ False: │ └─ Print String ("No ItemData assigned to BP_Pickup_MedKit") ``` ### 2.5 — Add I_Interactable and Wire Same pattern as flashlight. The key difference for consumables is **stacking**: the pickup can hold multiple units. ``` Event Interact │ Interactor: AActor* │ ├─ Interactor → Get Component by Class (UBPC_InventorySystem) → Is Valid? │ │ │ └─ True → [Inventory] │ │ │ ├─ Can Add Item(ItemData, Quantity=1) │ │ │ │ │ ├─ True → Add Item(ItemData, Quantity=1) → Destroy Actor → Return True │ │ │ │ │ └─ False: │ │ ├─ Print "Inventory Full" │ │ └─ Return False ``` > For multi-pickup stacks (e.g., picking up 3 medkits at once), set a `Quantity` variable (Integer, Instance Editable) and pass it to `Add Item`. The inventory auto-stacks identical items. ### 2.6 — Add Bobbing (optional) Add a Timeline to `Event BeginPlay` with a sine wave for Z offset — same as flashlight example. --- ## 3. Wire Consumable Use (On Player Pawn) When the player uses a consumable from their inventory or quick-slot: ### 3.1 — In BPC_ConsumableSystem (BP child on pawn) ``` Event Use Consumable (custom event) │ ItemData: DA_ItemData* │ ├─ ItemData → Get Consumable Data (Break FItemConsumableData) │ │ │ ├─ Health Restore > 0? │ │ └─ True: │ │ ├─ Get Owner → Get Component by Class (UBPC_HealthSystem) │ │ │ │ │ │ │ └─ Is Valid? → True: │ │ │ └─ Apply Healing (HealthRestore, Healer=self) │ │ │ │ │ │ │ └─ Print String: "Restored {HealthRestore} HP" │ │ │ │ │ └─ False: Print "No HealthSystem found" │ │ │ ├─ Stress Reduce > 0? │ │ └─ True: │ │ └─ Get BPC_StressSystem → Remove Stress (StressReduce) │ │ │ ├─ bConsumedOnUse? │ │ └─ True: │ │ └─ Get BPC_InventorySystem → Remove Item (ItemData, 1) │ │ │ └─ (Optional) Play sound, screen effect, widget animation ``` ### 3.2 — Quick Test Without Full Integration Bind a test key (e.g., `IA_UseItem`) in your player character: ``` Event InputAction (IA_UseItem, Pressed) │ ├─ Get Component by Class (UBPC_InventorySystem) ├─ Get All Items → For Each Loop │ │ │ ├─ Break FInventorySlot → Item │ ├─ Item → Get Item Type == Consumable? │ │ └─ True: │ │ ├─ Item → Get Consumable Data → Health Restore │ │ ├─ Get BPC_HealthSystem → Apply Healing (HealthRestore) │ │ ├─ Inventory → Remove Item (Item, 1) │ │ └─ Break (exit loop — only use one) │ │ │ └─ Continue loop ``` --- ## 4. Verification Checklist - [ ] **Data Asset:** `DA_Item_MedKit` has `ItemType = Consumable`, `HealthRestore = 25`, `StackLimit = 5` - [ ] **Pickup in level:** Mesh appears, bobs, interaction prompt shows "Pick up MedKit" - [ ] **Inventory:** Pick up medkit → appears in inventory slot. Pick up 4 more → they stack (quantity = 5). Pick up 6th → fails (stack limit). - [ ] **Use:** Press use item key → health increases by 25, stack count decreases by 1 - [ ] **Weight:** Each medkit adds 1.0 to carry weight. `Get Remaining Weight` decreases by 1.0 per pickup. - [ ] **Full inventory:** Pick up medkit when no slots left → "Inventory Full" feedback, pickup remains in world --- ## 5. Key Concepts | Concept | How It Works | |---------|-------------| | **Stacking** | `StackLimit = 5` on the Data Asset. `BPC_InventorySystem.AddItem()` auto-finds existing stacks and adds to them instead of creating new slots. | | **Consumed on use** | `bConsumedOnUse = true` → `BPC_ConsumableSystem` calls `RemoveItem()` after applying effects. Set to `false` for reusable items (e.g., a reusable syringe with cooldown). | | **Soft references** | `WorldMesh` is a `TSoftObjectPtr` — it doesn't load into memory until Construction Script resolves it. This keeps memory low when assets aren't in use. | | **Inventory weight** | `BPC_InventorySystem.CurrentWeight` auto-updates when items are added/removed. `CanAddItem()` checks weight capacity before pickup. |