ποΈ Interactable Objects
Games come alive when the world responds to players. Pressing a button to open a door, picking up a health pack, flipping a switch to activate a bridgeβthese interactions transform a static environment into a living world. In this lesson, you'll learn how to create objects that respond to player input, combining line traces for detection with input actions for activation. By the end, you'll have a complete interaction system ready for any game.
π― Learning Objectives
By the end of this lesson, you will be able to:
- Implement line traces to detect interactable objects
- Create a reusable interaction interface
- Build interactable doors, switches, and pickups
- Display interaction prompts to the player
- Combine collision, input, and visual feedback for polished interactions
Estimated Time: 55-65 minutes
Prerequisites: Lesson 6.4 (Collision and Physics Interaction), Lesson 6.2 (Enhanced Input System)
π In This Lesson
Interaction System Overview
An interaction system answers two questions: "What can the player interact with?" and "What happens when they do?" Different games answer these questions differently, but most interaction systems share common components.
Types of Interaction
Proximity-Based (Automatic): Interaction happens automatically when the player gets close. Triggers from the previous lesson handle thisβwalking through a door opens it, stepping on a platform activates it.
Input-Based (Manual): Interaction requires a button press. The player must be near an object AND press a key. This is what we'll focus on in this lessonβ"Press E to interact" style systems.
Hybrid: Some objects use both. A door might open automatically when you approach, but a chest requires pressing a button to open.
Components of an Interaction System
A complete interaction system typically includes:
Detection: Determining what the player can interact with. This can use overlap triggers (radius around player), line traces (what you're looking at), or both.
Identification: Recognizing that an object is interactable and what kind of interaction it supports. Interfaces or tags help with this.
Feedback: Showing the player they can interact. UI prompts ("Press E to Open"), object highlights, crosshair changes.
Execution: Actually performing the interaction when the player presses the button. Each object handles its own logic.
Figure: The four components of a typical interaction system.
Our Approach
In this lesson, we'll build an interaction system that:
- Uses a line trace from the camera to detect what the player is looking at
- Checks if the hit object implements an interaction interface
- Shows a UI prompt when an interactable is detected
- Calls the object's Interact function when the player presses E
This approach is flexible, scalable, and used in many professional games.
π‘ Why Line Traces?
Line traces let the player interact with what they're looking at, not just what's nearby. This is more intuitiveβyou point at a door and press E, rather than bumping into it. It also allows interaction at a distance (picking up items from across the room) if desired.
Line Traces for Detection
A line trace (also called a raycast) shoots an invisible line from one point to another and reports what it hits. It's the most common way to detect what the player is looking at or aiming at.
Line Trace Basics
A line trace needs:
- Start Point: Where the line begins (usually camera location)
- End Point: Where the line ends (camera location + forward direction Γ distance)
- Trace Channel: What types of objects to hit (Visibility, Camera, custom channels)
- Ignored Actors: Actors to skip (usually the player themselves)
The trace returns a Hit Result containing information about what was hit: the actor, component, location, normal, and more.
Line Trace by Channel
The most common node is Line Trace By Channel:
- In Blueprint, right-click and search "Line Trace By Channel"
- Connect Start and End vectors
- Select Trace Channel (usually Visibility)
- The node outputs a boolean (hit something?) and a Hit Result struct
Figure: Line trace from camera stops at first blocking object and returns hit information.
Setting Up the Trace in Character
We'll add the interaction trace to the player character, running every frame (or every few frames for performance):
Get Start Point:
- Get the player camera's location:
Get Player Camera ManagerβGet Camera Location - Or use the character's camera component if you have one
Get End Point:
- Get camera forward vector:
Get Camera RotationβGet Forward Vector - Multiply by trace distance (e.g., 300 units)
- Add to start point:
Start + (Forward Γ Distance)
Perform the Trace:
- Add
Line Trace By Channel - Connect Start and End
- Set Trace Channel to Visibility
- Add Self to Actors to Ignore array
Figure: Basic interaction trace running on Event Tick.
Extracting Hit Information
When the trace hits something, extract information from the Hit Result:
Break Hit Resultβ Splits the struct into individual valuesHit Actorβ The actor that was hit (use this to check for interface)Hit Componentβ The specific component hitImpact Pointβ World location of the hitImpact Normalβ Surface direction at hit point
Optimizing the Trace
Running a trace every frame works but can be optimized:
Use a Timer: Instead of Event Tick, use a timer that fires every 0.1 seconds. Still responsive but fewer traces.
Trace on Input: Only trace when the player presses the interact key, not continuously. Simpler but no preview prompt.
Short Distance: Keep trace distance reasonable (200-400 units). Longer traces have minimal benefit for interaction.
β οΈ Debug Visualization
The Line Trace node has a "Draw Debug Type" parameter. Set it to "For Duration" during development to see the trace line in-game. Remember to set it back to "None" for the final build!
The Interaction Interface Pattern
When your trace hits an object, how do you know it's interactable? You could check the actor's class, but that gets messy with many interactable types. The cleaner solution is a Blueprint Interface.
What is a Blueprint Interface?
A Blueprint Interface defines a contractβa set of functions that any Blueprint can implement. It's like saying "any actor that implements BPI_Interactable promises to have an Interact function."
Benefits of interfaces:
- Decoupling: The player doesn't need to know about every interactable class
- Flexibility: Any actor can be interactable by implementing the interface
- Consistency: All interactables have the same function signature
- Easy checking: "Does this actor implement BPI_Interactable?" is a simple yes/no
Figure: One interface, many implementations. Each object handles Interact differently.
Creating the Interface
- In Content Browser, right-click β Blueprints β Blueprint Interface
- Name it
BPI_Interactable - Double-click to open
In the Interface Editor, add functions:
Add Interact Function:
- In the Functions panel, there's a default "NewFunction" β rename it to
Interact - Select the function and add an input parameter:
- Name:
Caller - Type:
Actor(object reference)
- Name:
- This lets the interactable know WHO is interacting (useful for player-specific logic)
Add GetInteractionText Function:
- Click + Add Function in the Functions panel
- Name it
GetInteractionText - Add an output parameter:
- Name:
Text - Type:
String
- Name:
- This returns the prompt text ("Open Door", "Pick Up", etc.)
Compile and save the interface.
Figure: BPI_Interactable with two functions: Interact and GetInteractionText.
Implementing the Interface
To make an actor interactable:
- Open the actor's Blueprint
- Go to Class Settings (toolbar)
- In Details panel, find Interfaces β Implemented Interfaces
- Click Add and select
BPI_Interactable - Compile β new events appear in the Event Graph
Now implement the functions:
Implement Interact:
- In My Blueprint panel, under Interfaces, find
Interact - Double-click or right-click β Implement Event
- An event node appears β add your interaction logic after it
Implement GetInteractionText:
- Find
GetInteractionTextunder Interfaces - Implement it β this is a function, not an event
- Add a Return node with your text string
Checking for Interface in Player
Back in the player character, after the line trace hits something:
- Get the
Hit Actorfrom the trace result - Use
Does Implement Interfacenode - Select
BPI_Interactable - Branch on the result
If true, call GetInteractionText on the actor to get the prompt, and store the actor reference for when the player presses the interact key.
flowchart TD
A["Line Trace Hit"] --> B["Get Hit Actor"]
B --> C{"Does Implement
BPI_Interactable?"}
C -->|"Yes"| D["Store as Current Target"]
D --> E["Call GetInteractionText"]
E --> F["Show UI Prompt"]
C -->|"No"| G["Clear Current Target"]
G --> H["Hide UI Prompt"]
style A fill:#4CAF50,color:#fff
style C fill:#667eea,color:#fff
style F fill:#FF9800,color:#fff
style H fill:#607D8B,color:#fff
Figure: Flow for checking if a hit actor is interactable.
Calling Interact on Input
When the player presses the interact key (E):
- Check if we have a valid
Current Target(from the trace) - If yes, call
Interactinterface message on that actor - Pass
Self(the player) as the Caller parameter
Use Interact (Message) node, not a direct function call. Messages work on any actor implementing the interface without needing to know the specific class.
β Interface Message vs. Function Call
When calling interface functions, use the Message version (shows with an envelope icon). It safely handles the call even if the target doesn't implement the interface, returning nothing instead of crashing. Direct interface calls require casting first.
Creating Interactable Objects
Now that we have an interaction system framework, let's create some actual interactable objects. Each object implements the BPI_Interactable interface and handles its own behavior when Interact is called.
Interactable Door
An interactive door opens or closes when the player interacts with it. We'll use a timeline to animate the rotation smoothly.
Create the Door Blueprint:
- Right-click in Content Browser β Blueprint Class β Actor
- Name it
BP_InteractableDoor - Open and add components:
- Scene (root) β acts as the pivot point
- Static Mesh (child of Scene) β the door mesh
- Box Collision (child of root) β for blocking
Set up the mesh:
- Select the Static Mesh component
- Assign a door mesh (or use a scaled cube: 100Γ10Γ200)
- Offset the mesh so the pivot (Scene root) is at the hinge edge
- For a door 100 units wide, offset X by 50 so the left edge aligns with the pivot
Implement the Interface:
- Class Settings β Add
BPI_Interactable - Compile
- Implement
GetInteractionText: Return "Open Door" or "Close Door" based on state - Implement
Interactevent: Toggle between open and closed
Create the open/close animation:
- Create a variable
IsOpen(Boolean, default False) - Add a Timeline named "DoorTimeline"
- In the timeline, add a Float track named "Alpha" (0 to 1 over 0.5 seconds)
- Use
Lerp (Rotator)to interpolate between closed (0, 0, 0) and open (0, 90, 0) - Set the Scene component's relative rotation
Figure: Door Blueprint with components, variables, and animation timeline.
Interactable Pickup
A pickup item that the player collects (health, ammo, coins). When interacted with, it adds to the player's inventory and destroys itself.
Create the Pickup Blueprint:
- Create new Actor Blueprint:
BP_InteractablePickup - Add components:
- Static Mesh β the item visual
- Sphere Collision β for proximity detection (optional)
- Point Light β glow effect (optional)
Variables:
ItemName(String) β "Health Pack", "Gold Coin", etc.ItemValue(Integer) β Amount to give (25 health, 100 gold)- Make these Instance Editable so each pickup can be configured in the level
Implement Interface:
GetInteractionText: Return "Pick up " + ItemNameInteract:- Cast Caller to your character class
- Call a function on character to add item (e.g., AddHealth, AddGold)
- Play pickup sound
- Destroy Actor (self)
Figure: Different pickup types use the same base system with different values.
Interactable Switch
A switch that toggles something else in the levelβa light, a door, a platform. Switches demonstrate how interactables can affect other actors.
Create the Switch Blueprint:
- Create
BP_InteractableSwitch - Add components:
- Static Mesh β switch/lever visual
- Point Light β indicator (red/green)
Variables:
IsActivated(Boolean) β Current stateLinkedActors(Array of Actors) β Things to toggle- Make LinkedActors Instance Editable for level design
Implement Interface:
GetInteractionText: Return "Activate" or "Deactivate" based on stateInteract:- Toggle IsActivated
- Update indicator light color
- Loop through LinkedActors and call their activation function
Actor Communication: Event Dispatchers
How does a switch tell a door to open? Several approaches:
Direct Reference: The switch has a reference to specific actors and calls functions on them. Simple but tightly coupled.
Interface: Create a BPI_Activatable interface with Activate/Deactivate functions. Linked actors implement it.
Event Dispatcher: The switch broadcasts an event. Any actor can bind to it and respond. Most flexible.
For simple cases, direct reference works fine. We'll use that approach in the hands-on exercise.
flowchart LR
S["BP_Switch"] -->|"Interact"| T["Toggle State"]
T --> L["Loop LinkedActors"]
L --> D1["Door 1
Open/Close"]
L --> D2["Light 1
On/Off"]
L --> D3["Platform
Move"]
style S fill:#9C27B0,color:#fff
style T fill:#667eea,color:#fff
style D1 fill:#4CAF50,color:#fff
style D2 fill:#FF9800,color:#fff
style D3 fill:#2196F3,color:#fff
Figure: A switch can control multiple linked actors.
Adding Visual Feedback
Great interactions include visual feedback:
Highlight Effect:
- Enable "Render Custom Depth" on the mesh when targeted
- Use a post-process material to create outline effect
- Or simply change material/emissive when targeted
UI Prompt:
- Create a Widget Blueprint with text ("Press E to Open")
- Add Widget Component to interactables, or
- Display a single HUD widget that updates based on current target
Interaction Feedback:
- Play sound effect on interact
- Spawn particle effect
- Brief UI flash or icon
Figure: Visual feedback progresses from normal β targeted β interacted.
π‘ Reusable Base Class
For games with many interactables, create a base class BP_InteractableBase that implements the interface and common functionality (highlight, sound). Then create child classes (BP_Door, BP_Pickup) that override specific behavior. This reduces duplicate code.
Hands-On: Build an Interactive Door
Let's build a complete interactive door system from scratch. We'll create the interface, the door Blueprint, the interaction detection in the character, and a simple UI prompt.
π― Exercise Goal
Create a door that: shows "Press E to Open/Close" when the player looks at it, opens with smooth animation when interacted, and closes when interacted again. This demonstrates the complete interaction workflow.
Step 1: Create the Interface
- Content Browser β Right-click β Blueprints β Blueprint Interface
- Name it
BPI_Interactable - Double-click to open
Add Interact function:
- Rename the default function to
Interact - Add input:
Caller(Actor Reference)
Add GetInteractionText function:
- Click + Add Function
- Name it
GetInteractionText - Add output:
Text(String)
Compile and save.
Step 2: Create the Door Blueprint
- Right-click β Blueprint Class β Actor
- Name it
BP_InteractableDoor - Open it
Add Components:
- Add
Scenecomponent β name it "Pivot" (this will be root) - Make Pivot the root by dragging it onto DefaultSceneRoot
- Add
Static Meshas child of Pivot β name it "DoorMesh" - Set DoorMesh's Static Mesh to
Shape_Cube - Scale DoorMesh to (1, 0.1, 2) for a door-like shape
- Set DoorMesh's Location to (50, 0, 100) β offset so pivot is at edge
Add Variables:
IsOpen(Boolean) β Default: FalseOpenAngle(Float) β Default: 90, Instance Editable
Implement Interface:
- Click Class Settings in toolbar
- In Details β Interfaces β Add
BPI_Interactable - Compile
Step 3: Implement GetInteractionText
- In My Blueprint panel, find Interfaces β GetInteractionText
- Double-click to create the function graph
- Add a
Selectnode (String) - Connect
IsOpento the Index - Set False option to "Open Door"
- Set True option to "Close Door"
- Connect Select output to Return Node's Text input
Step 4: Create Door Timeline
- In Event Graph, right-click β Add Timeline
- Name it "DoorTimeline"
- Double-click to open timeline editor
- Click + Track β Add Float Track
- Name the track "DoorAlpha"
- Add keyframes:
- Time 0, Value 0
- Time 0.5, Value 1
- Set Length to 0.5
- Close timeline editor
Step 5: Implement Interact Event
- In My Blueprint β Interfaces, right-click
Interactβ Implement Event - From the Interact event:
- Add a
Branchnode - Connect
IsOpento condition
- Add a
- If False (door is closed):
- Set IsOpen to True
- DoorTimeline β
Play from Start
- If True (door is open):
- Set IsOpen to False
- DoorTimeline β
Reverse from End
Step 6: Animate Door Rotation
- From DoorTimeline's
Updateoutput: - Add
Lerp (Rotator)node - A: Make Rotator (0, 0, 0) β closed position
- B: Make Rotator (0, OpenAngle, 0) β open position
- Alpha: Connect to DoorAlpha output from timeline
- Drag
Pivotcomponent into graph - From Pivot, add
Set Relative Rotation - Connect Lerp output to New Rotation
Figure: Interact toggles the timeline direction; timeline drives rotation.
Step 7: Add Interaction to Character
Open your character Blueprint and add:
Variables:
CurrentInteractable(Actor Reference) β Stores what we're looking atInteractionDistance(Float) β Default: 300
Create Interaction Trace Function:
- Create a new function
CheckForInteractable - Get camera location and rotation (Get Player Camera Manager β Get Camera Location/Rotation)
- Calculate end point: Location + (Forward Vector Γ InteractionDistance)
- Line Trace By Channel (Visibility)
- If hit:
- Get Hit Actor
- Does Implement Interface (BPI_Interactable)?
- If yes: Set CurrentInteractable = Hit Actor
- If no: Set CurrentInteractable = None
- If no hit: Set CurrentInteractable = None
Call on Tick:
- Event Tick β Call CheckForInteractable
Handle Interact Input:
- Create Input Action
IA_Interact(Digital) - Map to E key in your Mapping Context
- Add EnhancedInputAction IA_Interact event
- Check if CurrentInteractable is valid
- If valid: Call
Interact(Message) on CurrentInteractable, pass Self as Caller
Step 8: Add Simple UI Prompt
Create a basic text widget:
- Right-click β User Interface β Widget Blueprint
- Name it
WBP_InteractionPrompt - Add a Text Block centered on screen
- Bind text to a variable or function
In Character:
- Create widget on BeginPlay, add to viewport, store reference
- In CheckForInteractable, when CurrentInteractable changes:
- If valid: Get Interaction Text, set widget text, show widget
- If none: Hide widget
Step 9: Test
- Place BP_InteractableDoor in your level
- Play the game
- Look at the door β prompt should appear
- Press E β door should open
- Press E again β door should close
- Look away β prompt should disappear
β Exercise Complete!
You've built a complete interaction system with:
- Blueprint Interface for consistent interaction API
- Line trace detection for "look at" targeting
- Animated door with timeline-driven rotation
- Input handling for the interact key
- UI feedback showing interaction prompts
This same pattern works for any interactable objectβjust implement the interface!
Bonus Challenges
- Locked Door: Add a
IsLockedvariable. If locked, GetInteractionText returns "Locked", Interact does nothing or plays error sound - Key Required: Check if player has key item before unlocking
- Sound Effects: Play door open/close sounds using Play Sound at Location
- Auto-Close: Add a timer that closes the door after a few seconds
- Pickup Item: Create BP_InteractablePickup that destroys itself and adds health to player
Summary
In this lesson, you've built a complete interaction systemβthe foundation for player engagement with the game world. From detecting what the player is looking at to responding with custom behaviors, you now understand how to make any object interactive.
Key Concepts
Interaction System Components: Detection (what can be interacted with), Identification (is it interactable?), Feedback (UI prompts, highlights), and Execution (the actual interaction logic). These four components work together to create polished interactions.
Line Traces: Invisible rays that detect what the player is looking at. Start from the camera, extend forward, and return hit information. Line Trace By Channel uses collision channels to filter what can be hit.
Blueprint Interfaces: Contracts that define what functions an actor must implement. BPI_Interactable with Interact and GetInteractionText functions allows any actor to be interactable without the player needing to know specific classes.
Interface Messages: Safe way to call interface functions on actors. Use "Interact (Message)" rather than direct callsβit handles cases where the target doesn't implement the interface gracefully.
Interactable Objects: Doors use timelines for smooth rotation. Pickups collect items and destroy themselves. Switches toggle other actors in the level. All implement the same interface but handle Interact differently.
Visual Feedback: UI prompts show what can be interacted with and how. Object highlights indicate the current target. Sound and visual effects confirm successful interaction.
Interaction System Quick Reference
| Component | Implementation | Purpose |
|---|---|---|
| Detection | Line Trace By Channel | Find what player looks at |
| Identification | Does Implement Interface | Check if interactable |
| Feedback | Widget + GetInteractionText | Show prompt to player |
| Execution | Interact (Message) | Trigger the interaction |
Best Practices
- Use interfaces: They decouple the player from interactable classes, making the system flexible and maintainable
- Store current target: Keep a reference to what the player is looking at for use when they press interact
- Provide clear feedback: Always show the player what they can interact with and what will happen
- Use timelines for animation: Smooth movement looks more polished than instant changes
- Make variables editable: Instance Editable variables let designers configure objects in the level
- Consider a base class: For many interactables, a parent class with common functionality reduces duplication
- Add sound: Audio feedback makes interactions feel responsive and satisfying
Figure: The complete interaction flow from detection to execution.
Module 6 Complete!
Congratulations! You've completed Module 6: Player Interaction and Input. You now understand:
- Player Controllers and Pawns: The architecture of player representation
- Enhanced Input System: Modern, flexible input handling with actions, contexts, and modifiers
- Character Movement: The Character Movement Component and how to tune it for different gameplay feels
- Collision and Physics: Collision channels, responses, triggers, and physics simulation
- Interactable Objects: Interface-based interaction systems with visual feedback
These systems form the core of player agency in games. In Module 7, you'll learn about User Interface with UMGβcreating menus, HUDs, and in-game UI to communicate information to players.
Knowledge Check
Question 1
What is the primary purpose of using a Blueprint Interface for interactable objects?
Correct answer: B β Blueprint Interfaces define a contract that any actor can implement. The player character only needs to check "Does this implement BPI_Interactable?" rather than casting to specific classes like BP_Door, BP_Pickup, etc. This decouples the interaction system from specific implementations.
Question 2
What does a Line Trace By Channel return when it hits an object?
Correct answer: B β Line Trace By Channel returns both a boolean (was something hit?) and a Hit Result struct containing detailed information: the hit actor, hit component, impact point, impact normal, physical material, bone name (for skeletal meshes), and more.
Question 3
Why should you use "Interact (Message)" instead of calling the interface function directly?
Correct answer: C β Interface Messages (shown with an envelope icon) safely call interface functions on any actor. If the target doesn't implement the interface, the message simply does nothing instead of causing an error. Direct interface calls require you to cast first and handle the failure case manually.
Question 4
What is the recommended way to animate a door opening smoothly?
Correct answer: C β Timelines provide smooth, controlled animation with easy-to-edit curves. They output an alpha value (0-1) that you use with Lerp to interpolate between closed and open states. Timelines can also be played forward or reversed, making toggle behavior simple.
Question 5
Which component of an interaction system is responsible for showing "Press E to Open" on screen?
Correct answer: C β Feedback is responsible for communicating to the player what they can interact with. This includes UI prompts (text showing the action), object highlights (visual indication of the target), and interaction confirmations (sounds, effects when interacting).