Input Events | Package Manager UI website
docs.unity3d.com
    Show / Hide Table of Contents

    NOTE: Events are an advanced, mostly internal feature of the input system. It is not necessary to understand this feature to use the input system. Knowledge of the event system is mostly useful when wanting to support custom devices or when wanting to modify the behavior of existing devices.

    Input Events

    • Types of Events
      • State Events
      • Device Events
      • Text Events
    • Working With Events
      • Monitoring Events
      • Reading State Events
      • Creating Events
      • Capturing Events

    The input system is event-driven. All input is delivered as events and custom input can be generated by injecting events. Also, by listening in on the events flowing through the system, all source input can be observed.

    Input events are a low-level mechanism. You will usually not need to deal with events yourself when all you want to do is receive input for your game. Events are stored in unmanaged memory buffers and not converted to C# heap objects. Wrapper APIs are provided but for more involved event manipulations, unsafe code is required.

    Note that there is no routing mechanism. Events are delivered from the runtime straight to the input system where they are incorporated directly into device state.

    Input events are represented by the InputEvent struct. Each event has a set of properties common to all events:

    Property Description
    type FourCC code that indicates what type of event it is.
    eventId Unique numeric of the event.
    time Timestamp of when the event was generated.
    deviceId ID of the device that the event is targeted at.
    sizeInBytes Total size of the event in bytes.

    The events received for a specific input device can be observed in the input debugger.

    Types of Events

    State Events

    A state event contains input state for a device. These events are what gets new input into the system.

    There are two types of state events:

    • StateEvent ('STAT')
    • DeltaStateEvent ('DLTA')

    StateEvent contains a full snapshot of the entire state of a device in the format specific to the device. The stateFormat field identifies the type of the data in the event. The raw data can be accessed using the state pointer and is stateSizeInBytes long.

    DeltaStateEvent are like StateEvent, but a DeltaStateEvent will only contain a partial snapshot of the state of a device. This is usually sent by the backend for devices requiring a large state record to reduce the amount of memory which needs to be updated if only some of the controls change their state. The raw data can be accessed using the deltaState pointer and is deltaStateSizeInBytes long. The data should be applied to the device's state at the offset at stateOffset.

    Device Events

    Device events indicate a change that is relevant to a device as a whole. If you are interested in these events, it is usually more convenient to subscribe to the higher-level InputSystem.onDeviceChange event rather then processing InputEvents yourself.

    • DeviceRemoveEvent ('DREM')
    • DeviceConfigurationEvent ('DCFG')

    DeviceRemovedEvent indicates that a device has been removed/disconnected. The device which has been removed can be queried from the common deviceId field. This event does not have any additional data.

    DeviceConfigurationEvent indicates that the configuration of a device has changed. The meaning of this is device-specific. This may signal, for example, that the layout used by the keyboard has changed or that, on a console, a gamepad has changed which player ID(s) it is assigned to. The device which has been changed can be queried from the common deviceId field. This event does not have any additional data.

    Text Events

    These events are sent by Keyboard devices to handle text input. If you are interested in these events, it is usually more convenient to subscribe to the higher-level callbacks on the Keyboard class rather then processing InputEvents yourself.

    • TextEvent ('TEXT')
    • IMECompositionEvent ('IMES')

    Working With Events

    Monitoring Events

    If you want to do any monitoring or processing on incoming events yourself, subscribe to the InputSystem.onEvent callback.

    Reading State Events

    State events contain raw memory snapshots for devices. As such, interpreting the data in the event requires knowledge about where and how individual state is stored for a given device.

    The easiest way to access state contained in a state event is to rely on the device the state is meant for. Any control can be asked to read its value from a given event rather than from its own internally stored state.

    For example, the following code demonstrates how to read a value for Gamepad.leftStick from a state event targeted at a Gamepad.

    InputSystem.onEvent +=
        (eventPtr, device) =>
        {
            // Ignore anything that isn't a state event.
            if (!eventPtr.IsA<StateEvent>() && !eventPtr.IsA<DeltaStateEvent>())
                return;
    
            var gamepad = device as Gamepad;
            if (gamepad == null)
            {
                // Event isn't for a gamepad or device ID is no longer valid.
                return;
            }
    
            var leftStickValue = gamepad.leftStick.ReadValueFromEvent(eventPtr);
        };
    

    Creating Events

    New input events can be created and queued by anyone and against any existing device. Queueing an input event is thread-safe meaning that event generation can happen in background threads.

    NOTE: Memory allocated to events coming from background threads is limited. If too many events are produced by background threads, queueing an event from a thread will block the thread until the main thread has flushed out the background event queue.

    Note that queuing an event will not immediately consume the event. Processing of events happens on the next update (depending InputSettings.updateMode, either manually triggered via InputSystem.Update or triggered automatically as part of the player loop).

    Sending State Events

    The easiest way to create a state event is directly from the device.

    // `StateEvent.From` creates a temporary buffer in unmanaged memory holding
    // a state event large enough for the given device and containing a memory
    // copy of the device's current state.
    InputEventPtr eventPtr;
    using (StateEvent.From(myDevice, out eventPtr))
    {
        ((AxisControl) myDevice["myControl"]).WriteValueIntoEvent(0.5f, eventPtr);
        InputSystem.QueueEvent(eventPtr);
    }
    

    Another way for sending state is to send events for individual controls.

    // Send event to update leftStick on the gamepad.
    InputSystem.QueueDeltaStateEvent(Gamepad.current.leftStick,
        new Vector2(0.123f, 0.234f);
    

    Note that delta state events only work for controls that are both byte-aligned and a multiple of 8 bits in size in memory. It is not supported to, for example, send a delta state event for a button control that is stored as a single bit.

    Capturing Events

    You can use the InputEventTrace class to record input events for later processing:

    
        var trace = new InputEventTrace(); // Can also give device ID to only
                                           // trace events for a specific device.
    
        trace.Enable();
    
        //... run stuff
    
        var current = new InputEventPtr();
        while (trace.GetNextEvent(ref current))
        {
            Debug.Log("Got some event: " + current);
        }
    
        // Also supports IEnumerable.
        foreach (var eventPtr in trace)
            Debug.Log("Got some event: " + eventPtr);
    
        // Trace consumes unmanaged resources. Make sure to dispose.
        trace.Dispose();
    
    Back to top
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023