Files
UE5-Modular-Game-Framework/docs/blueprints/03-interaction/18_BPC_DiegeticDisplay.md
Lefteris Notas 411edea8ce add blueprints
2026-05-19 13:22:27 +03:00

370 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# `BPC_DiegeticDisplay` — Diegetic Display System
**Parent Class:** `ActorComponent`
**Category:** Interaction / UI
**Target UE Version:** 5.55.7
**Build Phase:** 2 — Interaction
---
## 1. Overview
`BPC_DiegeticDisplay` manages any in-world screen that renders game UI directly inside the 3D scene — watches, PDAs, tablets, computer monitors, cockpit screens. Instead of traditional HUD overlays, the player looks down at their character's wrist (watch) or picks up a tablet to see inventory/map/messages rendered as a world-space widget on a static mesh.
The component provides a 6-mode state machine (`Off → Splash → Idle → Menu → Messaging → Mapping/Scanning`), handles input routing to the active widget, manages screen transitions (flicker, boot sequence, static interference), and communicates with other systems via Event Dispatchers.
---
## 2. Mermaid — Display Mode State Machine
```mermaid
flowchart TD
A[Off] --> B{Power On?}
B -->|Yes| C[Splash]
C --> D[Idle]
D --> E{User Input?}
E -->|Open Menu| F[Menu]
E -->|Open Map| G[Mapping]
E -->|Receive Message| H[Messaging]
E -->|Activate Scan| I[Scanning]
F --> J{Close Menu?}
J -->|Yes| D
G --> K{Close Map?}
K -->|Yes| D
H --> L{Message Dismissed?}
L -->|Yes| D
I --> M{Scan Complete?}
M -->|Yes| D
D --> N{Idle Timeout?}
N -->|Yes| A
```
---
## 3. Enums
### `E_DiegeticDisplayMode`
| Value | Description |
|-------|-------------|
| `Off` | Screen completely off (black/no widget). |
| `Splash` | Boot-up animation playing (logo, startup sequence). |
| `Idle` | Default active state. May show time, low-priority info. |
| `Menu` | Full menu — inventory, settings, journal. |
| `Messaging` | Incoming/outgoing message display. |
| `Mapping` | Map or floorplan overlay. |
| `Scanning` | Active scanning mode (environment analysis, entity detection). |
### `E_ScreenEffect`
| Value | Description |
|-------|-------------|
| `None` | No effect — clean image. |
| `Static` | Analog TV static / interference. |
| `Flicker` | Rapid on/off flicker (power fluctuation). |
| `Glitch` | Digital artifact corruption. |
| `ScanLine` | CRT scan lines overlay. |
| `BootSequence` | OS-style boot animation (loading bars, text crawl). |
| `LowBattery` | Dim + pulsing warning overlay. |
### `E_DisplayInputMode`
| Value | Description |
|-------|-------------|
| `Locked` | Display ignores player input. |
| `Passthrough` | Input forwarded to active widget. |
| `Modal` | Input consumed entirely by display (menu open). |
---
## 4. Structs
### `S_DiegeticDisplayConfig`
| Field | Type | Description |
|-------|------|-------------|
| `DisplayName` | `FText` | Human-readable name (e.g., "Wrist Link", "PDA-7"). |
| `DefaultMode` | `E_DiegeticDisplayMode` | Mode to start in at BeginPlay. |
| `bStartPoweredOn` | `bool` | If false, starts in Off mode. |
| `WidgetClass` | `TSubclassOf<UUserWidget>` | World-space widget class to render on the screen. |
| `ScreenMeshComponent` | `FName` | Name of the static mesh component the widget renders on. |
| `ScreenSize` | `FVector2D` | Widget resolution in pixels (e.g., 256x144). |
| `InteractionDistance` | `float` | Max distance to interact with the display (0 = attached to player). |
| `bIsPlayerOwned` | `bool` | If true, attached to player (watch) vs. world object (terminal). |
| `IdleTimeoutSeconds` | `float` | Seconds of inactivity before powering off. 0 = never timeout. |
| `BootDuration` | `float` | Seconds the Splash animation plays. |
| `bHasMapMode` | `bool` | If true, Mapping mode is available. |
| `bHasScanMode` | `bool` | If true, Scanning mode is available. |
| `bReplicates` | `bool` | Whether display state is replicated. |
### `S_ScreenState`
| Field | Type | Description |
|-------|------|-------------|
| `CurrentMode` | `E_DiegeticDisplayMode` | Active display mode. |
| `ActiveEffect` | `E_ScreenEffect` | Currently playing visual effect. |
| `EffectIntensity` | `float` | 01 intensity of the active effect. |
| `InputMode` | `E_DisplayInputMode` | Current input routing mode. |
| `BatteryLevel` | `float` | 01 remaining battery (if applicable). |
| `bIsPoweredOn` | `bool` | Quick check for power state. |
### `S_MessagePayload`
| Field | Type | Description |
|-------|------|-------------|
| `SenderName` | `FText` | Name of message sender. |
| `MessageBody` | `FText` | Message text content. |
| `bIsUrgent` | `bool` | If true, forces display to Messaging mode with priority. |
| `AssociatedQuestTag` | `FGameplayTag` | Quest/objective this message relates to. |
| `AudioAttachment` | `USoundBase*` | Optional audio clip attached to message. |
---
## 5. Variables
### Configuration (Instance Editable, Expose On Spawn)
| Variable | Type | Description |
|----------|------|-------------|
| `DisplayConfig` | `S_DiegeticDisplayConfig` | Primary configuration struct. |
| `IdleWidget` | `TSubclassOf<UUserWidget>` | Widget to display in Idle mode. |
| `MenuWidget` | `TSubclassOf<UUserWidget>` | Widget to display in Menu mode. |
| `MessagingWidget` | `TSubclassOf<UUserWidget>` | Widget for incoming/outgoing messages. |
| `MapWidget` | `TSubclassOf<UUserWidget>` | Widget for mapping overlay. |
| `ScanWidget` | `TSubclassOf<UUserWidget>` | Widget for scanning mode. |
### State (Blueprint Read Only)
| Variable | Type | Description |
|----------|------|-------------|
| `CurrentState` | `S_ScreenState` | Struct holding all current screen state. |
| `ActiveWidget` | `UUserWidget*` | Reference to the currently displayed widget instance. |
| `ScreenMesh` | `UStaticMeshComponent*` | Cached reference to the screen mesh. |
| `IdleTimerHandle` | `FTimerHandle` | Handle for idle power-off timer. |
| `BootTimerHandle` | `FTimerHandle` | Handle for boot-up duration timer. |
| `PendingMessages` | `TArray<S_MessagePayload>` | Queue of messages to display. |
| `CurrentMessageIndex` | `int32` | Index into PendingMessages for cycling. |
### Input Handling (Blueprint Read Only)
| Variable | Type | Description |
|----------|------|-------------|
| `bInputConsumed` | `bool` | Whether the display is currently consuming input. |
| `InputActionBindings` | `TArray<FInputActionBinding>` | Active input bindings for display mode. |
---
## 6. Functions & Events
### Public Functions
| Function | Description |
|----------|-------------|
| `PowerOn` | Boots the display. Plays Splash sequence, then transitions to Idle. |
| `PowerOff` | Immediately turns off display, clears widget, kills idle timer. |
| `SetDisplayMode` | Transitions to any `E_DiegeticDisplayMode`. Plays transition effect. |
| `ApplyScreenEffect` | Applies a temporary `E_ScreenEffect` for a given duration. |
| `ClearScreenEffect` | Immediately clears active effect, returns to clean image. |
| `ReceiveMessage` | Adds a `S_MessagePayload` to the queue. If current mode is Idle, auto-switches to Messaging. |
| `DismissMessage` | Closes current message. If queue has more, shows next; else returns to Idle. |
| `OpenMenu` | Transitions to Menu mode. Locks input to display. |
| `CloseMenu` | Returns to Idle mode. Releases input. |
| `OpenMap` | Transitions to Mapping mode (if `bHasMapMode`). |
| `CloseMap` | Returns to Idle mode. |
| `StartScan` | Begins Scanning mode (if `bHasScanMode`). |
| `StopScan` | Ends Scanning mode, returns to Idle. |
| `ToggleDisplay` | Toggles between current mode and Off/Idle based on power state. |
| `IsDisplayActive` | Returns true if powered on and not Off/Splash/Boot. |
| `GetScreenState` | Returns the `S_ScreenState` struct. |
### Protected Functions
| Function | Description |
|----------|-------------|
| `BeginPlay` | Caches references, creates widget instance if auto-start. |
| `Tick` | If `ActiveEffect != None`, applies effect material parameter animation. |
| `CreateWidgetInstance` | Creates the world-space widget for the given mode class. Attaches to `ScreenMesh`. |
| `DestroyWidgetInstance` | Removes and destroys current widget. |
| `PlayBootSequence` | Timelines splash animation. On complete, calls `OnBootComplete`. |
| `OnBootComplete` | Transitions to Idle, starts idle timeout timer. |
| `StartIdleTimer` | Resets and starts the idle timeout. |
| `OnIdleTimeout` | Powers off the display. |
| `SetupInputForMode` | Binds/unbinds input actions based on `CurrentState.InputMode`. |
| `HandleMenuInput` | Processes navigation/select inputs in Menu mode. |
| `HandleMessageInput` | Processes dismiss/respond inputs in Messaging mode. |
| `HandleMapInput` | Processes pan/zoom inputs in Mapping mode. |
| `HandleScanInput` | Processes scan activation input. |
### Event Dispatchers
| Dispatcher | Payload | Description |
|------------|---------|-------------|
| `OnDisplayModeChanged` | `E_DiegeticDisplayMode NewMode`, `E_DiegeticDisplayMode PreviousMode` | Fired on any mode transition. |
| `OnDisplayPoweredOn` | — | Fired after boot sequence completes. |
| `OnDisplayPoweredOff` | — | Fired when display is turned off. |
| `OnMessageReceived` | `S_MessagePayload Message` | Fired when a new message enters the queue. |
| `OnMessageDismissed` | `S_MessagePayload Message` | Fired when a message is dismissed. |
| `OnScreenEffectStarted` | `E_ScreenEffect Effect`, `float Duration` | Fired when a screen effect begins. |
| `OnScreenEffectEnded` | `E_ScreenEffect Effect` | Fired when a screen effect ends. |
| `OnDisplayInputLocked` | `bool bIsLocked` | Fired when input mode changes to Locked or unlocked. |
---
## 7. Blueprint Graph Flow
```
Event BeginPlay
→ GetOwner → FindComponentByTag (ScreenMeshComponent name) → Cache ScreenMesh
→ If DisplayConfig.bStartPoweredOn → Call PowerOn
→ Else → Set CurrentState.CurrentMode = Off
PowerOn
→ Set CurrentState.bIsPoweredOn = true
→ Set CurrentState.InputMode = Locked
→ Broadcast OnDisplayModeChanged (Off → Splash)
→ PlayBootSequence
PlayBootSequence
→ ApplyScreenEffect (BootSequence)
→ Set Timer by Event (DisplayConfig.BootDuration, Call OnBootComplete)
OnBootComplete
→ ClearScreenEffect
→ Set CurrentState.CurrentMode = Idle
→ CreateWidgetInstance (IdleWidget)
→ Set CurrentState.InputMode = Passthrough
→ Broadcast OnDisplayPoweredOn
→ Broadcast OnDisplayModeChanged (Splash → Idle)
→ StartIdleTimer
SetDisplayMode
→ Store PreviousMode = CurrentState.CurrentMode
→ If PreviousMode == NewMode → return
→ DestroyWidgetInstance
→ Broadcast OnDisplayModeChanged (PreviousMode → NewMode)
→ Set CurrentState.CurrentMode = NewMode
→ Branch on NewMode:
— Menu → CreateWidgetInstance (MenuWidget), SetupInputForMode (Modal)
— Messaging → CreateWidgetInstance (MessagingWidget), SetupInputForMode (Modal)
— Mapping → CreateWidgetInstance (MapWidget), SetupInputForMode (Modal)
— Scanning → CreateWidgetInstance (ScanWidget), SetupInputForMode (Modal)
— Idle → CreateWidgetInstance (IdleWidget), SetupInputForMode (Passthrough), StartIdleTimer
→ If NewMode != Idle → Clear idle timer
ReceiveMessage
→ PendingMessages.Add(Message)
→ If CurrentState.CurrentMode == Idle:
→ SetDisplayMode (Messaging)
→ If CurrentState.CurrentMode == Messaging:
→ Update widget to show new message count
→ Broadcast OnMessageReceived
DismissMessage
→ Remove CurrentMessage from PendingMessages
→ If PendingMessages.Num() > 0:
→ Show next message
→ Else:
→ SetDisplayMode (Idle)
→ Broadcast OnMessageDismissed
PowerOff
→ ClearScreenEffect
→ DestroyWidgetInstance
→ Clear Input Bindings
→ Set CurrentState.bIsPoweredOn = false
→ Set CurrentState.CurrentMode = Off
→ Clear IdleTimerHandle
→ Broadcast OnDisplayPoweredOff
→ Broadcast OnDisplayModeChanged (previous → Off)
OpenMenu
→ SetDisplayMode (Menu)
CloseMenu
→ SetDisplayMode (Idle)
Event Tick (DeltaTime)
→ If ActiveEffect != None and ActiveEffectDuration > 0:
→ Update material parameter for effect animation (flicker intensity, static noise)
→ Decrement remaining duration
→ If duration expired → ClearScreenEffect
```
---
## 8. Replication
| Variable | Replication | Callback |
|----------|-------------|----------|
| `CurrentState.CurrentMode` | `RepNotify` | `OnRep_DisplayMode` — recreates widget on remote clients |
| `CurrentState.ActiveEffect` | `Replicated` | — |
| `CurrentState.bIsPoweredOn` | `Replicated` | — |
**Authority:** Server controls power/mode transitions. Client predicts input for Menu/Message dismissal, but server validates.
---
## 9. Widget Setup (Per-Mode)
| Mode | Widget Content |
|------|----------------|
| `Idle` | Time display, low-priority notifications, battery indicator. |
| `Menu` | Radial or list menu: Inventory, Journal, Settings, Map, Messages. |
| `Messaging` | Scrolling text log with sender avatar, reply options, audio playback. |
| `Mapping` | 2D floorplan with player position marker, discovered rooms, objective markers. |
| `Scanning` | Overlaid data readouts: entity heat signatures, material composition, structural integrity. |
All widgets are added as `UUserWidget` instances attached to the screen mesh via `AddToViewport`/`SetWidget` on a `UWidgetComponent`. The component handles creation/destruction; individual widgets handle their own internal state.
---
## 10. Dependencies & Communication
| System | Relationship |
|--------|--------------|
| `BPC_InteractionDetector` | Detects world terminals; calls `Interact_Implementation` on the host actor. |
| `BPC_InventoryComponent` | Menu mode reads inventory contents to display in widget. |
| `BPC_MappingSubsystem` | Supplies floorplan data to Map widget. |
| `BPC_ScanningSubsystem` | Supplies scan results to Scan widget. |
| `GI_GameFramework` | Provides game time, date, and phase info for idle widget display. |
| `BPC_StressSystem` | High stress may trigger screen flicker/glitch effects. |
| `BPC_HealthSystem` | Low health may apply low battery / dimming effect. |
| `BPC_PlayerMetricsTracker` | Logs display usage events for analytics. |
| `BPC_AdaptiveDifficulty` | May adjust idle timeout or boot duration based on player performance. |
| `Save/Load System` | Saves `CurrentState` and `PendingMessages` array for restore. |
| `Narrative Subsystem` | Pushes messages via `ReceiveMessage` for story-driven communication. |
---
## 11. Success Criteria
1. Display boots with splash sequence and transitions to idle.
2. Player can open/close menu from idle.
3. Receiving a message from narrative subsystem forces display to Messaging mode.
4. Player dismisses message and display returns to idle.
5. Display powers off after idle timeout; interact to power back on.
6. Screen effects (static, flicker, glitch) play on demand and clear correctly.
7. Stress/health systems trigger appropriate visual feedback on the display.
8. Multiplayer: display mode syncs across clients.
9. Save/load restores display mode, pending messages, and effect state.
10. Multiple displays (watch + terminal) operate independently with separate state.
---
## 12. Data Flow Summary
```
External System (e.g. Narrative)
→ calls ReceiveMessage (S_MessagePayload)
→ BPC_DiegeticDisplay.PendingMessages.Add
→ Auto-switches to Messaging mode if currently Idle
→ Broadcast OnMessageReceived
→ Widget shows message content
→ Player dismisses → DismissMessage
→ Broadcast OnMessageDismissed
→ If queue empty → return to Idle
Player Input (Menu)
→ Input routed via SetupInputForMode (Modal)
→ Widget handles navigation
→ On close → CloseMenu → SetDisplayMode (Idle)