Files
UE5-Modular-Game-Framework/docs/blueprints/02-player/12_BPC_HidingSystem.md
Lefteris Notas 8bc731e5ae feat: Add multiplayer networking architecture and documentation updates
- Updated Master Blueprint Index to include Multiplayer Networking support.
- Added detailed Multiplayer Networking sections across all developer documentation (01-11).
- Introduced authority maps, key patterns, and RPC guidelines for each system.
- Established a comprehensive multiplayer networking architecture document outlining core principles, replication strategies, and anti-cheat considerations.
- Enhanced UI documentation to clarify local-only behavior and binding to replicated dispatchers.
- Implemented client prediction strategies and RPC naming conventions for consistency across the framework.
2026-05-19 17:15:57 +03:00

15 KiB

12 — Hiding System (BPC_HidingSystem)

Purpose

Manages the player's ability to hide inside, behind, or under environmental objects. Handles entering/exiting hiding spots, line-of-sight checks against enemies, peeking, and stress reduction while concealed. The central component for stealth gameplay.

Dependencies

  • Requires: FL_GameUtilities (interface casts), I_HidingSpot (interface on world actors)
  • Required By: AI_EnemyController (query hiding state for awareness), BPC_StressSystem (stress decay while hidden), BPC_PlayerController (movement/input restriction)
  • Engine/Plugin Requirements: GameplayTags, LineTraceByChannel (LOS checks)

Class Info

Property Value
Parent Class ActorComponent
Class Type Blueprint Component
Asset Path Content/Framework/Player/BPC_HidingSystem
Implements Interfaces None

1. Enums

E_HideState

Value Description
Exposed = 0 Not hiding, fully visible
Entering = 1 Transient — animation playing to enter hide spot
Hidden = 2 Inside hide spot, concealed
Peeking = 3 Partially visible, can look around
Exiting = 4 Transient — animation playing to exit hide spot

E_HideType

Value Description
Locker = 0 Fully enclosed (locker, wardrobe)
BehindCover = 1 Behind low wall, crate, counter
Under = 2 Under bed, table, porch
InShadow = 3 Standing in a shadow volume
TallGrass = 4 Crouch-moving through vegetation

E_PeekDirection

Value Description
Left = 0 Peek left from behind cover
Right = 1 Peek right from behind cover
Over = 2 Peek over low cover

2. Structs

S_HideSpotInfo

Field Type Description
HidingActor AActor The hide spot actor
HideType E_HideType Type of hiding
SlotCount Integer How many can hide here (-1 = infinite)
bHasPeekAbility Boolean Can player peek from this spot?
PeekSocketLeft FName Socket name for left peek camera
PeekSocketRight FName Socket name for right peek camera
PeekSocketOver FName Socket name for over peek camera
ExitLocation Vector World location to place player on exit
ExitRotation Rotator Rotation to face on exit
bBlocksStress Boolean Whether this spot reduces stress gain
HideTags GameplayTagContainer Tags for filtering
LOSTraceChannel TEnumAsByte<ETraceTypeQuery> Trace channel for LOS checks from this spot

3. Variables

Configuration (Instance Editable, Expose On Spawn)

Variable Type Default Category Description
bCanHide Boolean true Hiding Config Can this player hide at all?
StressDecayWhileHidden Float 5.0 Hiding Config Stress lost per second while hidden
bEnemyCanFindHidingSpot Boolean true Hiding Config Can enemies discover this spot
MaxPeekDuration Float 3.0 Hiding Config Max seconds player can peek before forced back
PeekCooldown Float 1.5 Hiding Config Seconds before player can peek again
CapsuleCheckRadius Float 50.0 Hiding Config Radius for capsule trace when finding hide spots

Internal (Private / Protected, No Expose)

Variable Type Default Category Description
CurrentHideState E_HideState Exposed Hiding State Current hiding state
PreviousHideState E_HideState Exposed Hiding State Previous state for transition detection
CurrentHideSpot S_HideSpotInfo - Hiding State Active hide spot data
PendingHideSpot AActor None Hiding State Hide spot being entered
PeekTimerHandle FTimerHandle - Hiding State Timer for max peek duration
PeekCooldownTimerHandle FTimerHandle - Hiding State Timer for peek cooldown
bCanPeek Boolean true Hiding State Whether peeking is allowed
LastLOSCheckTime Float 0.0 Hiding State World time of last LOS check
LOSTimerHandle FTimerHandle - Hiding State Timer for periodic LOS checks
BreathHeldTimer FTimerHandle - Hiding State Timer for breath-hold mechanic
bIsHoldingBreath Boolean false Hiding State Whether player is holding breath

Replicated (if multiplayer)

Variable Type Condition Description
CurrentHideState E_HideState RepNotify Replicated hide state
CurrentHideSpot S_HideSpotInfo Replicated Replicated spot reference

4. Functions

Public Functions

EnterHideSpotBoolean

  • Description: Attempts to enter a hiding spot. Returns true if successful.
  • Parameters:
    Param Type Description
    HideSpotActor AActor The hide spot to enter
  • Blueprint Authority: Server (if MP), Any (single-player)
  • Flow:
    1. Early-out if CurrentHideState != Exposed or !bCanHide
    2. Validate that HideSpotActor implements I_HidingSpot
    3. Check slot availability (I_HidingSpot.Execute_HasAvailableSlots)
    4. If available:
      • Set CurrentHideState = Entering
      • Store HideSpotActor info in CurrentHideSpot
      • Disable player movement input
      • Play entering animation (via ABP_GASP)
      • On animation complete: Set CurrentHideState = Hidden
      • Fire OnHideStateChanged
      • Start stress decay timer
      • Start periodic LOS check timer
      • Return true
    5. If full: return false

ExitHideSpotvoid

  • Description: Exits the current hiding spot.
  • Parameters:
    Param Type Description
    bForceExit Boolean If true, skip exit animation
  • Flow:
    1. If CurrentHideState != Hidden and CurrentHideState != Peeking: return
    2. Set CurrentHideState = Exiting
    3. If bForceExit: skip animation, immediately set Exposed
    4. Else: play exiting animation
    5. On animation complete or bForceExit:
      • Teleport player to CurrentHideSpot.ExitLocation with ExitRotation
      • Re-enable movement input
      • Set CurrentHideState = Exposed
      • Clear CurrentHideSpot
      • Stop stress decay and LOS timers
      • Fire OnHideStateChanged
      • Fire OnExitedHidingSpot

StartPeekvoid

  • Description: Begins peeking from behind cover.
  • Parameters:
    Param Type Description
    Direction E_PeekDirection Which direction to peek
  • Flow:
    1. Early-out if CurrentHideState != Hidden or !bCanPeek or !CurrentHideSpot.bHasPeekAbility
    2. Set CurrentHideState = Peeking
    3. Move camera to peek socket location
    4. Start MaxPeekDuration timer
    5. Start PeekCooldown timer (bCanPeek = false during cooldown)
    6. Fire OnPeekStarted

StopPeekvoid

  • Description: Ends the peek and returns to Hidden state.
  • Flow:
    1. If CurrentHideState != Peeking: return
    2. Set CurrentHideState = Hidden
    3. Return camera to default hide position
    4. Fire OnPeekEnded

IsPlayerDetectableBoolean

  • Description: Checks if the player is detectable from a given enemy location, considering hide type and edges.
  • Parameters:
    Param Type Description
    EnemyLocation Vector Location of the enemy
    DetectionRange Float Max range for detection check
  • Flow:
    1. If CurrentHideState != Hidden: return true (fully detectable)
    2. If EnemyLocation distance > DetectionRange: return false
    3. Perform line trace from enemy to player's approximate position
    4. If trace hits CurrentHideSpot.HidingActor before player: return false (blocked by cover)
    5. If trace hits player directly: return true (cover not fully effective)
    6. Edge case: peek state increases detection radius

TryBreathHoldvoid

  • Description: Player holds breath to reduce noise/detectability for a short time.
  • Flow:
    1. bIsHoldingBreath = true
    2. Start breath-hold timer (e.g., 8 seconds)
    3. On timer end: forced exhale, brief noise event, bIsHoldingBreath = false
    4. Fire OnBreathHoldChanged

Protected / Private Functions

PerformLOSCheckvoid

  • Description: Timer callback — checks if any enemy has line of sight to this hide spot.
  • Flow:
    1. Get all AI_EnemyController instances within detection range
    2. For each enemy: call IsPlayerDetectable(EnemyLocation)
    3. If any enemy has LOS:
      • Fire OnHideSpotCompromised
      • If CurrentHideSpot.bEnemyCanFindHidingSpot: fire OnForcedExitWarning

OnAnimationHideEnterCompletevoid

  • Description: Animation notify callback when enter animation finishes.
  • Flow:
    1. Set CurrentHideState = Hidden
    2. Attach player to hide spot socket if applicable
    3. Fire OnHideStateChanged
    4. Start stress decay loop

OnAnimationHideExitCompletevoid

  • Description: Animation notify callback when exit animation finishes.
  • Flow:
    1. Perform final exit steps already queued in ExitHideSpot

5. Event Dispatchers

Dispatcher Parameters Bind Access Description
OnHideStateChanged E_HideState OldState, E_HideState NewState Public Fired on any hide state change
OnEnteredHidingSpot AActor HideSpot, E_HideType HideType Public Fired when player successfully hides
OnExitedHidingSpot AActor HideSpot Public Fired when player leaves hiding
OnPeekStarted E_PeekDirection Direction Public Fired when player starts peeking
OnPeekEnded none Public Fired when player stops peeking
OnHideSpotCompromised AActor EnemyActor Public Fired when an enemy sees the player's spot
OnForcedExitWarning float TimeUntilDiscovered Public Fired when enemy is approaching known spot
OnBreathHoldChanged bool bIsHoldingBreath Public Fired when breath hold toggles

6. Overridden Events / Custom Events

Event: BeginPlay

  • Description: Initialises state, binds to input actions.
  • Flow:
    1. Set CurrentHideState = Exposed
    2. Register with GI_GameTagRegistry if needed
    3. Cache reference to CharacterMovementComponent for disabling during hide

Custom Event: ForceKickFromHide

  • Description: Called externally (e.g., by enemy discovery) to force player out of hiding.
  • Flow:
    1. Call ExitHideSpot(bForceExit = true)
    2. Apply brief stun or camera shake
    3. Fire OnForcedExitWarning with 0 seconds

Custom Event: OnDamageWhileHiding

  • Description: Listener for when damage is taken while hidden.
  • Flow:
    1. If damage source penetrates cover: force exit
    2. Else: reduce stress instead of health (environmental damage)

7. Blueprint Graph Logic Flow

flowchart TD
    A[EnterHideSpot called] --> B{Is Exposed?}
    B -->|No| C[Return false]
    B -->|Yes| D[Validate I_HidingSpot]
    D --> E{Has available slots?}
    E -->|No| F[Return false]
    E -->|Yes| G[Set Entering state]
    G --> H[Disable movement input]
    H --> I[Play Enter animation]
    I --> J[Animation notify: OnComplete]
    J --> K[Set Hidden state]
    K --> L[Start stress decay loop]
    L --> M[Start periodic LOS check]
    M --> N[Fire OnEnteredHidingSpot]
    N --> O[Return true]

8. Communication Matrix

Who Talks How What Is Sent
BPC_HidingSystem Dispatcher OnHideStateChanged -> BPC_PlayerController (input), ABP_GASP (anim), BPC_StressSystem (decay), AI_EnemyController (awareness reset)
BPC_HidingSystem Dispatcher OnHideSpotCompromised -> BPC_StressSystem (stress spike), BP_AudioManager (tension music)
BPC_HidingSystem Dispatcher OnForcedExitWarning -> WBP_HUD (hide icon flash), BP_AudioManager (heartbeat)
External (AI) Query IsPlayerDetectable called by AI_EnemyController for LOS checks
External (World) Interface I_HidingSpot on BP_Locker, BP_Wardrobe, BP_Cover
BPC_HidingSystem Dispatcher OnPeekStarted/Ended -> BPC_CameraStateLayer (FOV/position)

9. Validation / Testing Checklist

  • EnterHideSpot correctly transitions through Entering -> Hidden
  • ExitHideSpot correctly transitions through Exiting -> Exposed
  • Forced exit with bForceExit = true skips animation, immediately exits
  • Peek timer forces player back to Hidden after MaxPeekDuration
  • PeekCooldown prevents rapid peek toggling
  • IsPlayerDetectable returns correct values for all hide types and peek states
  • Multiple hide spots with limited slots: full slots reject entry
  • Stress decays while hidden at configured rate
  • LOS check detects enemies within range and fires compromise dispatcher
  • Edge case: EnterHideSpot called while already hiding returns false
  • Edge case: ExitHideSpot called while Exposed does nothing
  • Edge case: Destroying hide spot while inside force-exits player

10. Reuse Notes

  • Enemy AI characters can use a simplified version to find and occupy hide spots.
  • Hide spots can be pre-placed (lockers, beds) or dynamic (shadow volumes, tall grass).
  • The LOS trace channel should be custom (e.g., DetectionChannel) to ignore small props.
  • Breath-hold mechanic adds depth to stealth gameplay near enemies.
  • For multiplayer: only the hiding player knows their state; other players see a generic "occupado" on the spot.

11. Multiplayer Networking (Expanded)

Server RPCs

RPC Direction Description
Server_EnterHideSpot Client→Server Client requests entering hide spot. Server validates slot availability, proximity.
Server_ExitHideSpot Client→Server Client requests exiting. Server validates, teleports player, replicates.
Server_StartPeek Client→Server Client starts peeking. Server validates peek ability, starts duration timer.
Server_StopPeek Client→Server Client stops peeking. Server returns to Hidden state.
Server_TryBreathHold Client→Server Client holds breath. Server validates, applies noise reduction on server.

Authority

  • EnterHideSpot, ExitHideSpot are server-authoritative.
  • IsPlayerDetectable is server-only — AI runs on server.
  • PerformLOSCheck runs on server; results multicast to clients for UI feedback.
  • ForceKickFromHide is server-only (triggered by enemy discovery / damage).

Client Prediction

  • Enter/exit animations: client predicts; server confirms via replicated CurrentHideState.
  • Peek: camera offset is local; state replicated.
  • Hide spot occupation: I_HidingSpot.OccupantPawn is replicated — other clients see "Occupied".
  • Hide spots with bBlocksStress = true can double as narrative safe rooms.

Blueprint Spec: Hiding System. Conforms to TEMPLATE.md v1.0 — part of the UE5 Modular Game Framework.