Skip to main content

Input

This section provides guidance for setting up inputs. The inputs that are currently supported are touch, keyboard, mouse, and gamepad.

Input Manager

In Studio, there are Inputs and Actions - the Input Manager sets up the mapping in between them. An action is an abstraction over the source of input(s) it receives. They are most useful for representing input as "logical" concepts (e.g. "jump") rather than as "physical" inputs (e.g. "space bar on keyboard pressed").

Manage Action Maps

You can manage Action Maps via the Input Manager in the Space Settings (the default state of the Inspector when no entity is selected).

Input Manager Button

Adding a Action

Actions are an abstraction layer to user inputs. To add a Action to the Action Map, click the (+) New Action button then type in the name for your Action.

Input Manager Add Action

Adding a Binding to a Action

Bindings are how inputs can be associated with an action. To add a binding click the Add Binding button and select the input you want to bind to the action in the dropdown. There are Bindings for many types of inputs including keyboard, mouse and gamepad. Multiple input bindings can be mapped to a single action. To delete a binding, click the trash bin next to the binding you want to delete.

Input Manager Add Binding

Adding a Binding with a Modifier

Modifiers are an additional input you can assign to a binding in order activate the action. To create a Binding with an modifier, click the With Modifier button. The modifier is selected with the first dropdown and the binding is selected with the second dropdown.

Input Manager Add Modifier

Creating a New Action Map

Action Map are sets of actions that can be swapped programmatically. To create a new action map click on the action map dropdown then click on Create New Action Map. Then type in the name of the action map and save it. Action Maps can be renamed, duplicated, and deleted. The default action map can only be duplicated.

The currently selected Action Map is the Action Map that will be active by default.

Input Manger Create New Action Map

Touch Events

See Events for how to listen on events.

Notes:

  • Multiple screen touches can be active at the same time.
  • Only one multitouch/single touch gesture will be active at a time.

Screen Touch

The following events are emitted for single touch actions:

ecs.input.SCREEN_TOUCH_START // Emits when the user initially touches the screen.
ecs.input.SCREEN_TOUCH_MOVE // Emits when the user moves their finger on the screen.
ecs.input.SCREEN_TOUCH_END // Emits when the user lift the finger off the screen.

Screen Touch Event Properties

Property NameTypeNotes
pointerIdnumberA unique ID for the pointer provided by the browser
position{x: number, y: number}The screen position in pixels
targetEid (BigInt)If initial touch raycasts to an object, this will be the eid of the object, and as the pointer moves, the target will be the same as the initial target.
start{x: number, y: number}On move/end, this will be the first position emitted in start
change{x: number, y: number}On move, the delta of movement since the last event

Note: If the screen touch has a target, events will be emitted on that target and bubble up their parents to the global level, meaning a touch listener on a parent object will receive touch events for all of their children.

Gesture

Gesture events are emitted when the user makes a "gesture" on the phone screen. A gesture is any action that requires multiple fingers. If the user starts with a "'zoom" action (2 fingers moving away from each other) then adds another finger to the screen then the "zoom" gesture will end and a new one will start with 3 fingers.

The following events are emitted for multi-touch actions:

ecs.input.GESTURE_START // Emits when the user touches the screen with multiple fingers. 
ecs.input.GESTURE_MOVE // Emits when the user moves their finger(s) on the screen.
ecs.input.GESTURE_END // Emits when the number of fingers change from an previous gesture check.

Gesture Event Properties

Property NameTypeNotes
touchCountnumberThe number of points contributing to the touch, for example a pinch gesture on mobile will be touchCount: 2
position{x: number, y: number}The screen position in pixels.
startPosition{x: number, y: number}On move/end, this will be the first position emitted in start.
positionChange{x: number, y: number}On move, the delta of movement since the last event.
spreadnumberThe average distance between pointers from the center point, a metric of how pinched or spread the touches are.
startSpreadnumberOn move, the first spread emitted in start.
spreadChangenumberOn move, the delta of spread since the last event.
nextTouchCountnumberOn end, the number of pointers involved in the following gesture. For example if the gesture is changing from 2 to 3 fingers, the two finger gesture will be ended with nextTouchCount: 3

Input API

Actions

FunctionDescriptionExample
setActiveMap = (name: string) => voidSets the active action map. The default action map's name is defaultworld.input.setActiveMap('menu')
getActiveMap = () => voidFetches the active action map.world.input.getActiveMap()
getAction = (action: string) => numberReturns > 0 if the action was triggered. Value is usually from 0 to 1. The exception is mouse velocity and scroll which is uncapped.world.input.getAction('jump')

Keyboard Input

FunctionDescriptionExample
getKey = (code: string) => booleanReturns true while the user holds down the key identified by name.world.input.getKey('KeyQ')
getKeyDown = (code: string) => booleanReturns true during the frame the user starts pressing down the key identified by name.world.input.getKeyDown('KeyQ')
getKeyUp = (code: string) => booleanReturns true during the frame the user releases the key identified by name.world.input.getKeyUp('KeyQ')

Gamepad Input

FunctionDescriptionExample
getButton = (input: number, gamepadIdx?: number) => booleanTakes a Returns true while the virtual button identified by buttonName is held down.world.input.getButton(1)
getButtonDown = (input: number, gamepadIdx?: number) => booleanReturns true during the frame the user pressed down the button mapped to the index https://www.w3.org/TR/gamepad/#remappingworld.input.getButtonDown(1)
getButtonUp = (input: number, gamepadIdx?: number) => booleanReturns true the first frame the user releases the button.world.input.getButtonUp(1)
getAxis = (gamepadIdx?: number) => number4[]Returns the value of the axis of the gamepadIdx.world.input.getAxis()
getGamepads = () => Gamepad[]Returns all gamepads connected to the device.world.input.getGamepads()

Gamepad Events

ecs.input.GAMEPAD_CONNECTED // Emits when a gamepad is connected to the device.
ecs.input.GAMEPAD_DISCONNECTED // Emits when a gamepad is disconnected from the device.

Gamepad Event Properties

Property NameTypeNotes
gamepadGamepadThe gamepad that was connected/disconnected.

Mouse Input

Mouse Button Keys

This is the table of number to mouse buttons that is used in the mouse input api to fetch the state of mouse buttons.

NumberMouse Button
0Primary
1Auxillary
2Secondary
3Fourth
4Fifth
FunctionDescriptionExample
getMouseButton = (button: number) => booleanReturns true while the user holds down the mouse button identified by button number.world.input.getMouseButton(0)
getMouseDown = (button: number) => booleanReturns true during the frame the user starts pressing down on the mouse button.world.input.getMouseDown(0)
getMouseUp = (button: number) => booleanReturns true during the frame the user releases the mouse button.world.input.getMouseUp(0)
getMousePosition = () => [number, number]Returns the x and y position of the mouse in the screen.world.input.getPosition()
getMouseVelocity = () => [number, number]Returns the x and y velocity of the mouseworld.input.getMouseVelocity()
getMouseScroll = () => [number, number]Return the x and y velocity of mouse scrollworld.input.getMouseScroll()
enablePointerLockRequest = () => voidRequest a pointer lock from the user when the screen is clicked.world.input.enablePointerLockRequest()
disablePointerLockRequest = () => voidDisables the pointer lock request on click.world.input.disablePointerLockRequest()