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).
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.
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.
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.
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.
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 Name | Type | Notes |
---|---|---|
pointerId | number | A unique ID for the pointer provided by the browser |
position | {x: number, y: number} | The screen position in pixels |
target | Eid (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 Name | Type | Notes |
---|---|---|
touchCount | number | The 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. |
spread | number | The average distance between pointers from the center point, a metric of how pinched or spread the touches are. |
startSpread | number | On move, the first spread emitted in start. |
spreadChange | number | On move, the delta of spread since the last event. |
nextTouchCount | number | On 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
Function | Description | Example |
---|---|---|
setActiveMap = (name: string) => void | Sets the active action map. The default action map's name is default | world.input.setActiveMap('menu') |
getActiveMap = () => void | Fetches the active action map. | world.input.getActiveMap() |
getAction = (action: string) => number | Returns > 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
Function | Description | Example |
---|---|---|
getKey = (code: string) => boolean | Returns true while the user holds down the key identified by name. | world.input.getKey('KeyQ') |
getKeyDown = (code: string) => boolean | Returns true during the frame the user starts pressing down the key identified by name. | world.input.getKeyDown('KeyQ') |
getKeyUp = (code: string) => boolean | Returns true during the frame the user releases the key identified by name. | world.input.getKeyUp('KeyQ') |
Gamepad Input
Function | Description | Example |
---|---|---|
getButton = (input: number, gamepadIdx?: number) => boolean | Takes a Returns true while the virtual button identified by buttonName is held down. | world.input.getButton(1) |
getButtonDown = (input: number, gamepadIdx?: number) => boolean | Returns true during the frame the user pressed down the button mapped to the index https://www.w3.org/TR/gamepad/#remapping | world.input.getButtonDown(1) |
getButtonUp = (input: number, gamepadIdx?: number) => boolean | Returns 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 Name | Type | Notes |
---|---|---|
gamepad | Gamepad | The 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.
Number | Mouse Button |
---|---|
0 | Primary |
1 | Auxillary |
2 | Secondary |
3 | Fourth |
4 | Fifth |
Function | Description | Example |
---|---|---|
getMouseButton = (button: number) => boolean | Returns true while the user holds down the mouse button identified by button number. | world.input.getMouseButton(0) |
getMouseDown = (button: number) => boolean | Returns true during the frame the user starts pressing down on the mouse button. | world.input.getMouseDown(0) |
getMouseUp = (button: number) => boolean | Returns 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 mouse | world.input.getMouseVelocity() |
getMouseScroll = () => [number, number] | Return the x and y velocity of mouse scroll | world.input.getMouseScroll() |
enablePointerLockRequest = () => void | Request a pointer lock from the user when the screen is clicked. | world.input.enablePointerLockRequest() |
disablePointerLockRequest = () => void | Disables the pointer lock request on click. | world.input.disablePointerLockRequest() |