Design a general interaction system for a multiplayer Unreal Engine game with many kinds of interactable objects — doors, pickups, levers, triggers — and more types added over the project's life. The player should be able to focus the object they are looking at, see a context prompt for it, and act on it. New interactable types must be addable without editing the player's interaction code (no growing per-type branch the player has to know about). The session is networked, so the actual effect of an interaction (a door opening, an item being consumed) must be authoritative on the server and not decided by the client, while the focus detection and prompt can be local to the acting player. Describe how the player discovers and talks to interactables generically, how an interaction is requested and executed, where authority lives, and the trade-offs of your approach.
Define a common IInteractable interface with an Interact(Instigator) method; doors and pickups implement it. The player runs a trace to find the focused interactable, calls a Server RPC, and the server executes the interaction authoritatively.
- ✗Casting to each concrete class instead of using a shared interface
- ✗Executing interactions on the client and only replicating the result
- ✗Polling distance every Tick instead of tracing on input
- →How would you show an interaction prompt only for the locally focused object?
- →How would you handle an interaction that takes time, like a hold-to-open door?
Key classes
IInteractable— aUINTERFACEwithInteract(AActor* Instigator),CanInteract,GetInteractText.ADoor,APickup,ATriggerVolume— concreteActors implementing the interface.UInteractionComponent— aUActorComponenton the player: traces for a focused target, sends a Server RPC.UInteractPromptWidget— a local "Press E" prompt widget.
Data model
The interface decouples the player from objects: the player knows only IInteractable, not concrete classes. A door stores bIsOpen; a pickup references a UItemDataAsset; a trigger stores a target reference or an event tag.
Data flow
UInteractionComponenttraces forward each frame (or on a timer) and finds the nearestIInteractable.- A prompt is shown locally via
GetInteractText— only on the owning client. - On press → Server RPC
ServerInteract(Target). - The server checks
CanInteract(distance, state) and callsInteract. - The result (door
bIsOpen, pickup removal) replicates to everyone.
Replication
Object state (door open, item picked up) is Replicated with an OnRep for animation and sound. The interaction itself is initiated by a Server RPC. The prompt and trace are purely local and not replicated. Triggers are usually Server-only in logic, with the effect multicast.
Designer-facing config
Door, pickup, and trigger are Blueprint classes inheriting a C++ base and implementing the interface. The designer sets door speed, trigger event type, and item reference in the actor's details. New interactable types are added as new interface implementations.
Trade-offs
- Interface vs. shared base class: an interface is more flexible (an actor can be an interactable and something else), a base class is handier for shared code. Often combined.
- Trace-on-input vs. overlap: a trace is more precise for "looking at an object"; overlap is simpler for zones but less predictable with many objects.