Files
Lefteris Notas eeb1bf82c9 feat: Enhance interaction and inventory systems with new components and functionality
- Added BPC_UsableWorldObjectSystem for handling various interactable world objects with detailed manual implementation guide.
- Introduced BPC_ActiveItemSystem to manage quick slots and active item usage, including cycling and selection logic.
- Implemented BPC_DocumentArchiveSystem for managing collectible documents with read tracking and categorization.
- Developed BPC_JournalSystem for narrative entries with auto-adding features based on gameplay events.
- Created BPC_KeyItemSystem for key management with consumable and persistent key support.
- Enhanced BPC_FirearmSystem for ranged weapon mechanics, including hitscan and projectile firing.
- Updated BPC_MeleeSystem for melee combat with combo and blocking mechanics.
- Established BPC_ReloadSystem for managing weapon reloading processes, including partial reloads and state management.
2026-05-19 18:37:42 +03:00

20 KiB
Raw Permalink Blame History

BP_DoorActor — Door Actor System

Parent Class: Actor Category: Interaction Implements: I_Interactable Target UE Version: 5.55.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

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<AActor*> 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_InventoryComponentBPC_InventorySystem, BPC_LeverPuzzleComponentBP_PuzzleDeviceActor.

13. Multiplayer Networking (Expanded)

Server RPCs

RPC Direction Description
Server_Interact Client→Server Client requests door interaction. Server validates range, state, lock, then executes TryOpen/TryClose.
Server_DamageBarricade Client→Server Client deals damage to barricade. Server validates damage source, applies to barricade health.
Server_TryUnlock Client→Server Client attempts unlock with key item. Server validates inventory, consumes item if configured.

Authority Gates

Interact_Implementation
  If NOT HasAuthority:
    → Call Server_Interact(DoorActor)
    → Return (client prediction: show prompt, wait for OnRep)
  // Server executes authoritative logic
  → TryOpen / TryClose / TryUnlock
  → OnRep broadcasts to all clients

Client Prediction

  • Interaction: Client calls Server_Interact RPC; server validates and changes state.
  • Animation: OnRep_DoorState triggers animation on all clients identically.
  • Locked feedback: Played locally by client when server rejects interaction.

Anti-Cheat

  • Server validates player is within interaction range before opening door.
  • Server validates key item is in player inventory before unlocking.
  • Server validates barricade damage source.

14. Manual Implementation Guide

14.1 Class Setup

  1. Create Blueprint Class: Parent = Actor, Name = BP_DoorActor
  2. Add components: DoorRoot (SceneComponent), DoorFrame (StaticMesh — static), DoorMesh (StaticMesh — rotates/slides), InteractionCollision (Box or Sphere)
  3. Implement Interfaces: I_Interactable, I_Persistable
  4. Set Replicates = true in Class Defaults

14.2 Variable Defaults

Variable Default
CurrentState Closed
CurrentLockState Unlocked
CurrentBarricadeHealth 100.0
AutoCloseDelay 3.0 (0 = never)
OpenAngle 90.0
OpenSpeed 2.0
CloseSpeed 1.5

14.3 Function Node-by-Node

BeginPlay

Event BeginPlay
  → Cache OwningActor (Self)
  → Get DoorMesh by tag/name → Cache DoorMeshComponent
  → Spawn Audio Component → Cache DoorAudioComponent
  → Apply DefaultState from DoorConfig:
    Switch on DoorConfig.DefaultState:
      Closed → (nothing, already closed)
      Locked → Call LockDoor
      Open → Call ForceSetState(Open) ← for save/load or pre-opened doors

Interact_Implementation(Instigator: Actor) — I_Interactable

Switch on CurrentState:
  Closed → Call TryOpen(Instigator)
  Open → Call TryClose(Instigator)
  Locked → Call TryUnlockWithItem(Instigator)
    Branch on result:
      True → Call UnlockDoor → Call TryOpen(Instigator)
      False → Call PlayLockedFeedback → Fire OnInteractionFailed
  Barricaded → Call DamageBarricade(Instigator)
    If attack breaks barricade → OnBarricadeBroken → SetState Closed
  Opening/Closing → Return (ignored during animation)

TryOpen(Instigator)Must check HasAuthority() for MP

  Branch: CurrentState != Closed → Return false
  If DoorConfig.IsOneWay:
    Check player side (dot product of door forward vs player forward)
    If wrong side → Play locked feedback → Return false
  SetWeaponState(Opening)
  Fire OnDoorStateChanged
  PlayOpenAnimation()  ← uses Timeline, not Timer

PlayOpenAnimationKey node setup:

  Create Timeline (float track, 0→1 over OpenSpeed seconds)
    Timeline Update pin:
      → Get DoorMesh → Set Relative Rotation:
        Lerp (Quat): startRotation to startRotation + Rotator(0, OpenAngle, 0) by Timeline Alpha
    Timeline Finished pin:
      → Call OnOpenComplete
  Play Sound: AudioConfig.OpenSound at DoorMesh location via SS_AudioManager

OnOpenComplete

  Set CurrentState = Open
  Fire OnDoorOpened(Instigator, bIsOpenFromFront)
  If AutoCloseDelay > 0:
    Set Timer by Event (AutoCloseDelay) → Call TryClose(Self)
      Use "Self" as instigator for auto-close
  Notify LinkedActors with "Open" event

TryClose(Instigator)

  Branch: CurrentState != Open → Return false
  Set CurrentState = Closing
  Clear AutoCloseTimer (if running — prevents auto-close during manual close)
  Fire OnDoorStateChanged
  PlayCloseAnimation()

TryUnlockWithItem(Instigator)Boolean

  If CurrentLockState == KeyRequired:
    Get RequiredItemTag from DoorConfig
    Get Instigator → Get BPC_InventorySystem → Call HasItemQuantity(RequiredItemTag, 1)
    If found:
      If DoorConfig.RemoveItemOnUse:
        BPC_InventorySystem.RemoveItemByTag(RequiredItemTag, 1)
      Return true
    Return false
  If CurrentLockState == PuzzleLinked:
    Get LinkedPuzzle → Call IsPuzzleSolved
    Return result

DamageBarricade(Instigator, DamageAmount)

  Branch: CurrentState != Barricaded → Return
  CurrentBarricadeHealth -= DamageAmount
  If CurrentBarricadeHealth <= 0:
    Set CurrentBarricadeHealth = 0
    Set CurrentState = Closed
    Fire OnBarricadeBroken(Instigator)
    Fire OnDoorStateChanged
  Mark variable dirty (replication)

14.4 Blueprint Build Checklist

  • Create BP_DoorActor with DoorFrame + DoorMesh + InteractionCollision
  • Add all config variables (S_DoorConfig, S_DoorAudioConfig, LinkedActors)
  • Set DoorMesh mobility to Movable (for rotation during animation)
  • Implement I_Interactable with Interact_Implementation
  • Build TryOpen/TryClose with state validation
  • Create Timeline for door open/close animation (NOT Timer — Timeline for smooth interpolation)
  • Implement auto-close timer with reset on re-open
  • Build TryUnlockWithItem querying player inventory
  • Implement lock/barricade damage with health tracking
  • Add DoorAudioComponent for spatialized sounds
  • Set up LinkedActors — designer assigns in editor
  • Add networking: replicated CurrentState, Server_Interact RPC
  • Test: approach → interact → door opens → auto-closes → locked door → use key → unlocks