OmniInteraction

一个灵活、对蓝图友好的交互系统。可检测附近的物体,在它们之间切换选择,并支持即时交互或长按交互,内置 UI 事件。


概览

OmniInteraction 让任意 Actor 都能发现并使用周围的可交互对象。只需为你的角色添加一个组件,并在你的对象上实现一个接口,即可获得检测、视线检查、可选择列表、长按交互和 UI 事件。

半径检测以所有者为中心进行球形扫描,半径可配置。
视线检查自动忽略被墙壁遮挡的对象。
多对象选择使用 IndexUp / IndexDown 在附近的多个对象间切换,可选循环选择。
即时或长按每个对象自行决定交互时长。进度可供 UI 进度条使用。
面向 UI 的事件提供进入、移除、选择以及实时文本更新的委托,供控件使用。
内置调试可绘制半径,并在屏幕上打印完整的交互状态。

快速入门

  1. 启用插件
    Edit → Plugins,启用 OmniInteraction,然后重启编辑器。
  2. 添加组件
    打开你的角色(Character,或任意 Actor)蓝图,并添加 Interaction System。
  3. 实现接口
    在你想要交互的对象中:Class Settings → Interfaces → 添加 Interactable。
  4. 填写函数
    重写 Interact、Get Interact Text、Get Interact Icon、Get Interaction Duration 和 Should Remove On Interact。
  5. 连接输入
    按下时调用 Interact(Get Current Index),松开时调用 Stop Interact,滚动时调用 Index Up / Down。
  6. 运行
    走近该对象,它会被自动检测并高亮显示。
碰撞要求:可交互的 Actor 必须带有碰撞组件,该组件需与 Visibility 通道重叠或阻挡,否则扫描将无法发现它们。

Interactable 接口

在任意 Actor 上实现 IInteractable。所有函数都是 Blueprint Native Event,因此你可以在蓝图中实现,或在 C++ 中重写 _Implementation。

函数返回值用途
Interact(Interactor)void交互成功时调用。Interactor 是该组件的所有者。
GetInteractTextString在 UI 中显示的标签,例如“拾取长剑”。每帧都会被轮询,因此可以是动态的。
GetInteractIconTexture2DUI 条目的可选图标。
GetInteractionDurationfloat0 = 即时。大于 0 = 玩家必须按住的秒数。
ShouldRemoveOnInteractbool为 true 时,交互成功后该对象会从列表中移除(拾取物、消耗品)。
OnHighlightStartvoid当该对象成为选中项时调用。可用于描边或发光效果。
OnHighlightEndvoid当它被取消选中或离开范围时调用。

C++ 示例

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; }
};

组件参考

类:UInteractionSystem(Actor 组件)。请将其添加到执行交互的 Actor 上。

属性

属性默认值说明
InteractionRadius90.0检测半径,单位为 Unreal 单位。可在蓝图中读写。
bWrapSelectionfalse滚动时,选择会从最后一项循环到第一项(反之亦然)。
bShowDebugRadiusfalse绘制检测球体。空闲时为绿色,长按时为红色。
bShowDebugStatefalse在屏幕上打印当前选中索引、对象列表和长按进度。

函数

函数类型说明
Interact(Index)Callable与 Index 处的对象交互。即时交互对象立即触发;长按交互对象则启动按住计时器。
StopInteractCallable取消当前的长按并重置进度。请在输入松开时调用。
IndexUp / IndexDownCallable移动选择,并触发高亮开始/结束。
InteractAll(bOnlyInstant)Callable与附近的每个对象交互。默认仅处理即时交互对象。
ClearAllInteractablesCallable清空列表并取消任何长按。
RegisterWidgetReference(Widget)Callable将已创建的控件关联到下一个对象槽位,以便之后能正确移除。
GetHoldProgressPure0 到 1。可绑定到进度条。
GetCurrentIndexPure当前选中的索引。
GetSelectedActorPure选中的 Actor,或 null。
IsHoldInteractionAtIndex(Index)Pure如果该对象需要长按,则为 true。
GetUpdatedTextAtIndex(Index)Pure某个对象当前的交互文本。
GetDistanceToInteractable(Index)Pure从所有者到该对象的距离。

事件

在蓝图中(使用 Assign 节点)或在 C++ 中使用 AddDynamic 进行绑定。

事件参数触发时机
OnItemEnteredItemName, ItemIcon新的可交互对象进入范围且可见时。
OnItemRemovedWidgetRef, Index对象离开范围或被消耗时。可用它来销毁控件。
OnSelectionChangedNewSelectedIndex选中的索引发生变化时。
OnUpdateInteractionTextIndex, NewText每帧为每个对象触发,以保持动态文本同步。

UI 设置(蓝图)

  1. 绑定 OnItemEntered。创建你的条目控件(名称 + 图标),并将其添加到 Vertical Box 中。
  2. 立即调用 RegisterWidgetReference 并传入该控件。请在创建控件后立即执行,每个进入范围的对象对应一个控件。
  3. 绑定 OnItemRemoved。对 WidgetRef 调用 Remove From Parent。
  4. 绑定 OnSelectionChanged 以高亮 NewSelectedIndex 处的条目。
  5. 绑定 OnUpdateInteractionText 以刷新 Index 处的标签。
  6. 对于长按操作,请用 GetHoldProgress 驱动进度条。

技巧与最佳实践

保持半径较小扫描每帧都会运行。较小的半径开销更低,手感也更精确。
使用调试开关启用 bShowDebugState 即可准确看到系统正在追踪的内容。
动态文本从 GetInteractText 返回与状态相关的字符串,例如“打开门”或“关闭门”。
安全地高亮仅在 OnHighlightStart/End 中处理高亮逻辑,以保证选择状态一致。

常见问题

我的对象没有被检测到。

可以用于 AI 或非玩家 Actor 吗?

如何实现长按交互?

它支持 Enhanced Input 吗?


Copyright KhalidBen 2026. All rights reserved.