ContinuousInteraction

Custom Unity Input System interaction that fires Performed every frame while the control is actuated. Unlike the default interaction which performs once per press, this enables per-frame input reading — ideal for continuous actions like camera movement, aiming, or analog stick input.

Definition

Namespace: Paragon.Core.InputSystem Assembly: Paragon.dll

[InitializeOnLoad]
[RuntimeInitializeOnLoad]
public class ContinuousInteraction : IInputInteraction

Implements: IInputInteraction (UnityEngine.InputSystem)

Remarks

ContinuousInteraction solves a common problem with Unity's Input System: by default, input actions only fire Performed once when the interaction completes (e.g., button press). For continuous input (mouse movement, joystick axes, held buttons), game code needs to read values every frame.

How It Works

  1. Process() is called by the Input System when the action's control changes. If the control is actuated and not yet in Performed/Started phase, it calls OnPerformBegin() to start the continuous loop.

  2. OnPerformBegin() subscribes to InputSystem.onAfterUpdate, which fires every frame after input processing. This is the key mechanism — the Update() method runs each frame.

  3. Update() calls context.PerformedAndStayPerformed() every frame, which keeps the action in Performed phase and fires the performed callback to subscribers. This continues until the control is released.

  4. When the control is released, Cancel() calls context.Performed() (final perform) then context.Canceled(), and OnPerformEnd() unsubscribes from all events.

Safety Subscriptions

The interaction also subscribes to device/layout change events and (in the Editor) play mode state changes. These all trigger Reset(), which ensures the interaction cleans up if the input system state changes unexpectedly — for example, when a device is disconnected or the user exits play mode.

Quick Lookup

Goal
How

Apply to an action

Set the interaction to ContinuousInteraction in the Input Action Asset

Read value every frame

Subscribe to action.performed — it fires every frame while held

Registration

Automatic via [InitializeOnLoad] and [RuntimeInitializeOnLoad]

Methods

Process

Called by the Input System when the bound control changes state. Routes to either Cancel() (control released) or OnPerformBegin() (control actuated).

Parameter
Type
Description

context

ref InputInteractionContext

The interaction context from the Input System

Behavior:

  • If control is not actuated: calls Cancel() to end the interaction

  • If control is actuated and phase is not Performed/Started: calls OnPerformBegin() to start the per-frame loop

Reset

Called by the Input System when the interaction needs to be reset. Unsubscribes from all frame events via OnPerformEnd().

Update (private)

Called every frame via InputSystem.onAfterUpdate. Checks if the interaction should continue and calls PerformedAndStayPerformed() to fire the performed callback.

Behavior:

  • If phase is Canceled, Disabled, action map is disabled, or control is not actuated: calls Cancel()

  • If phase is Performed, Started, or Waiting: calls context.PerformedAndStayPerformed()

Cancel (private)

Ends the continuous interaction. Calls OnPerformEnd(), then fires a final Performed() followed by Canceled() if the phase was active.

OnPerformBegin (private)

Subscribes to per-frame and safety events to start the continuous loop.

Subscribes to:

  • InputSystem.onAfterUpdate — per-frame Update() calls

  • InputSystem.onLayoutChange — layout change safety reset

  • InputSystem.onDeviceChange — device change safety reset

  • EditorApplication.playModeStateChanged — editor play mode safety reset (editor only)

OnPerformEnd (private)

Unsubscribes from all events registered by OnPerformBegin().

Common Pitfalls

circle-exclamation
circle-exclamation
circle-exclamation

Examples

Using in an Input Action Asset

In the Unity Input Action Asset editor:

  1. Select an action (e.g., "Look", "Move")

  2. Add an interaction → select ContinuousInteraction

  3. The performed callback will now fire every frame while the control is actuated

Reading Continuous Input

See Also

Last updated