# BPC_UsableWorldObjectSystem — Usable World Object System **Parent Class:** `ActorComponent` **Category:** Interaction **Target UE Version:** 5.5–5.7 **Build Phase:** 2 — Interaction ## 1. Overview `BPC_UsableWorldObjectSystem` powers generic usable objects in the world — switches, buttons, valves, terminals, readable notes, audio logs. Provides a unified interaction interface for any object the player can "use" via the InteractionDetector. ## 2. Enums ### `E_UsableObjectType` | Value | Description | |-------|-------------| | `Switch` | Toggleable switch | | `Button` | Pressable button | | `Valve` | Rotatable valve | | `Terminal` | Interactive screen | | `Readable` | Note/book | | `AudioLog` | Audio playback device | | `Generic` | Custom interaction | ## 3. Variables | Variable | Type | Description | |----------|------|-------------| | `ObjectType` | `E_UsableObjectType` | Type of usable object | | `InteractionData` | `DA_InteractionData*` | Interaction definition | | `bIsActive` | `bool` | Object enabled | | `bSingleUse` | `bool` | Can only be used once | | `bHasBeenUsed` | `bool` | Tracked if single-use | | `CooldownSeconds` | `float` | Reuse cooldown | ## 4. Functions | Function | Description | |----------|-------------| | `OnUse` | Executes interaction logic | | `SetEnabled` | Enable/disable object | | `ResetObject` | Return to initial state | ## 5. Event Dispatchers | Dispatcher | Payload | Description | |------------|---------|-------------| | `OnObjectUsed` | `AActor* User` | Object successfully used | | `OnObjectStateChanged` | `bool bIsActive` | State toggled | ## 6. Dependencies | System | Relationship | |--------|--------------| | `BPC_InteractionDetector` | Focus and interaction routing | | `DA_InteractionData` | Data-driven interaction config | ## 7. Reuse Notes - Generic base for all "press E to use" world objects - Can be subclassed for specialized behavior --- ## 8. Manual Implementation Guide ### 8.1 Class Setup 1. Create Blueprint Class: Parent = `ActorComponent`, Name = `BPC_UsableWorldObjectSystem` 2. Attach to any world actor that should be "usable" (switches, buttons, valves, terminals, notes, audio logs) 3. The owner actor must implement `I_Interactable` (or this component implements it on behalf of owner) ### 8.2 Variable Initialization (BeginPlay) ``` Event BeginPlay ├─ Set bIsActive = true ├─ Set bHasBeenUsed = false ├─ Load InteractionData (Data Asset reference) │ ├─ Read PromptText → store for UI │ ├─ Read InteractionDuration → for hold interactions │ └─ Read ObjectType → set behavior mode └─ Set LinkedActor from owner variable (designer-assigned in editor) ``` ### 8.3 Function Implementations #### `OnUse(Instigator: Actor)` → `Boolean` ``` [Function: OnUse] — core interaction handler Step 1: Branch on bIsActive → If false, Fire OnObjectStateChanged(false), Return false Step 2: Branch on bSingleUse AND bHasBeenUsed: True → Return false (already used once) Step 3: Switch on ObjectType: Case Switch: - Toggle bIsActive (invert) - Play switch animation: flip lever/button - If LinkedActor: call I_Toggleable.Toggle(Instigator) on LinkedActor - Start CooldownSeconds timer → bIsActive = true after cooldown Case Button: - Set bIsActive = false (press in) - Play button press animation - Notify LinkedActor if set - Start timer → spring back: bIsActive = true Case Valve: - Begin rotate interaction (player holds E and moves mouse) - Call Adjust on LinkedActor (I_Adjustable) with rotation delta - On release: stop adjustment Case Terminal: - Call OpenTerminal UI on LinkedActor or self - Set player input mode to UI Only - On close → restore input Case Readable: - Get NoteText from InteractionData - Call WBP_JournalDocumentViewer.OpenNote(NoteText) - Play "paper rustle" sound via SS_AudioManager Case AudioLog: - Get AudioClip from InteractionData - Call SS_AudioManager.PlayDialogue(AudioClip) - Show subtitle text if available Case Generic: - Fire custom dispatcher or call blueprint event OnGenericUse Step 4: Set bHasBeenUsed = true (if bSingleUse) Step 5: Fire OnObjectUsed(Instigator) Step 6: Return true ``` **Nodes:** `Switch on E_UsableObjectType`, `Play Animation`, `I_Toggleable.Toggle`, `Open UI Widget`, `Play Sound` #### `SetEnabled(bEnabled: Boolean)` → `void` ``` [Function: SetEnabled] Step 1: Set bIsActive = bEnabled Step 2: Update visual: enable/disable highlight, change material Step 3: Fire OnObjectStateChanged(bEnabled) ``` #### `ResetObject()` → `void` ``` [Function: ResetObject] Step 1: Set bHasBeenUsed = false Step 2: Set bIsActive = true Step 3: Reset visual state to default Step 4: Fire OnObjectStateChanged(true) ``` ### 8.4 I_Interactable Implementation (on owner actor) If the component is on an actor that implements I_Interactable: ``` [Owner Actor: I_Interactable.OnInteract(Instigator)] Step 1: Get Component by Class (BPC_UsableWorldObjectSystem) Step 2: Call BPC_UsableWorldObjectSystem.OnUse(Instigator) [Owner Actor: I_Interactable.CanInteract(Instigator)] Get UsableComp → Return UsableComp.bIsActive AND NOT (UsableComp.bSingleUse AND UsableComp.bHasBeenUsed) [Owner Actor: I_Interactable.GetInteractionPrompt()] Get UsableComp → Return UsableComp.InteractionData.PromptText ``` ### 8.5 Blueprint Build Checklist - [ ] Define enum E_UsableObjectType and create DA_InteractionData with usage config - [ ] Create BPC_UsableWorldObjectSystem component - [ ] Add variables: ObjectType, InteractionData, bIsActive, bSingleUse, bHasBeenUsed, CooldownSeconds - [ ] Implement OnUse with type-switch for all 7 object types - [ ] Implement SetEnabled / ResetObject - [ ] Create owner actor (BP_UsableObject) that implements I_Interactable - [ ] Route I_Interactable calls to this component - [ ] Set LinkedActor reference for Switch/Button objects - [ ] Test: place switch → press E → linked light toggles → cooldown → press again