OmniInteraction

A flexible, Blueprint-friendly interaction system. Detect nearby objects, select between them, and interact instantly or by holding, with UI events built in

Overview

OmniInteraction gives any actor the ability to find and use interactable objects around it. Add one component to your character, implement one interface on your objects, and you get detection, line-of-sight checks, a selectable list, hold-to-interact, and UI events.

Radius detectionSpherical scan around the owner with a configurable radius.
Line-of-sightObjects hidden behind walls are ignored automatically.
Multi-item selectionScroll through several nearby items with IndexUp / IndexDown, with optional wrap-around.
Instant or holdEach object decides its own interaction duration. Progress is exposed for UI bars.
UI-ready eventsEnter, remove, selection, and live text-update delegates for widgets.
Built-in debugDraw the radius and print the full interaction state on screen.

Quick Start

  1. Enable the plugin
    Edit → Plugins, enable OmniInteraction, restart the editor.
  2. Add the component
    Open your Character (or any actor) Blueprint and add Interaction System.
  3. Implement the interface
    In the object you want to interact with: Class Settings → Interfaces → add Interactable.
  4. Fill in the functions
    Override Interact, Get Interact Text, Get Interact Icon, Get Interaction Duration and Should Remove On Interact.
  5. Hook up input
    Call Interact(Get Current Index) on press, Stop Interact on release, and Index Up / Down on scroll.
  6. Play
    Walk near the object. It is detected and highlighted automatically.
Collision requirement: interactable actors must have a collision component that overlaps or blocks the Visibility channel, otherwise the scan will not find them.

Interactable Interface

Implement IInteractable on any actor. All functions are Blueprint Native Events, so you can implement them in Blueprint or override _Implementation in C++.


C++ example

class AMyPickup : public AActor, public IInteractable
{
    GENERATED_BODY()
public:
    virtual void Interact_Implementation(AActor* Interactor) override;
    virtual FString GetInteractText_Implementation() override { return TEXT("Pick up"); }
    virtual float GetInteractionDuration_Implementation() override { return 0.0f; }
    virtual bool ShouldRemoveOnInteract_Implementation() override { return true; }
};

Component Reference

Class: UInteractionSystem (Actor Component). Add it to the actor that does the interacting.

Properties

PropertyDefaultDescription
InteractionRadius90.0Detection radius in Unreal units. Read/write in Blueprint.
bWrapSelectionfalseSelection loops from last to first (and back) when scrolling.
bShowDebugRadiusfalseDraws the detection sphere. Green when idle, red while holding.
bShowDebugStatefalsePrints selected index, item list and hold progress on screen.

Functions

FunctionTypeDescription
Interact(Index)CallableInteracts with the item at Index. Instant items fire at once; hold items start the hold timer.
StopInteractCallableCancels the current hold and resets progress. Call on input release.
IndexUp / IndexDownCallableMoves selection and fires highlight start/end.
InteractAll(bOnlyInstant)CallableInteracts with every nearby item. Defaults to instant items only.
ClearAllInteractablesCallableClears the list and cancels any hold.
RegisterWidgetReference(Widget)CallableLinks a created widget to the next item slot so it can be removed correctly later.
GetHoldProgressPure0 to 1. Bind to a progress bar.
GetCurrentIndexPureCurrently selected index.
GetSelectedActorPureThe selected actor, or null.
IsHoldInteractionAtIndex(Index)PureTrue if the item needs a hold.
GetUpdatedTextAtIndex(Index)PureCurrent interact text for an item.
GetDistanceToInteractable(Index)PureDistance from owner to item.

Events

Bind these in Blueprint (Assign nodes) or in C++ with AddDynamic.

EventParametersFires when
OnItemEnteredItemName, ItemIconA new interactable enters range and is visible.
OnItemRemovedWidgetRef, IndexAn item leaves range or is consumed. Use it to destroy the widget.
OnSelectionChangedNewSelectedIndexThe selected index changes.
OnUpdateInteractionTextIndex, NewTextEvery frame for each item, so dynamic text stays in sync.

UI Setup (Blueprint)

  1. Bind OnItemEntered. Create your entry widget (name + icon), add it to a Vertical Box.
  2. Immediately call RegisterWidgetReference with that widget. Do this right after creating it, one widget per entered item.
  3. Bind OnItemRemoved. Call Remove From Parent on WidgetRef.
  4. Bind OnSelectionChanged to highlight the entry at NewSelectedIndex.
  5. Bind OnUpdateInteractionText to refresh the label at Index.
  6. For hold actions, drive a progress bar from GetHoldProgress.

Tips & Best Practices

Keep the radius smallThe scan runs every frame. Small radii are cheaper and feel more precise.
Use the debug togglesEnable bShowDebugState to see exactly what the system is tracking.
Dynamic textReturn state-aware strings, like "Open Door" or "Close Door", from GetInteractText.
Highlight safelyDo highlight work only in OnHighlightStart/End so selection stays consistent.

FAQ

My object is not detected.

Can I use this on AI or non-player actors?

How do I make hold-to-interact?

Does it work with Enhanced Input?


Copyright KhalidBen 2026. All rights reserved.