Input Sniffer, Overlays, and Tiles¶
Overview¶
ControllerHawk has at its foundation an EngineSubsystem called UInputSnifferSubsystem
. It listens for key and mouse events as well as creates representations for devices attached to the current machine. Included in the plugin are a set of widgets (UI_ControllerTile and EUW_ControllerDebugger) which listen to sniffed events and attached devices to show live controller debug information.

The InputSniffer forwards events and creates representations of controllers that are used for visualizing user inputs.¶
As devices (i.e. specific controller hardware) are discovered they are captured as a USniffedInputDevice
. These are then mapped to Controller Tiles and allow live updates based on key and analog events and the specific controller product information.

The Controller Tile can switch specific representations based on the configured device or live inputs.¶
The Controller Tile (UControllerTileWidget
) consists of several overlays (UControllerOverlayWidget
) mapped to specific controller models or controller archetypes.

The Controller Debugger with an XBox and PS5 controller attached to the current machine.¶
To view which controllers are connected, run EUW_ControllerDebugger to see which controllers are connected and see live inputs.
Input Scopes¶
The InputSniffer uses InputScopes to try and gain additional information about connected devices and as it routes inputs.

The XInput flow uses Unreal’s XInput driver and we capture information using what is provided by that implementation.¶
For XInput, we use the FInputDeviceScope to capture information about the device as well as call an XInput function to retrieve product-specific information about the connected device.

The HID flow uses a controller driver setup specific to ControllerHawk to capture more information about the underlying controller.¶
For ControllerHawk’s HID driver, we provide an additional scope FGameControllerScope
which provides direct access to the interface (HID) and the specific controller implementation (IGameControllerInterface
).
These scopes help us identify which devices particular input belongs to and lets us route this correctly to the Controller Tile assigned for that device. This information is captured in the FScopedInputDeviceHandle
structure and reflected in the USniffedInputDevice
, which passed to the Overlay and Tile.
Overlays¶
Each specific kind of controller is captured as an Overlay (UControllerOverlayWidget
). Here is an example looking through the XInput (Xbox controller) overlay.

An XInput (Xbox controller) overlay¶
The overlay is a sandwich of a base Material followed by a series of textures arranged on a canvas.
The material is responsible for handling the highlight odd-shaped and variable buttons like the shoulder and triggers. Those button states are encoded and then sent to the material.
The textures are mostly just Kenney icons overlapped on each other / swapped out dynamically as the user presses inputs.

Structure of the XInput overlay¶
Overlays are mostly just data and widgets connected together that automatically respond to inputs. The Control Change Descriptions field is used to describe what happens to bound widgets as the user presses inputs. We bind the widget to an input event, and then the Control Change Description modifies the widget automatically.

Example of a widget being bound to a control change description¶
Tiles¶
Tiles are used to manage the display of a specific controller. As mentioned above, UI_ControllerTile collects the available overlays into a switched display. It can be told to display a specific controller archetype using PresentControllerType() and show only inputs from a specific device by calling AssignDeviceHandle(). If no device handle is assigned then the tile forwards all events to the current overlay.

If you want a Controller Tile that automatically switches to the active device, use UI_DynamicControllerTile. As you enter inputs, it will automatically switch to an available overlay.
