16 — Interaction Detector (BPC_InteractionDetector)
Purpose
The player's "interaction eye" — performs trace-based detection of interactable objects in the world, sorts them by priority/distance, tracks the current best target, and manages the interaction prompt widget. Every interactive system in the game funnels through this component.
Dependencies
- Requires:
I_Interactable (interface on all interactable actors), PlayerCameraManager (for trace origin), BPC_MovementStateSystem (block interaction during specific states)
- Required By:
WBP_InteractionPrompt (HUD element), BPC_PickupComponent, BPC_InteractableDoorComponent, BPC_LeverPuzzleComponent
- Engine/Plugin Requirements:
LineTraceByChannel (ECC_GameTraceChannel1 = Interaction), TimerHandle for scan interval
Class Info
| Property |
Value |
| Parent Class |
ActorComponent |
| Class Type |
Blueprint Component |
| Asset Path |
Content/Framework/Interaction/BPC_InteractionDetector |
| Implements Interfaces |
None |
1. Enums
E_InteractionInputMode
| Value |
Description |
Press = 0 |
Single press to interact |
Hold = 1 |
Hold over duration to confirm |
DoubleTap = 2 |
Two rapid presses |
Auto = 3 |
Automatic on proximity (no input) |
E_InteractionPriority
| Value |
Description |
Low = 0 |
Ambient / cosmetic items |
Normal = 1 |
Standard pickups, doors |
High = 2 |
Story-critical, puzzles |
Emergency = 3 |
Immediate threat (hide spot, weapon) |
E_DetectionState
| Value |
Description |
NoTarget = 0 |
Nothing in range |
TargetInRange = 1 |
Potential target found |
TargetConfirmed = 2 |
Best target selected |
Interacting = 3 |
Currently performing interaction |
2. Structs
S_InteractableTarget
| Field |
Type |
Description |
TargetActor |
AActor |
The interactable actor |
InterfaceRef |
I_Interactable |
Cast to interface |
Priority |
E_InteractionPriority |
Priority level |
Distance |
Float |
Distance from player to target |
InteractionLabel |
FText |
Display name (e.g. "Open Door", "Pick Up Key") |
InputMode |
E_InteractionInputMode |
How interaction is triggered |
HoldDuration |
Float |
Seconds required if InputMode is Hold |
bIsHighlighted |
Boolean |
Whether target is visually highlighted |
TargetLocation |
Vector |
World location for UI widget |
S_InteractionResult
| Field |
Type |
Description |
bSuccess |
Boolean |
Whether interaction was successful |
FailureReason |
FText |
Human-readable failure reason |
TargetActor |
AActor |
The interacted actor |
ContextTag |
GameplayTag |
Tag for event recording |
3. Variables
Configuration (Instance Editable, Expose On Spawn)
| Variable |
Type |
Default |
Category |
Description |
InteractionRange |
Float |
250.0 |
Detection Config |
Max trace distance (cm) |
DetectionAngle |
Float |
45.0 |
Detection Config |
Cone half-angle for detection (degrees) |
TraceRadius |
Float |
10.0 |
Detection Config |
Sphere trace radius |
ScanInterval |
Float |
0.1 |
Detection Config |
Seconds between detection scans |
MaxTargetsInRange |
Integer |
16 |
Detection Config |
Max detected targets per scan |
bShowDebugTrace |
Boolean |
false |
Detection Config |
Visualise trace in editor |
TraceChannel |
TEnumAsByte<ECollisionChannel> |
ECC_GameTraceChannel1 |
Detection Config |
Collision channel for interaction |
bBlockDuringDeath |
Boolean |
true |
Detection Config |
Block interaction while dead |
bBlockDuringHiding |
Boolean |
true |
Detection Config |
Block interaction while hidden |
bBlockDuringCombat |
Boolean |
false |
Detection Config |
Block interaction during combat |
Internal (Private / Protected, No Expose)
| Variable |
Type |
Default |
Category |
Description |
BestTargetIndex |
Integer |
-1 |
Detection State |
Index of currently selected target |
DetectedTargets |
Array<S_InteractableTarget> |
[] |
Detection State |
All detected targets this scan |
CurrentTarget |
S_InteractableTarget |
- |
Detection State |
Currently selected best target |
DetectionState |
E_DetectionState |
NoTarget |
Detection State |
Current state of the detector |
bIsPerformingInteraction |
Boolean |
false |
Detection State |
Whether interaction is in progress |
HoldInteractionProgress |
Float |
0.0 |
Detection State |
Progress for hold-type interactions |
OwnerPlayerController |
APlayerController |
None |
Cache |
Cached player controller |
OwnerCameraManager |
APlayerCameraManager |
None |
Cache |
Cached camera manager |
ScanTimerHandle |
FTimerHandle |
- |
Timing |
Timer for scan interval |
DetectedActors_LastFrame |
Set<AActor> |
{} |
Tracking |
Previous frame targets for enter/exit detection |
Replicated (if multiplayer)
| Variable |
Type |
Condition |
Description |
CurrentTarget |
S_InteractableTarget |
Replicated |
Synced selected target |
4. Functions
Public Functions
StartDetection → void
- Description: Begins the scan loop for interactable targets.
- Parameters: None
- Flow:
- Get owner Player Controller
- Get Player Camera Manager
- Start scan timer (ScanInterval)
- If bShowDebugTrace: enable debug line visualisation
StopDetection → void
- Description: Stops the scan loop and clears detected targets.
- Parameters: None
- Flow:
- Clear scan timer
- Clear DetectedTargets array
- Set DetectionState = NoTarget
- Fire OnTargetLost
- Clear any highlight effects
PerformInteraction → S_InteractionResult
- Description: Executes interaction on the current best target.
- Parameters:
| Param |
Type |
Description |
InputMode |
E_InteractionInputMode |
How the input was triggered |
- Flow:
- If not CurrentTarget valid or CurrentTarget actor is None: return failure
- If bIsPerformingInteraction: return failure (already interacting)
- If InputMode != CurrentTarget.InputMode: return failure (input mismatch)
- Set bIsPerformingInteraction = true
- Set DetectionState = Interacting
- Fire OnInteractionStarted
- Call CurrentTarget.InterfaceRef.ExecuteInteraction (owner)
- Wait for I_Interactable.OnInteractionCompleted or timeout
- On completion: set bIsPerformingInteraction = false
- Resume scanning
- Return S_InteractionResult with success/failure
CancelInteraction → void
- Description: Aborts the current interaction if possible.
- Parameters: None
- Flow:
- If not bIsPerformingInteraction: return
- Call CurrentTarget.InterfaceRef.CancelInteraction
- Set bIsPerformingInteraction = false
- HoldInteractionProgress = 0.0
- Set DetectionState = TargetConfirmed
- Fire OnInteractionCancelled
GetBestTarget → S_InteractableTarget
- Description: Returns the current best target.
- Parameters: None
- Flow: Return CurrentTarget
HasTarget → Boolean
- Parameters: None
- Flow: Return DetectionState >= TargetInRange
ForceSetTarget → void
- Description: Forcefully sets a specific target (for scripted interactions).
- Parameters:
| Param |
Type |
Description |
TargetActor |
AActor |
The specific actor to target |
- Flow:
- If TargetActor implements I_Interactable:
- Build S_InteractableTarget
- Set CurrentTarget
- Set DetectionState = TargetConfirmed
- Fire OnTargetFound
- Else: fire OnInteractionError(not interactable)
Private Functions
ScanForInteractables (Timer) → void
- Description: Timer callback — performs trace and sorts targets.
- Flow:
- If DetectionState == Interacting: return (skip scan while interacting)
- Get camera forward vector and world location
- Sphere trace forward (TraceRadius, InteractionRange, TraceChannel)
- For each hit actor:
- If implements I_Interactable: add to DetectedTargets
- If not: skip
- Remove duplicates by actor reference
- Sort by Priority (descending), then Distance (ascending)
- Clamp to MaxTargetsInRange
- Track enter/exit for each actor — fire OnTargetEntered / OnTargetExited
- Select BestTarget from sorted list
- Update DetectionState accordingly
- Fire OnTargetFound or OnTargetLost
CalculateInteractionScore → Float
- Description: Computes a score for a target based on priority, distance, and facing angle.
- Parameters:
| Param |
Type |
Description |
Target |
S_InteractableTarget |
The target to score |
- Flow:
- Score = Priority * 100 - Distance * 0.5
- Facing bonus: if angle < 15 deg, add 50
- Return Max(0, Score)
HighlightTarget → void
- Description: Applies highlight effect to target actor.
- Parameters:
| Param |
Type |
Description |
Target |
S_InteractableTarget |
Target to highlight |
bHighlighted |
Boolean |
Whether to enable or disable |
- Flow:
- Call Target.InterfaceRef.SetHighlighted(bHighlighted)
GetViewTraceOrigin → Vector, Vector
- Description: Returns camera location and forward direction for trace.
- Parameters: None
- Flow:
- If OwnerCameraManager valid:
- Return cam location and forward vector
- Else: fall back to owner actor location and forward
5. Event Dispatchers
| Dispatcher |
Parameters |
Bind Access |
Description |
OnTargetFound |
S_InteractableTarget NewTarget |
Public |
New best target selected |
OnTargetLost |
S_InteractableTarget LostTarget |
Public |
Current target lost from view / range |
OnTargetEntered |
AActor TargetActor |
Public |
Actor entered detectable range |
OnTargetExited |
AActor TargetActor |
Public |
Actor left detectable range |
OnInteractionStarted |
S_InteractableTarget Target |
Public |
Interaction began |
OnInteractionCompleted |
S_InteractionResult Result |
Public |
Interaction finished |
OnInteractionCancelled |
S_InteractableTarget Target |
Public |
Interaction was cancelled |
OnInteractionError |
FText ErrorMessage |
Public |
Interaction blocked or failed |
OnHoldProgressUpdated |
Float Progress, S_InteractableTarget Target |
Public |
Hold interaction progress [0..1] |
6. Overridden Events / Custom Events
Event: BeginPlay
- Description: Cache references, bind to relevant systems, start detection.
- Flow:
- Get owning actor → ensure it is a Pawn
- Get Player Controller from owner
- Get Player Camera Manager from controller
- Bind to BPC_MovementStateSystem.OnPostureChanged — block when hidden
- Bind to BPC_HealthSystem.OnDeathStateChanged — block when dead
- StartDetection()
Custom Event: OnInputInteractPressed
- Description: Handles press input for interaction.
- Flow:
- If DetectionState < TargetConfirmed: return
- If CurrentTarget.InputMode == Press:
- PerformInteraction(Press)
- If CurrentTarget.InputMode == Hold:
- If CurrentTarget.InputMode == DoubleTap:
- Wait for second press within threshold
Custom Event: OnHoldProgressTick (Timer) → void
- Description: Ticks hold interaction progress and fires progress dispatcher.
- Flow:
- HoldInteractionProgress += DeltaTime / CurrentTarget.HoldDuration
- Clamp to 1.0
- Fire OnHoldProgressUpdated
- If HoldInteractionProgress >= 1.0: PerformInteraction(Hold)
Custom Event: OnInputInteractReleased
- Description: Cancels hold interaction if button released early.
- Flow:
- If CurrentTarget.InputMode == Hold and not completed:
- CancelInteraction()
- HoldInteractionProgress = 0.0
7. Blueprint Graph Logic Flow
8. Communication Matrix
| Who Talks |
How |
What Is Sent |
BPC_InteractionDetector |
Dispatcher |
OnTargetFound -> WBP_InteractionPrompt (show prompt) |
BPC_InteractionDetector |
Dispatcher |
OnTargetLost -> WBP_InteractionPrompt (hide prompt) |
BPC_InteractionDetector |
Dispatcher |
OnInteractionStarted -> BPC_PlayerMetricsTracker (log event) |
BPC_InteractionDetector |
Dispatcher |
OnInteractionCompleted -> BPC_PlayerMetricsTracker (log result) |
BPC_InteractionDetector |
Dispatcher |
OnHoldProgressUpdated -> WBP_InteractionPrompt (progress bar) |
BPC_InteractionDetector |
Dispatcher |
OnInteractionCancelled -> WBP_InteractionPrompt (hide) |
BPC_InteractionDetector |
Listener |
Binds to BPC_MovementStateSystem.OnPostureChanged |
BPC_InteractionDetector |
Listener |
Binds to BPC_HealthSystem.OnDeathStateChanged |
BPC_InteractionDetector |
Direct |
Calls I_Interactable.ExecuteInteraction on target |
BPC_InteractionDetector |
Direct |
Calls I_Interactable.CancelInteraction on target |
BPC_InteractionDetector |
Direct |
Calls I_Interactable.SetHighlighted on target |
BPC_InteractionDetector |
Direct call (other) |
GetBestTarget called by WBP_InteractionPrompt for name |
PC_PlayerController |
Input Event |
Binds press / release / hold to OnInputInteractPressed etc. |
9. Validation / Testing Checklist
10. Reuse Notes
- TraceChannel should be set to a custom object channel (ECC_GameTraceChannel1) with only interactable actors responding.
- Priority values can be overridden per actor via the
I_Interactable interface's GetInteractionPriority function.
- The hold interaction progress is designed to drive a radial progress widget in the HUD.
- For controller/console:
E_InteractionInputMode.Hold is preferred to prevent accidental interactions.
- The same component can be attached to NPCs if they need interaction detection.
- To support networked games: replicate CurrentTarget and have each client run their own trace locally.
Blueprint Spec: Interaction Detector. Conforms to TEMPLATE.md v1.0 — part of the UE5 Modular Game Framework.