# `BP_DoorActor` — Door Actor System **Parent Class:** `Actor` **Category:** Interaction **Implements:** `I_Interactable` **Target UE Version:** 5.5–5.7 **Build Phase:** 2 — Interaction --- ## 1. Overview `BP_DoorActor` powers all door-like actors in the game world — standard hinged doors, sliding doors, double doors, and barricaded passages. It manages a discrete 6-state machine (`Closed → Opening → Open → Closing → Locked → Barricaded`), supports key/lock mechanics, item-required unlocking, one-way passage, partial-open positions, and networked replication. The door state is exposed via Event Dispatchers so other systems (AudioManager, CameraStateLayer, AI, Narrative) can react. --- ## 2. Mermaid — Door State Machine & Interaction Flow ```mermaid flowchart TD A[Idle Closed] --> B{Interact?} B -->|Player presses Interact| C[TryOpen] C --> D{Is Locked?} D -->|Yes: Has Required Item?| E{Remove Item?} D -->|Yes: No Item| F[Play Locked Feedback] E -->|Yes| G[Unlock & Open] E -->|No| F D -->|No| H[Play Open Anim] H --> I[State = Opening] I --> J[State = Open] J --> K{Close Conditions Met?} K -->|Auto-Close Timer| L[Play Close Anim] K -->|Player Interact| L K -->|Manual Call| L L --> M[State = Closing] M --> A N[Locked Entry] --> O[State = Locked] P[Barricaded Entry] --> Q[State = Barricaded] Q --> R{Barricade Broken?} R -->|Yes| A R -->|No| Q ``` --- ## 3. Enums ### `E_DoorState` Defined in `E_DoorState` enum asset. | Value | Description | |-------|-------------| | `Closed` | Door fully closed, no movement. Can be interacted with. | | `Opening` | Door playing open animation. Input blocked. | | `Open` | Door fully open. Can be interacted with to close, or auto-closes. | | `Closing` | Door playing close animation. Input blocked. | | `Locked` | Door locked. Cannot be opened unless unlocked via key/item or external trigger. | | `Barricaded` | Door physically blocked. Must be destroyed/breached. | ### `E_DoorType` | Value | Description | |-------|-------------| | `Hinged` | Standard door that swings open/closed. | | `Sliding` | Door slides horizontally into a wall pocket. | | `Double` | Two doors that open outward/inward. | | `RollUp` | Garage-style door that rolls upward. | | `TrapDoor` | Floor/ceiling door that opens vertically. | ### `E_LockState` Optional sub-state for locked doors. | Value | Description | |-------|-------------| | `Unlocked` | Door can be opened normally. | | `KeyRequired` | Requires a specific key item in inventory. | | `ItemRequired` | Requires a specific non-key item (crowbar, code). | | `PuzzleLinked` | Lock is controlled by an external puzzle actor. | | `Breachable` | Lock can be broken with force (weapon/explosive). | --- ## 4. Structs ### `S_DoorConfig` | Field | Type | Description | |-------|------|-------------| | `DoorType` | `E_DoorType` | Visual/mechanical type of door. | | `DefaultState` | `E_DoorState` | State the door starts in at BeginPlay. | | `LockState` | `E_LockState` | Lock type if DefaultState is Locked. | | `RequiredItemTag` | `FGameplayTag` | Tag of item required to unlock (if KeyRequired/ItemRequired). | | `RemoveItemOnUse` | `bool` | If true, the key/item is consumed on unlock. | | `AutoCloseDelay` | `float` | Seconds before door auto-closes. 0 = never auto-close. | | `OpenAngle` | `float` | Degrees the door opens (default 90). | | `OpenSpeed` | `float` | Animation play rate / interpolation speed. | | `CloseSpeed` | `float` | Animation play rate for closing. | | `IsOneWay` | `bool` | If true, door only opens from one side. | | `CanBeBarricaded` | `bool` | If true, door can transition to Barricaded state. | | `BarricadeHealth` | `float` | Damage required to break barricade. | | `bReplicates` | `bool` | Whether door state is replicated. | ### `S_DoorAudioConfig` | Field | Type | Description | |-------|------|-------------| | `OpenSound` | `USoundBase*` | Sound played when door begins opening. | | `CloseSound` | `USoundBase*` | Sound played when door begins closing. | | `LockedSound` | `USoundBase*` | Sound played when player tries to open a locked door. | | `UnlockSound` | `USoundBase*` | Sound played when door is unlocked. | | `BarricadeBreakSound` | `USoundBase*` | Sound played when barricade is destroyed. | | `SqueakInterval` | `float` | Seconds between squeak sounds during movement (0 = no squeak). | --- ## 5. Variables ### Configuration (Instance Editable, Expose On Spawn) | Variable | Type | Description | |----------|------|-------------| | `DoorConfig` | `S_DoorConfig` | Primary configuration struct. | | `AudioConfig` | `S_DoorAudioConfig` | Audio configuration struct. | | `LinkedActors` | `TArray` | Actors to notify on door open/close (lights, alarms, traps). | | `RequiredItemTag` | `FGameplayTag` | Shortcut to DoorConfig.RequiredItemTag (for BP pin). | ### State (Blueprint Read Only, Replicated) | Variable | Type | Description | |----------|------|-------------| | `CurrentState` | `E_DoorState` | Current door state. Replicated using `OnRep_DoorState`. | | `CurrentLockState` | `E_LockState` | Current lock state. Replicated. | | `CurrentBarricadeHealth` | `float` | Remaining barricade health. Replicated. | | `bIsOpenFromFront` | `bool` | Tracks which side the door was opened from (for one-way logic). | ### Internal (Blueprint Read Only, Not Replicated) | Variable | Type | Description | |----------|------|-------------| | `OwningDoorActor` | `AActor*` | Cached reference to owning actor (BP_DoorBase). | | `DoorMeshComponent` | `UStaticMeshComponent*` | Cached reference to the door's static mesh (if hinged/sliding). | | `DoorAudioComponent` | `UAudioComponent*` | Cached audio component for spatialized sounds. | | `AutoCloseTimerHandle` | `FTimerHandle` | Handle for auto-close timer. | | `AnimationTimeline` | `float` | Internal 0-1 progress of open/close animation. | --- ## 6. Functions & Events ### Public Functions | Function | Description | |----------|-------------| | `Interact_Implementation` | Implements `I_Interactable.ExecuteInteraction`. Routes to `TryOpen` if Closed/Locked/Barricaded, or `TryClose` if Open. | | `TryOpen` | Checks state: if Locked, attempts unlock (check inventory or puzzle); if Barricaded, plays blocked feedback; if Closed, begins open animation. Returns `E_DoorOperationResult`. | | `TryClose` | If Open, begins close animation. If Opening/Closing, ignores. Returns bool. | | `LockDoor` | Transitions to Locked state. Optionally sets lock type and required item. | | `UnlockDoor` | Removes lock, plays unlock effects. If `bAutoOpenOnUnlock`, begins opening. | | `BarricadeDoor` | Transitions to Barricaded state, sets health. | | `DamageBarricade` | Reduces barricade health by damage amount. If health reaches 0, removes barricade and transitions to Closed. | | `ForceSetState` | Bypasses animation; immediately sets door to any valid state. Used for save/load. | | `IsDoorUsable` | Returns true if door can be interacted with (not Opening/Closing/Barricaded with health). | | `GetDoorState` | Returns current `E_DoorState`. | | `GetDoorType` | Returns `E_DoorType` from config. | ### Protected Functions | Function | Description | |----------|-------------| | `BeginPlay` | Caches references, applies default state, initialises audio component. | | `PlayOpenAnimation` | Starts timeline/interp for door rotation/slide. Plays open sound. Calls `OnOpenComplete` when finished. | | `PlayCloseAnimation` | Starts timeline/interp for reverse. Plays close sound. Calls `OnCloseComplete` when finished. | | `OnOpenComplete` | Sets state to Open, clears auto-close timer if `AutoCloseDelay > 0`, notifies `LinkedActors`. | | `OnCloseComplete` | Sets state to Closed. | | `TryUnlockWithItem` | Checks player inventory for `RequiredItemTag`. If found and `RemoveItemOnUse`, consumes the item. Returns bool. | | `CheckPuzzleUnlockCondition` | Returns true if linked puzzle is solved. | | `PlayLockedFeedback` | Plays locked sound + optional UI prompt notifying player of required item. | | `OnRep_DoorState` | RepNotify: when `CurrentState` changes, plays appropriate animation on remote clients. | ### Event Dispatchers | Dispatcher | Payload | Description | |------------|---------|-------------| | `OnDoorStateChanged` | `E_DoorState NewState`, `AActor* Instigator` | Fired on any state transition. | | `OnDoorOpened` | `AActor* Instigator`, `bool bFromFront` | Fired when door reaches Open state. | | `OnDoorClosed` | `AActor* Instigator` | Fired when door reaches Closed state. | | `OnDoorLocked` | `AActor* Instigator` | Fired when door transitions to Locked. | | `OnDoorUnlocked` | `AActor* Instigator` | Fired when door is unlocked. | | `OnBarricadeBroken` | `AActor* Instigator` | Fired when barricade health reaches 0. | | `OnInteractionFailed` | `E_DoorState CurrentState`, `FText FailReason` | Fired when player cannot interact. | --- ## 7. Blueprint Graph Flow ### Event Graph Flow ``` Event BeginPlay → GetOwner → Cast to BP_DoorBase → Cache OwningDoorActor → FindComponentByClass UStaticMeshComponent → Cache DoorMeshComponent → Create Audio Component → Cache → Apply Default State from DoorConfig.DefaultState → If Locked → Set CurrentLockState → LockDoor On Interact_Implementation → Branch: CurrentState — Closed → Call TryOpen — Locked → Call TryUnlockWithItem → Branch Result — Success → Play Unlock Effects → Call TryOpen — Fail → Play LockedFeedback → Broadcast OnInteractionFailed — Barricaded → Play Blocked Feedback → Broadcast OnInteractionFailed — Open → Call TryClose — Opening/Closing → Ignore (return) TryOpen → IsDoorUsable? → If not, return false → Set CurrentState = Opening → Broadcast OnDoorStateChanged → Set bIsOpenFromFront = (player side check) → PlayOpenAnimation TryClose → IsDoorUsable? → If not, return false → Set CurrentState = Closing → Broadcast OnDoorStateChanged → Clear AutoCloseTimerHandle → PlayCloseAnimation PlayOpenAnimation → Timeline: 0→1 over 1/OpenSpeed seconds → Interp: DoorMeshComponent RelativeRotation.Yaw from 0 → OpenAngle (or DoorConfig sign for direction) → PlaySound: AudioConfig.OpenSound → On Finished → OnOpenComplete PlayCloseAnimation → Timeline: 1→0 over 1/CloseSpeed seconds → Interp: DoorMeshComponent RelativeRotation.Yaw from current → 0 → PlaySound: AudioConfig.CloseSound → On Finished → OnCloseComplete OnOpenComplete → Set CurrentState = Open → Broadcast OnDoorOpened → If AutoCloseDelay > 0 → Set Timer by Event (AutoCloseDelay, Call TryClose) → Notify LinkedActors (Open event) OnCloseComplete → Set CurrentState = Closed → Broadcast OnDoorClosed → Notify LinkedActors (Close event) LockDoor → Set CurrentState = Locked → Set CurrentLockState = Input LockState → Broadcast OnDoorLocked UnlockDoor → Set CurrentLockState = Unlocked → If bAutoOpenOnUnlock → Call TryOpen → Broadcast OnDoorUnlocked DamageBarricade → CurrentBarricadeHealth -= Damage → If CurrentBarricadeHealth <= 0 → Set CurrentState = Closed → Broadcast OnBarricadeBroken → Broadcast OnDoorStateChanged ``` --- ## 8. Replication | Variable | Replication | Callback | |----------|-------------|----------| | `CurrentState` | `RepNotify` | `OnRep_DoorState` — plays matching animation on remote | | `CurrentLockState` | `Replicated` | — | | `CurrentBarricadeHealth` | `Replicated` | — | | `bIsOpenFromFront` | `Replicated` | — | **Server authority:** All state transitions are executed on the server. Clients predict input via `Interact_Implementation`, but the server validates and broadcasts the authoritative state. --- ## 9. Dependencies & Communication | System | Relationship | |--------|--------------| | `BPC_InteractionDetector` | Calls `Interact_Implementation` when player looks at door and presses Interact. | | `BPC_InventorySystem` | Queried via `TryUnlockWithItem` for item possession and consumption. | | `BPC_HealthSystem` | Listens to `OnBarricadeBroken` for environmental damage credit. | | `BPC_CameraStateLayer` | May request FOV push when door opens into a large space. | | `AudioManager` | Consumes `AudioConfig` and may play ambient/occlusion changes on door state. | | `AI Perception` | AI listens to `OnDoorOpened`/`OnDoorClosed` to update pathfinding and awareness. | | `Save/Load System` | Calls `ForceSetState` and `LockDoor`/`UnlockDoor` during restore. | | `Narrative Subsystem` | May bind to `OnDoorUnlocked` to trigger dialogue when a story-key door is opened. | | `BP_PuzzleDeviceActor` | `PuzzleLinked` lock type — puzzle completion calls `UnlockDoor`. | | `BPC_DifficultyManager` | May adjust `AutoCloseDelay` and `BarricadeHealth` based on player performance metrics. | --- ## 10. Success Criteria 1. Player can open/close a hinged door with standard interaction. 2. Locked door plays feedback sound and shows item-required prompt. 3. Player with correct key/item unlocks door; item is consumed if configured. 4. Door auto-closes after configurable delay; auto-close timer resets on re-open. 5. Barricaded door blocks passage until its health reaches 0 via damage. 6. `PuzzleLinked` door unlocks when linked `BP_PuzzleDeviceActor` reports completion. 7. One-way doors only open from the configured side. 8. Double doors open/close in sync as a paired animation. 9. Multiplayer: server-authoritative state syncs to all clients via `OnRep_DoorState`. 10. Save/load correctly restores door state, lock state, and barricade health. --- ## 11. Data Flow Summary ``` Player Presses Interact → BPC_InteractionDetector.ScanForInteractables → Closest valid target = BP_DoorActor → Call I_Interactable.ExecuteInteraction → BP_DoorActor.Interact_Implementation → State check / lock check / inventory check → Play animation / sound → Broadcast Event Dispatchers → Downstream systems react (AI, Audio, Narrative, Save) ``` ## 12. Reuse Notes - This renamed file (formerly `BPC_InteractableDoorComponent`) is now an Actor-based system (`BP_DoorActor`) as per Master Section 3.5. - The door actor encapsulates all door logic directly rather than as an ActorComponent. - Cross-references updated: `BPC_InventoryComponent` → `BPC_InventorySystem`, `BPC_LeverPuzzleComponent` → `BP_PuzzleDeviceActor`.