unfurl

Technical Documentation

NsInteraction

Architecture

Modules

Module Type Loading phase Content
NsInteraction Runtime Default The interface, the option types, the interaction component, the view sensor, and the interactable actor

The .uplugin file lists no plugin dependencies.

Folders

Main Classes

Type Responsibility
INsInteractable The interface of a usable actor. GetInteractionOption, ExecuteInteraction, OnInteractorEnter, OnInteractorExit. All are BlueprintNativeEvent. The defaults return false or do nothing.
ANsInteractableActor An actor that implements INsInteractable with one Option from the Details panel. Fires ReceiveInteract (“On Interact”) and OnInteracted.
UNsInteractionComponent Holds the targets, picks the best option, runs the press and the hold, and sends server requests.
UNsInteractionViewSensor Traces along a view source, runs the aim assist, and gives one target to the interaction component.
FNsInteractionTarget An Actor and an optional Part (UPrimitiveComponent). GetLocation() returns the bounds origin of the part, or the actor location.
FNsInteractionOption The target, ActionId, TapActionId, Title, Prompt, bEnabled, Input, HoldSeconds, Authority, PromptLocation, and Priority. ShowsSame compares the fields that the prompt shows.
ENsInteractionInput Press, Hold.
ENsInteractionAuthority Local, Server.
FNsInteractionModule The module class. It has no startup code.

Data Flow

Targets and options:

  1. A sensor calls SetTargets, AddTarget, or RemoveTarget. AddTarget and RemoveTarget build a new list and call SetTargets.
  2. SetTargets drops invalid targets, the owner, and repeats. It calls OnInteractorExit on each actor that lost its last target, and OnInteractorEnter on each new actor. Then it calls UpdateTickState and Refresh.
  3. Refresh skips targets out of reach (MaxDistanceCm). It calls QueryOption for each other target, scores each option with ScoreOption, and keeps the best. A tie keeps the first target.
  4. QueryOption sets OutOption.Target, calls GetInteractionOption, and restores the actor. It keeps the part of the target when the interactable names no part. It sets PromptLocation to the target location when it is zero.
  5. When ShowsSame reports a change, Refresh cancels a hold on another target and fires OnOptionChanged.

Input:

  1. BeginInteract calls Refresh. A Press option runs at once. A Hold option stores HoldOption and the world time, and turns on the tick.
  2. The tick runs the hold action when GetHoldProgress() reaches 1.
  3. EndInteract before that cancels the hold and runs TapActionId, when it is set.
  4. RunAction does nothing for a disabled option. For a Server option on a machine without authority, it fires OnServerRequest, then calls ServerRequestAction when bSendServerRequests is true. Else it calls ExecuteInteraction.
  5. ServerRequestAction (Server, Reliable) calls ExecuteOnServer. ExecuteOnServer checks the reach, builds the option again with QueryOption, and checks bEnabled and that the action is ActionId or TapActionId. Then it calls ExecuteInteraction.

View sensor, each tick where IsControlledHere() is true (a pawn that this machine controls, or an owner that is not a pawn):

  1. RefreshFocus traces from ViewSource along its forward vector, TraceDistanceCm long, on TraceChannel. It ignores the owner.
  2. The hit part takes the focus when QueryOption gives an option for it.
  3. Else, when AssistAngleDeg is above 0, FindAssistTargets runs a sphere overlap of radius TraceDistanceCm. It keeps blocking parts of actors that implement INsInteractable.
  4. MeasureViewAngle finds the point of the local bounds box nearest to the view line with a ternary search of 24 steps. A sight trace drops the part when another actor is more than 10 cm in front of the point.
  5. The parts sort by angle. The part of the last focus gets AssistStickDeg off its angle. The first part with an option takes the focus.
  6. The sensor calls SetTargets with the focus, or ClearTargets.

IsPartInView uses the same trace and the same angle rule, with AssistAngleDeg + AssistStickDeg + ExtraAngleDeg as the limit. It is for a server check of a client request.

Lifetime

Extension Points

Dependencies

Dependency Kind Why
Core, CoreUObject, Engine Public module Actors, components, collision queries, the camera component, and RPCs

The .uplugin file lists no plugins.

Performance

Networking


Contact