Specialized components
Input and interaction system
Button and axis state
13 min
overview the button and axis state system provides a standardized representation of input states across different device types this abstraction layer allows the engine to process inputs consistently regardless of their physical source, enabling developers to create device agnostic interaction systems standardized input representation a key challenge in input handling is the diversity of input methods the same logical action (e g , "interact") might be triggered by pressing the 'e' key on a keyboard clicking the left mouse button pressing the 'a' button on a gamepad pulling the trigger on an xr controller the ir engine addresses this challenge by implementing a common data structure for all input types, allowing different parts of the system to work with inputs without needing to know their physical origin buttonstate structure for each button the system tracks, it maintains a buttonstate object containing comprehensive information about the button's current condition property description usage pressed whether the button is currently held down true for every frame the button is held down whether the button was just pressed this frame true only for the first frame of a press up whether the button was just released this frame true only for the frame when released value analog value for pressure sensitive buttons range from 0 0 (not pressed) to 1 0 (fully pressed) touched whether the button is being touched but not pressed used primarily with capacitive xr controller buttons dragging whether the input device is moving while the button is pressed used for drag operations code example // simplified representation of buttonstate // (found in state/buttonstate ts) type buttonstate = { down boolean; // true only the frame it's first pressed pressed boolean; // true as long as it's held up boolean; // true only the frame it's released value number; // for analog inputs (e g , triggers 0 0 to 1 0) touched boolean; // is the button being touched (capacitive)? dragging boolean;// is the pointer moving while pressed? // additional properties omitted for brevity }; input enumeration to provide a consistent way to reference specific buttons and axes, the system defines several enumeration types button enumerations mousebutton standard mouse buttons enum mousebutton { 'primaryclick' = 'primaryclick', // usually left mouse button 'auxiliaryclick' = 'auxiliaryclick', // usually middle mouse button/wheel 'secondaryclick' = 'secondaryclick' // usually right mouse button } keyboardbutton keyboard keys enum keyboardbutton { 'space' = 'space', 'keyw' = 'keyw', 'keya' = 'keya', 'keys' = 'keys', 'keyd' = 'keyd', 'enter' = 'enter', // many additional keys omitted for brevity } standardgamepadbutton & xrstandardgamepadbutton gamepad and xr controller buttons enum xrstandardgamepadbutton { 'xrstandardgamepadtrigger' = 0, // the main trigger 'xrstandardgamepadsqueeze' = 1, // the grip button // additional buttons omitted for brevity } axis enumerations mousescroll mouse wheel axes standardgamepadaxes standard gamepad analog inputs xrstandardgamepadaxes xr controller analog inputs enum xrstandardgamepadaxes { 'xrstandardgamepadtouchpadx' = 0, // left/right on touchpad/thumbstick 'xrstandardgamepadtouchpady' = 1, // up/down on touchpad/thumbstick // additional axes omitted for brevity } integration with input sources the inputsourcecomponent discussed in the previous chapter stores a collection of buttonstate objects indexed by the appropriate enumeration values this creates a comprehensive representation of the device's current state // conceptual representation of an inputsourcecomponent for a keyboard inputsourcecomponent (for keyboard) \ buttons \ keyboardbutton keyw { down false, pressed true, up false, value 1, } \ keyboardbutton space { down true, pressed true, up false, value 1, } \ keyboardbutton shiftleft { down false, pressed false, up false, value 0, } // additional keys omitted for brevity // conceptual representation of an inputsourcecomponent for an xr controller inputsourcecomponent (for left vr controller) \ buttons \ xrstandardgamepadbutton xrstandardgamepadtrigger { down false, pressed true, up false, value 0 8, touched true, } // additional buttons omitted for brevity \ axes \ xrstandardgamepadaxes xrstandardgamepadthumbstickx 0 5 // pushed left \ xrstandardgamepadaxes xrstandardgamepadthumbsticky 0 0 // centered // additional axes omitted for brevity processing pipeline the transformation from hardware events to standardized button states follows this process hardware event physical input occurs (e g , key press) operating system notification os sends event to the application event translation clientinputsystem converts raw event to standardized format state update system updates the appropriate buttonstate in the relevant inputsourcecomponent sequencediagram participant hw as hardware (e g , keyboard) participant os as operating system participant cis as ir engine (clientinputsystem) participant isc as inputsourcecomponent participant bs as buttonstate for 'keye' hw >>os user presses 'e' key os >>cis "key 'e' down" event cis >>isc find keyboard inputsource cis >>bs update buttonstate for keyboardbutton keye note over bs pressed true, down true, value 1 buttonstate initialization when a button event first occurs, the system creates a new buttonstate object using the createinitialbuttonstate function // from state/buttonstate ts // (simplified for brevity) export const createinitialbuttonstate = ( inputsourceentity entity, initial partial\<buttonstate> = { pressed true, value 1 } ) => { return { down initial down ?? initial pressed ?? false, pressed initial pressed ?? true, // additional properties omitted for brevity inputsourceentity, } as buttonstate; }; benefits of standardized input representation this standardized approach to input state representation provides several advantages consistency all input types are represented in the same format abstraction higher level systems can work with logical actions rather than specific physical inputs flexibility support for new input device types can be added without changing the core interaction system readability enumerated values provide clear, self documenting code next steps with an understanding of how input states are standardized across different device types, the next chapter explores how game entities can listen for and respond to these inputs through the input receiver system next input receiver docid\ e2hautpdl1izfvly6jmsh