reckfellENGINE

Input events and UI

Choose an input callback, let UI handle events first and stop propagation when consumed.

On this page

Where to handle input

TaskLocation
Continuous movement or analog stick strengthInput in _PhysicsProcess()
Gameplay action after UI_UnhandledInput(InputEvent)
Keyboard events after UI_UnhandledKeyInput(InputEvent)
Custom button or UI regionControl._GuiInput(InputEvent)
Interception before UI_Input(InputEvent); only when necessary

Within a Viewport, an event passes through _Input() and then eligible UI controls. If it remains unhandled, _ShortcutInput(), _UnhandledKeyInput() for keys, and _UnhandledInput() follow. This is a simplified order: embedded windows, nested viewports and physics object picking add stages. Marking an event handled stops its later stages.

An action after UI

Add interact in Project Settings → Input Map and bind E. Attach InteractReceiver.cs to an ordinary entity in the game level:

C#
using Reckfell;

public partial class InteractReceiver : Entity
{
    public int Interactions { get; private set; }

    public override void _UnhandledInput(InputEvent @event)
    {
        if (!@event.IsActionPressed("interact"))
            return;

        Interactions++;
        ReckfellApi.Print("Interaction ", Interactions);
        GetViewport().SetInputAsHandled();
    }
}

Build and run. Pressing E increments the counter once if UI did not consume the event. InputEvent.IsActionPressed() defaults to allowEcho = false, so held-key echoes do not count as new presses. SetInputAsHandled() prevents later recipients from handling this event.

Inside Control._GuiInput(), call AcceptEvent() for a consumed UI event. Mouse input depends on control size, MouseFilter, overlap order and pointer position; keyboard input depends on focus. MouseFilter.Stop automatically stops pointer events at the Control even without explicit AcceptEvent(); scrolling has a separate parent-propagation rule.

Handled events do not block Input polling

Input.IsActionPressed() reads global device state, not a list of unhandled events. A press accepted by a menu can still affect gameplay polling. Disable gameplay controls explicitly or pause their branch.

Input.ActionPress() changes an action's polled state but does not dispatch an event to _Input(). Use Input.ParseInputEvent() for a synthetic event or PushInput() for an isolated Viewport. Synthetic input does not replace testing a real device.

Find the cause

SymptomCheck
One press triggers two actionsThe same logic in _Input() and _UnhandledInput(), two active listeners or duplicate subscriptions. Keep one owner of the gameplay action; do not manually call both handlers.
A key never reaches _UnhandledInput()The interact Input Map binding and the keyboard-focused Control: UI may have consumed the event already. Observe _Input() for diagnosis rather than moving gameplay there to bypass menus.
A button under an image never receives clicksOverlapping Control bounds and order. Set MouseFilter.Ignore on a purely decorative layer; do not apply it indiscriminately to interactive UI.
The character moves through an open menuGameplay polls Input, which ignores event consumption. Explicitly disable gameplay controls or pause their branch when opening the menu.

Keep discrete events distinct from holding: @event.IsActionPressed() suits one action; Input.IsActionPressed() reads held state.

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.