Skip to content
Open
2 changes: 2 additions & 0 deletions creator/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,14 @@
* [Raycasting](sdk7/interactivity/raycasting.md)
* [Runtime Data](sdk7/interactivity/runtime-data.md)
* [Skybox Control](sdk7/interactivity/skybox-control.md)
* [On-screen Controls](sdk7/interactivity/touch-screen-controls.md)
* [User Data](sdk7/interactivity/user-data.md)
* [2D UI](sdk7/2d-ui/)
* [Onscreen UI](sdk7/2d-ui/onscreen-ui.md)
* [UI Positioning](sdk7/2d-ui/ui-positioning.md)
* [UI Background](sdk7/2d-ui/ui_background.md)
* [UI Button Events](sdk7/2d-ui/ui_button_events.md)
* [UI Input Binding](sdk7/2d-ui/ui_input_binding.md)
* [UI Special Types](sdk7/2d-ui/ui_special_types.md)
* [UI Text](sdk7/2d-ui/ui_text.md)
* [Dynamic UI](sdk7/2d-ui/dynamic-ui.md)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions creator/sdk7/2d-ui/onscreen-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ The following components are available to use in a `UiEntity`:
* `uiBackground`
* `uiText`
* `onClick`
* [`uiInputBinding`](ui_input_binding.md) — hold input actions while the element is pressed, to build custom controls

Like with HTML tags, you can define components as self-closing or nest one within another.

Expand Down
75 changes: 75 additions & 0 deletions creator/sdk7/2d-ui/ui_input_binding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
description: Bind input actions to your own UI elements so they drive player input.
---

# UI Input Binding

`UiInputBinding` turns any UI element into a control button. Bind an element to one or more [`InputAction`](../interactivity/button-events/click-events.md#pointer-buttons)s, and while it's pressed — by touch or pointer — those actions are held down, driving both the local player's input (movement, jumping) and any scene [`InputAction`](../interactivity/button-events/click-events.md#pointer-buttons) listeners, exactly like the native on-screen buttons.

Use it to build your own touch controls. It's typically paired with [On-screen Controls](../interactivity/touch-screen-controls.md): hide the native buttons, then put your own in their place.

<figure><img src="../../images/touch-controls/ui-input-binding.jpg" alt="A retro-style gamepad assembled from custom UI elements, each wired to an input action"><figcaption><p>A fully custom gamepad built from UI elements — each button is a UI entity bound to an input action</p></figcaption></figure>

## Bind an action to a UI element

Add a `uiInputBinding` prop to any element in your `.tsx` UI and list the actions to hold while it's pressed. The prop is available on every UI element ([`UiEntity`](onscreen-ui.md#ui-entities), [`Button`](onscreen-ui.md#ui-entities), [`Label`](onscreen-ui.md#ui-entities), …), just like `uiTransform` and `uiBackground`.

**A button that moves the player forward while held:**

```tsx
import { InputAction } from '@dcl/sdk/ecs'
import { Button } from '@dcl/sdk/react-ecs'

export const forwardButton = () => (
<Button
value="▲"
uiTransform={{ width: 100, height: 100 }}
uiInputBinding={{ actions: [InputAction.IA_FORWARD] }}
/>
)
```

## Build a custom control cluster

Combine several bound elements to assemble a full control scheme.

**A movement button plus an action button that fires `IA_PRIMARY`:**

```tsx
import { InputAction } from '@dcl/sdk/ecs'
import { Button, UiEntity } from '@dcl/sdk/react-ecs'

export const customControls = () => (
<UiEntity uiTransform={{ width: 240, height: 120 }}>
<Button
value="▲"
uiTransform={{ width: 100, height: 100 }}
uiInputBinding={{ actions: [InputAction.IA_FORWARD] }}
/>
<Button
value="Use"
uiTransform={{ width: 100, height: 100 }}
uiInputBinding={{ actions: [InputAction.IA_PRIMARY] }}
/>
</UiEntity>
)
```

The bound actions behave just like the native buttons: `IA_FORWARD` / `IA_BACKWARD` / `IA_LEFT` / `IA_RIGHT` move the avatar, and any action can be read by your scene's [`InputAction`](../interactivity/button-events/click-events.md#pointer-buttons) listeners. Removing the prop (or the component) releases the binding.

## Properties

| Property | Type | Description |
| --- | --- | --- |
| `actions` | array of [`InputAction`](../interactivity/button-events/click-events.md#pointer-buttons) | The input actions held down while this element is pressed. See [Click events](../interactivity/button-events/click-events.md) for the full list of [`InputAction`](../interactivity/button-events/click-events.md#pointer-buttons) values. |

{% hint style="info" %}
Pair this with [`TouchScreenControls`](../interactivity/touch-screen-controls.md) to hide the native controls and replace them with your own touch UI — the recommended way to ship a fully custom control scheme.
{% endhint %}

## Related

* [On-screen Controls](../interactivity/touch-screen-controls.md)
* [UI Button Events](ui_button_events.md)
* [Input on mobile](../building-for-mobile/input-on-mobile.md)
* [Click events](../interactivity/button-events/click-events.md)
47 changes: 22 additions & 25 deletions creator/sdk7/building-for-mobile/input-on-mobile.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,46 @@ description: How input actions map to touch on the Decentraland mobile client.

# Input on Mobile

Decentraland's input system is designed to be device-agnostic. The same `InputAction` enum that the SDK exposes on desktop is also routed from the on-screen controls on mobile, so most scenes work without any changes. There are, however, a few rules and gotchas worth knowing when you're building for touch.
Decentraland's input system is designed to be device-agnostic. The same [`InputAction`](../interactivity/button-events/click-events.md#pointer-buttons) enum that the SDK exposes on desktop is also routed from the on-screen controls on mobile, so most scenes work without any changes. There are, however, a few rules and gotchas worth knowing when you're building for touch.

For the full input model, see [Click events](../interactivity/button-events/click-events.md). This page focuses on what is mobile-specific.

## What touch maps to

Every `InputAction` that exists on desktop is also available on the mobile client — the on-screen controls simply route touch to the same SDK inputs. This means any scene that relies on the standard `InputAction` values will work on mobile out of the box.
Every [`InputAction`](../interactivity/button-events/click-events.md#pointer-buttons) that exists on desktop is also available on the mobile client — the on-screen controls simply route touch to the same SDK inputs. This means any scene that relies on the standard [`InputAction`](../interactivity/button-events/click-events.md#pointer-buttons) values will work on mobile out of the box.

The on-screen controls map as follows:
<figure><img src="../../images/touch-controls/touch-controls-default.jpg" alt="Default on-screen controls"><figcaption><p>Default on-screen controls</p></figcaption></figure>

* **On-screen joystick** — drives `IA_FORWARD` / `IA_BACKWARD` / `IA_LEFT` / `IA_RIGHT` and avatar movement.
* **Interaction button (bottom right)** — fires `IA_POINTER` (the left mouse button on desktop) against whatever the player is aiming at.
* **E button** — fires `IA_PRIMARY` (the `E` key on desktop).
* **F button** — fires `IA_SECONDARY` (the `F` key on desktop).
* **Jump button** — fires `IA_JUMP` (the `Space` key on desktop). This is the largest button on the HUD and is always easy to reach.
* **1 / 2 / 3 / 4 buttons** — fire `IA_ACTION_3` / `IA_ACTION_4` / `IA_ACTION_5` / `IA_ACTION_6` respectively. These live behind a secondary menu (see below).
* **Camera drag** — rotates the camera; not exposed as an `InputAction`.
The on-screen controls map to input actions as follows:

## Inputs to avoid for key actions on mobile
| Control | InputAction | Notes |
| --- | --- | --- |
| **On-screen joystick** | `IA_FORWARD` / `IA_BACKWARD` / `IA_LEFT` / `IA_RIGHT` | Drives avatar movement. |
| **Interaction button** (bottom right) | `IA_POINTER` | The left mouse button on desktop; fires against whatever the player is aiming at. |
| **E button** | `IA_PRIMARY` | The `E` key on desktop. |
| **F button** | `IA_SECONDARY` | The `F` key on desktop. |
| **Jump button** | `IA_JUMP` | The `Space` key on desktop. By default the largest, most reachable button — but a scene can reconfigure or hide it (see [Customizing the on-screen controls](#customizing-the-on-screen-controls)). |
| **1 / 2 / 3 / 4 buttons** | `IA_ACTION_3` / `IA_ACTION_4` / `IA_ACTION_5` / `IA_ACTION_6` | In the default layout these live behind a secondary "+" menu (see below). |
| **Camera drag** | — | Rotates the camera; not exposed as an [`InputAction`](../interactivity/button-events/click-events.md#pointer-buttons). |

All `InputAction` values are reachable on mobile, but `IA_ACTION_3`–`IA_ACTION_6` (the `1`/`2`/`3`/`4` buttons) are tucked away behind a secondary menu and are **not easily reachable during gameplay**. If your scene uses them as primary actions, mobile players will not be able to trigger them comfortably.
## Choosing reachable actions

Avoid binding key actions to:
In the default layout the `1`/`2`/`3`/`4` buttons (`IA_ACTION_3`–`IA_ACTION_6`) sit behind the "+" menu and are awkward to reach mid-game. For a key action, prefer a directly visible button — `IA_POINTER`, `IA_PRIMARY`, `IA_SECONDARY`, or `IA_JUMP` — or a [proximity trigger](../interactivity/button-events/proximity-events.md) that fires automatically as the player approaches. Alternatively, [customize the controls](#customizing-the-on-screen-controls) to surface the exact button you need.

* `IA_ACTION_3` — the `1` key on desktop / `1` button on mobile
* `IA_ACTION_4` — the `2` key on desktop / `2` button on mobile
* `IA_ACTION_5` — the `3` key on desktop / `3` button on mobile
* `IA_ACTION_6` — the `4` key on desktop / `4` button on mobile
## Cursor lock

Prefer instead:
The [`PointerLock` component](../interactivity/button-events/click-events.md#lock-or-unlock-the-cursor) is a desktop-client concept (locked vs. unlocked mouse cursor). It does not apply to touch on mobile and is safe to leave in your scene — it has no effect there.

* `IA_POINTER` for the main tap / interaction button
* `IA_PRIMARY` for the E button action
* `IA_SECONDARY` for the F button action
* `IA_JUMP` when an action maps naturally to jumping (it's the largest and most reachable button on the mobile HUD)
* Proximity-based triggers (see [Proximity Events](../interactivity/button-events/proximity-events.md)) when an action should fire automatically as the player approaches an entity
## Customizing the on-screen controls

## Cursor lock
Scenes can reconfigure these on-screen controls — hide the joystick or crosshair, hide any button (including jump), change what the central button does, re-icon buttons, or replace them with custom UI. See [On-screen Controls](../interactivity/touch-screen-controls.md) and [UI Input Binding](../2d-ui/ui_input_binding.md).

The [`PointerLock` component](../interactivity/button-events/click-events.md#lock-or-unlock-the-cursor) is a desktop-client concept (locked vs. unlocked mouse cursor). It does not apply to touch on mobile and is safe to leave in your scene — it has no effect there.
<figure><img src="../../images/touch-controls/custom-main-action.jpg" alt="Customized on-screen controls"><figcaption><p>Customized on-screen controls: a re-iconed central button</p></figcaption></figure>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add image here

Image

## Related

* [On-screen Controls](../interactivity/touch-screen-controls.md)
* [UI Input Binding](../2d-ui/ui_input_binding.md)
* [Click events](../interactivity/button-events/click-events.md)
* [Proximity Events](../interactivity/button-events/proximity-events.md)
* [Detect the platform from code](detect-platform.md)
Expand Down
Loading