---
title: "Input Action System"
url: /docs/en-us/input/input-action-system
last_updated: 2026-06-10T23:09:06Z
description: "The cross-platform Input Action System lets you connect actions and arrange bindings across various hardware inputs at edit time."
---

# Input Action System

The cross-platform **Input Action System** lets you connect [actions](#input-actions) and arrange [bindings](#input-bindings) across various hardware inputs at edit time. Combined with [contexts](#input-contexts), you can easily configure and edit a modular input system that works on any device in any phase of play. Use cases include:

- A first-person shooter system with actions dynamically swapping in and out depending on if the player is in battle mode or spectator mode.
- A comprehensive driving system equipped with acceleration/deceleration, car boosters, and refuel stations.
- Hotkeys for an abilities system in a fighting game to swap out moves seamlessly without players missing a punch.

## Input contexts

An `Class.InputContext` is a collection of actions which holds related [input actions](#input-actions), for example `PlayContext` for in‑experience character controls and `NavContext` for controls to navigate around UI menus. You can [enable/disable contexts](#context-changes) (and their corresponding actions) through their `Class.InputContext.Enabled|Enabled` property, such as to enable the `NavContext` when an inventory menu is open and then change to the `PlayContext` when the player closes the menu and returns to primary gameplay.

Even if an experience may not use multiple input contexts initially, it's recommended to create a primary context at the top level of any input system, for example the `PlayContext` instance for input that occurs during gameplay.

1. **RECOMMENDED** Create a `Class.Folder` named `Inputs` inside `Class.ReplicatedStorage` to hold various input contexts.![New Folder inside ReplicatedStorage, renamed to Inputs](../assets/studio/explorer/ReplicatedStorage-Folder-Inputs.png)
2. Insert a new `Class.InputContext` into the folder and rename it to `PlayContext`.![New InputContext instance inside ReplicatedStorage, renamed to PlayContext](../assets/studio/explorer/ReplicatedStorage-InputContext.png)
3. In the [Properties](/docs/en-us/studio/properties.md) window, set `Class.InputContext.Priority|Priority` to `2000` and enable `Class.InputContext.Sink|Sink`. A context with `Class.InputContext.Sink|Sink` enabled consumes input events for its bound `Enum.KeyCode|KeyCodes` at its priority level, blocking those inputs from reaching lower-priority contexts. This is practical for use cases like an inventory screen that should suppress specific gameplay inputs while open. In this example, `PlayContext` is given a high enough `Class.InputContext.Priority|Priority` to sink its bound inputs before the default `Class.PlayerScripts` contexts process them.

## Input actions

An `Class.InputAction` defines a gameplay action mechanic such as "Jump," "Sprint," or "Shoot." These actions are then mapped to hardware inputs using [input bindings](#input-bindings).

An `Class.InputAction` can be of several variations depending on its `Class.InputAction.Type|Type` property (`Enum.InputActionType`). The default is `Enum.InputActionType|Bool`, designed to receive `true`/`false` values from press/release of inputs such as `Enum.KeyCode.ButtonA|ButtonA`, `Enum.KeyCode.E|E`, or `Enum.KeyCode.MouseLeftButton|MouseLeftButton`.

| Input Action Type | Example Usage |
| --- | --- |
| `Enum.InputActionType\|Bool` | Triggered actions such as jump, shoot, sprint, etc. with support for pressed/released thresholds on analog inputs. |
| `Enum.InputActionType\|Direction1D` | Variable zero-to-full actions such as a car's accelerator pedal or a view scope's zoom level. |
| `Enum.InputActionType\|Direction2D` | 2D directional movement such as camera rotation, or the standard Roblox character movement. |
| `Enum.InputActionType\|Direction3D` | 3D directional movement like an airborne vehicle that can levitate up/down, accelerate/decelerate, and drift left/right. |
| `Enum.InputActionType\|ViewportPosition` | 2D viewport coordinates like mouse input, such as for custom cursors or raycasting to select world objects. |

#### Character Sprint

To test an `Class.InputAction` for simple character sprinting:

1. Create a new `Class.InputAction` inside the `PlayContext` context within `Class.ReplicatedStorage`. Rename it to `CharacterSprint` to indicate its dedicated action.![New InputAction instance inside an InputContext, renamed to CharacterSprint](../assets/studio/explorer/ReplicatedStorage-InputContext-SprintAction.png)
2. In the [Properties](/docs/en-us/studio/properties.md) window, notice that the action's `Class.InputAction.Type|Type` is `Enum.InputActionType|Bool` (default). This is a logical type for simple character sprinting as a boolean `true`/`false` action (character is either sprinting or not sprinting).![Type property of an InputAction set to Bool](../assets/studio/properties/SprintAction-Type-Bool.png)

#### Camera Rotation

To test an `Class.InputAction` for camera rotation:

1. Create a new `Class.InputAction` inside the `PlayContext` context within `Class.ReplicatedStorage`. Rename it to `CameraRotate` to indicate its dedicated action.![New InputAction instance inside an InputContext, renamed to CameraRotate](../assets/studio/explorer/ReplicatedStorage-InputContext-CameraAction.png)
2. In the [Properties](/docs/en-us/studio/properties.md) window, set the action's `Class.InputAction.Type|Type` to `Enum.InputActionType|Direction2D`. This reflects that camera rotation is a continuous 2D analog input rather than a discrete press/release.![Type property of an InputAction set to Direction2D](../assets/studio/properties/CameraAction-Type-Direction2D.png)

## Input bindings

An `Class.InputBinding` defines which hardware binding should trigger the parent `Class.InputAction`, for example a key press, gamepad button, or tap on a touch‑enabled device. For [cross‑platform](/docs/en-us/projects/cross-platform.md) compatibility, each `Class.InputAction` should have an `Class.InputBinding` for **gamepad**, **keyboard/mouse**, and **touch** as illustrated here.

The `Class.InputAction.Type|Type` assigned to the parent `Class.InputAction` directly affects which general input types (key/button/tap, analog trigger, thumbstick, etc.) are valid for child `Class.InputBinding` instances. In turn, values sent to the parent action's connected events depend on a binding's chosen input type. See [input events](#input-events) for details on the correlation between action types, bindings, and return values.

#### Character Sprint

To hook up bindings for simple character sprinting:

1. Insert a new `Class.InputBinding` into the `CharacterSprint` action and rename it to `KeyboardBinding`. Then set the binding's `Class.InputBinding.KeyCode|KeyCode` property to `Enum.KeyCode.LeftShift|LeftShift`.
2. To ensure mouse `Shift`-lock does not interfere with the key binding, select `Class.StarterPlayer` in the [Explorer](/docs/en-us/studio/explorer.md) and disable its `Class.StarterPlayer.EnableMouseLockOption|EnableMouseLockOption` in the [Properties](/docs/en-us/studio/properties.md) window.
3. Insert a second `Class.InputBinding` into the `CharacterSprint` action and rename it to `GamepadBinding`. Then set the binding's `Class.InputBinding.KeyCode|KeyCode` property to `Enum.KeyCode.ButtonY|ButtonY`.
4. Inside a `Class.ScreenGui` container inside `Class.StarterGui`, create an [on-screen button](/docs/en-us/ui/buttons.md), rename it to `SprintButton`, and [position/resize](/docs/en-us/ui/position-and-size.md) it as desired.
5. Insert a third `Class.InputBinding` into the `CharacterSprint` action and rename it to `TouchBinding`. Then, in the [Properties](/docs/en-us/studio/properties.md) window, link the binding's `Class.InputBinding.UIButton|UIButton` property to the `SprintButton` button you created previously inside `Class.StarterGui`.

#### Camera Rotation

To hook up bindings for camera rotation:

1. Insert a new `Class.InputBinding` into the `CameraRotate` action and rename it to `KeyboardBinding`. Leave `Class.InputBinding.KeyCode|KeyCode` empty and instead set the four composite directional properties — `Class.InputBinding.Left|Left`, `Class.InputBinding.Right|Right`, `Class.InputBinding.Up|Up`, and `Class.InputBinding.Down|Down` — to `Enum.KeyCode.Left|Left`, `Enum.KeyCode.Right|Right`, `Enum.KeyCode.Up|Up`, and `Enum.KeyCode.Down|Down` respectively.
2. Insert a second `Class.InputBinding` and rename it to `GamepadBinding`. Then set the binding's `Class.InputBinding.KeyCode|KeyCode` property to `Enum.KeyCode.Thumbstick2|Thumbstick2` (the right thumbstick).
3. Insert a third `Class.InputBinding` and rename it to `MouseBinding`. Set the binding's `Class.InputBinding.KeyCode|KeyCode` property to `Enum.KeyCode.MouseDelta|MouseDelta` and its `Class.InputBinding.Scale|Scale` to `0.01`. `Enum.KeyCode.MouseDelta|MouseDelta` reports values in pixels, so the scale converts them to a reasonable rotation range.
4. Insert a fourth `Class.InputBinding` and rename it to `TouchBinding`. Set the binding's `Class.InputBinding.KeyCode|KeyCode` property to `Enum.KeyCode.TouchDelta|TouchDelta` and its `Class.InputBinding.Scale|Scale` to `0.01`. Like `Enum.KeyCode.MouseDelta|MouseDelta`, `Enum.KeyCode.TouchDelta|TouchDelta` reports values in pixels.

## Input events

The `Class.InputAction` instance has three built-in **events** to handle player input coming from `Class.InputBinding|InputBindings`.

- `Class.InputAction.Pressed|Pressed` — This event fires only when the input action's `Class.InputAction.Type|Type` is set to `Enum.InputActionType|Bool`, and only when the state transitions from `false` to `true`.
- `Class.InputAction.Released|Released` — This event fires only when the input action's `Class.InputAction.Type|Type` is set to `Enum.InputActionType|Bool`, and only when the state transitions from `true` to `false`.
- `Class.InputAction.StateChanged|StateChanged` — This event fires for all input action types whenever the state changes, except if the state attempts to transition to the same state.

Depending on the input action's `Class.InputAction.Type|Type` (`Enum.InputActionType|Bool`, `Enum.InputActionType|Direction1D`, `Enum.InputActionType|Direction2D`, `Enum.InputActionType|Direction3D`, or `Enum.InputActionType|ViewportPosition`) and the general input type coming from a child `Class.InputBinding` (key/button/tap, analog trigger, thumbstick, etc.), different values are returned to the `Class.InputAction.Pressed|Pressed`, `Class.InputAction.Released|Released`, and `Class.InputAction.StateChanged|StateChanged` event handlers. Examine the following tables to better understand the correlation.

#### Bool

The `Enum.InputActionType|Bool` type is best for triggered actions such as jump, shoot, sprint, etc. with support for pressed/released thresholds on analog inputs.

| Valid Input Types on `Class.InputBinding\|InputBindings` | Returned to the `Class.InputAction` Event(s) |
| --- | --- |
| Boolean inputs from keyboard keys or basic mouse/gamepad buttons through the binding's `Class.InputBinding.KeyCode\|KeyCode` property, or a `Class.GuiButton` press/release through the binding's `Class.InputBinding.UIButton\|UIButton` property. | <ul><li>`Class.InputAction.Pressed\|Pressed` event:<ul><li>`true` when pressed</li></ul></li><li>`Class.InputAction.Released\|Released` event:<ul><li>`true` when released</li></ul></li><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`true` (pressed) or `false` (released)</li></ul></li></ul> |
| Variable input amounts from analog inputs like gamepad triggers (`Enum.KeyCode.ButtonL2\|ButtonL2`/`Enum.KeyCode.ButtonR2\|ButtonR2`) through the binding's `Class.InputBinding.KeyCode\|KeyCode` property. | <ul><li>`Class.InputAction.Pressed\|Pressed` event:<ul><li>`true` when trigger press is `>=` `Class.InputBinding.PressedThreshold\|PressedThreshold`</li></ul></li><li>`Class.InputAction.Released\|Released` event:<ul><li>`true` when trigger press is `<=` `Class.InputBinding.ReleasedThreshold\|ReleasedThreshold`</li></ul></li><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`true` when trigger press is `>=` `Class.InputBinding.PressedThreshold\|PressedThreshold`</li><li>`false` when trigger press is `<=` `Class.InputBinding.ReleasedThreshold\|ReleasedThreshold`</li></ul></li></ul> |

#### Direction1D

The `Enum.InputActionType|Direction1D` type is best for variable zero‑to‑full actions such as a car's accelerator pedal or a view scope's zoom level.

| Valid Input Types on `Class.InputBinding\|InputBindings` | Returned to the `Class.InputAction` Event(s) |
| --- | --- |
| Variable input amounts from analog inputs like gamepad triggers (`Enum.KeyCode.ButtonL2\|ButtonL2`/`Enum.KeyCode.ButtonR2\|ButtonR2`) through the binding's `Class.InputBinding.KeyCode\|KeyCode`, `Class.InputBinding.Up\|Up`, and `Class.InputBinding.Down\|Down` properties. | <ul><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`0` to `1` (fully released to fully pressed) through the `Class.InputBinding.KeyCode\|KeyCode` or `Class.InputBinding.Up\|Up` properties</li><li>`0` to `-1` (fully released to fully pressed) through the `Class.InputBinding.Down\|Down` property</li></ul></li></ul> |
| Boolean inputs from keyboard keys or basic mouse/gamepad buttons through the binding's `Class.InputBinding.KeyCode\|KeyCode`, `Class.InputBinding.Up\|Up`, and `Class.InputBinding.Down\|Down` properties. | <ul><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`1` (pressed) or `0` (released) through the `Class.InputBinding.KeyCode\|KeyCode` or `Class.InputBinding.Up\|Up` properties</li><li>`-1` (pressed) or `0` (released) through the `Class.InputBinding.Down\|Down` property</li></ul></li></ul> |

#### Direction2D

The `Enum.InputActionType|Direction2D` type is best for 2D directional movement such as camera rotation, or the standard Roblox character movement.

| Valid Input Types on `Class.InputBinding\|InputBindings` | Returned to the `Class.InputAction` Event(s) |
| --- | --- |
| Variable input amounts from 2D analog inputs like gamepad thumbsticks (`Enum.KeyCode.Thumbstick1\|Thumbstick1`/`Enum.KeyCode.Thumbstick2\|Thumbstick2`) through the binding's `Class.InputBinding.KeyCode\|KeyCode` property. | <ul><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`Datatype.Vector2` between`(-1, -1)` and`(1, 1)`</li></ul></li></ul> |
| Variable input amounts from analog inputs like gamepad triggers (`Enum.KeyCode.ButtonL2\|ButtonL2`/`Enum.KeyCode.ButtonR2\|ButtonR2`) through the binding's `Class.InputBinding.Up\|Up`, `Class.InputBinding.Down\|Down`, `Class.InputBinding.Left\|Left`, and `Class.InputBinding.Right\|Right` properties. | <ul><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`Datatype.Vector2` with `Datatype.Vector2.Y\|Y` component between `0` and `1` (fully released to fully pressed) through the `Class.InputBinding.Up\|Up` property</li><li>`Datatype.Vector2` with `Datatype.Vector2.Y\|Y` component between `0` and `-1` (fully released to fully pressed) through the `Class.InputBinding.Down\|Down` property</li><li>`Datatype.Vector2` with `Datatype.Vector2.X\|X` component between `0` and `-1` (fully released to fully pressed) through the `Class.InputBinding.Left\|Left` property</li><li>`Datatype.Vector2` with `Datatype.Vector2.X\|X` component between `0` and `1` (fully released to fully pressed) through the `Class.InputBinding.Right\|Right` property</li></ul></li></ul> |
| Boolean inputs from keyboard keys or basic mouse/gamepad buttons through the binding's `Class.InputBinding.Up\|Up`, `Class.InputBinding.Down\|Down`, `Class.InputBinding.Left\|Left`, and `Class.InputBinding.Right\|Right` properties. | <ul><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`Datatype.Vector2` of`(0, 1)` (pressed) or`(0, 0)` (released) through the `Class.InputBinding.Up\|Up` property</li><li>`Datatype.Vector2` of`(0, -1)` (pressed) or`(0, 0)` (released) through the `Class.InputBinding.Down\|Down` property</li><li>`Datatype.Vector2` of`(-1, 0)` (pressed) or`(0, 0)` (released) through the `Class.InputBinding.Left\|Left` property</li><li>`Datatype.Vector2` of`(1, 0)` (pressed) or`(0, 0)` (released) through the `Class.InputBinding.Right\|Right` property</li></ul></li></ul> |

#### Direction3D

The `Enum.InputActionType|Direction3D` type is best for 3D directional movement like an airborne vehicle that can levitate up/down, accelerate/decelerate, and drift left/right.

| Valid Input Types on `Class.InputBinding\|InputBindings` | Returned to the `Class.InputAction` Event(s) |
| --- | --- |
| Variable input amounts from analog inputs like gamepad triggers (`Enum.KeyCode.ButtonL2\|ButtonL2`/`Enum.KeyCode.ButtonR2\|ButtonR2`) through the binding's `Class.InputBinding.Up\|Up`, `Class.InputBinding.Down\|Down`, `Class.InputBinding.Left\|Left`, `Class.InputBinding.Right\|Right`, `Class.InputBinding.Forward\|Forward`, and `Class.InputBinding.Backward\|Backward` properties. | <ul><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`Datatype.Vector3` with `Datatype.Vector3.Y\|Y` component between `0` and `1` (fully released to fully pressed) through the `Class.InputBinding.Up\|Up` property</li><li>`Datatype.Vector3` with `Datatype.Vector3.Y\|Y` component between `0` and `-1` (fully released to fully pressed) through the `Class.InputBinding.Down\|Down` property</li><li>`Datatype.Vector3` with `Datatype.Vector3.X\|X` component between `0` and `-1` (fully released to fully pressed) through the `Class.InputBinding.Left\|Left` property</li><li>`Datatype.Vector3` with `Datatype.Vector3.X\|X` component between `0` and `1` (fully released to fully pressed) through the `Class.InputBinding.Right\|Right` property</li><li>`Datatype.Vector3` with `Datatype.Vector3.Z\|Z` component between `0` and `-1` (fully released to fully pressed) through the `Class.InputBinding.Forward\|Forward` property</li><li>`Datatype.Vector3` with `Datatype.Vector3.Z\|Z` component between `0` and `1` (fully released to fully pressed) through the `Class.InputBinding.Backward\|Backward` property</li></ul></li></ul> |
| Boolean inputs from keyboard keys or basic mouse/gamepad buttons through the binding's `Class.InputBinding.Up\|Up`, `Class.InputBinding.Down\|Down`, `Class.InputBinding.Left\|Left`, `Class.InputBinding.Right\|Right`, `Class.InputBinding.Forward\|Forward`, and `Class.InputBinding.Backward\|Backward` properties. | <ul><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`Datatype.Vector3` of`(0, 1, 0)` (pressed) or`(0, 0, 0)` (released) through the `Class.InputBinding.Up\|Up` property</li><li>`Datatype.Vector3` of`(0, -1, 0)` (pressed) or`(0, 0, 0)` (released) through the `Class.InputBinding.Down\|Down` property</li><li>`Datatype.Vector3` of`(-1, 0, 0)` (pressed) or`(0, 0, 0)` (released) through the `Class.InputBinding.Left\|Left` property</li><li>`Datatype.Vector3` of`(1, 0, 0)` (pressed) or`(0, 0, 0)` (released) through the `Class.InputBinding.Right\|Right` property</li><li>`Datatype.Vector3` of`(0, 0, -1)` (pressed) or`(0, 0, 0)` (released) through the `Class.InputBinding.Forward\|Forward` property</li><li>`Datatype.Vector3` of`(0, 0, 1)` (pressed) or`(0, 0, 0)` (released) through the `Class.InputBinding.Backward\|Backward` property</li></ul></li></ul> |

#### ViewportPosition

The `Enum.InputActionType|ViewportPosition` type is best for absolute 2D viewport coordinates of an input such as a mouse pointer or touch, which can be used for features like custom cursors or selecting objects.

| Valid Input Types on `Class.InputBinding\|InputBindings` | Returned to the `Class.InputAction` Event(s) |
| --- | --- |
| Variable input amounts from positional inputs such as a mouse pointer (`Enum.KeyCode.MousePosition\|MousePosition`) or touch (`Enum.KeyCode.Touch\|Touch`). | <ul><li>`Class.InputAction.StateChanged\|StateChanged` event:<ul><li>`Datatype.Vector2` between`(0, 0)` and the maximum absolute`(X, Y)` pixel size in the viewport.</li></ul></li></ul> |

#### Character Sprint

To connect events for simple character sprinting:

1. Insert a new `Class.Script` into the `CharacterSprint` tree, alongside the various input bindings. Then set its `Class.BaseScript.RunContext|RunContext` to `Enum.RunContext.Client|Client` and rename it to `OnActivate`.
2. Paste the following code into the `OnActivate` script. Note the `Class.InputAction.Pressed|Pressed` event connection on lines `13`‑`15` which doubles the character's walk speed when a sprint input binding is pressed, and the corresponding `Class.InputAction.Released|Released` event connection on lines `16`‑`18` which resets the walk speed to default when a sprint input binding is released.```lua
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local character = player.Character
if not character or character.Parent == nil then
	character = player.CharacterAdded:Wait()
end
local humanoid = character:WaitForChild("Humanoid")
local defaultWalkSpeed = humanoid.WalkSpeed

local inputAction = script.Parent

inputAction.Pressed:Connect(function()
	humanoid.WalkSpeed = defaultWalkSpeed * 2
end)
inputAction.Released:Connect(function()
	humanoid.WalkSpeed = defaultWalkSpeed
end)
```
3. Playtest your experience and test the character sprint action with the [bindings](#input-bindings) you chose previously: `Enum.KeyCode.LeftShift|LeftShift` for keyboard, `Enum.KeyCode.ButtonY|ButtonY` for gamepad, and the on‑screen `SprintButton` for touch‑enabled devices. Remember that you can use the [Controller Emulator](/docs/en-us/studio/testing-modes.md#controller-emulation) to test gamepad inputs directly in Roblox Studio.

#### Camera Rotation

For **continuous analog inputs** like camera rotation, `Class.InputAction.StateChanged|StateChanged` fires **once** when the state changes and does not signal until the next change, so a thumbstick held at a fixed angle only fires the event once. In these cases, poll `Class.InputAction:GetState()|GetState()` each frame and multiply by delta time for frame-rate-independent behavior.

1. Insert a new `Class.Script` into the `CameraRotate` tree, alongside the various input bindings. Then set its `Class.BaseScript.RunContext|RunContext` to `Enum.RunContext.Client|Client` and rename it to `OnInput`.
2. Paste the following code into the `OnInput` script. Note that it uses `Class.RunService:BindToRenderStep()|BindToRenderStep()` with `Enum.RenderPriority|Enum.RenderPriority.Camera.Value` rather than `Class.RunService.RenderStepped|RenderStepped`; this guarantees the camera update runs after the engine's input processing step and stays synchronized with the default `Class.PlayerScripts` camera pipeline.```lua
local RunService = game:GetService("RunService")

local CAMERA_SENSITIVITY = 1.5 -- Radians per second at action state 1

local inputAction = script.Parent
local camera = workspace.CurrentCamera

RunService:BindToRenderStep("CameraRotation", Enum.RenderPriority.Camera.Value, function(dt)
	local state = inputAction:GetState()
	if state.Magnitude > 0 then
		camera.CFrame = camera.CFrame
			* CFrame.Angles(0, -state.X * CAMERA_SENSITIVITY * dt, 0)
			* CFrame.Angles(-state.Y * CAMERA_SENSITIVITY * dt, 0, 0)
	end
end)
```

## Context changes

Once you have an [input context](#input-contexts) such as `PlayContext`, you can enable/disable it during gameplay through scripting, change its `Class.InputContext.Priority|Priority` to determine which actions take precedence over others, and `Class.InputContext.Sink|Sink` inputs from being processed within contexts of lower priority.

1. To make it easier to switch contexts from other scripts, insert a new `Class.BindableEvent` into your inputs folder within `Class.ReplicatedStorage` and rename it to `ContextEvent`.
2. Create a new `Class.Script` at the same level, set its `Class.BaseScript.RunContext|RunContext` to `Enum.RunContext.Client|Client`, and rename it to `UpdateContext`.
3. Inside the `UpdateContext` script, paste the following code:```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local inputsFolder = ReplicatedStorage:WaitForChild("Inputs")
local contextEvent = inputsFolder:WaitForChild("ContextEvent")

-- Connect bindable event
contextEvent.Event:Connect(function(targetContext, enabled)
	local context = inputsFolder:FindFirstChild(targetContext)
	if context then
		context.Enabled = enabled
		print(context.Name .. ": " .. tostring(context.Enabled))
	else
		warn("InputContext not found!")
	end
end)
```
4. With the `UpdateContext` script in place, you can now update a named `Class.InputContext` by firing the bindable event, for example from a `Class.LocalScript` that powers a `Class.GuiButton` inside a `Class.ScreenGui` container.```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local inputsFolder = ReplicatedStorage:WaitForChild("Inputs")
local contextEvent = inputsFolder:WaitForChild("ContextEvent")

local button = script.Parent
button.Activated:Connect(function()
	-- Fire bindable event with target input context and enabled state
	contextEvent:Fire("PlayContext", true)
end)
```

## Default bindings

Roblox provides default input bindings for movement, camera control, and basic environment interaction — Roblox players are familiar with these controls, so you should only override them in specific cases. Also note that the **reserved** inputs cannot be overridden and will always operate with their intended purpose.

#### Roblox Reserved

| Action | Mouse/Keyboard | Gamepad | Touch |
| --- | --- | --- | --- |
| Open Roblox menu | `Esc` | `Start` button (`Enum.KeyCode\|ButtonStart`) | N/A |
| [Developer Console](/docs/en-us/studio/developer-console.md) | `F9` | N/A | N/A |
| Fullscreen mode (Windows)<br>Show desktop (Mac) | `F11` | N/A | N/A |
| Record video (Windows) | `F12` | N/A | N/A |
| Take screenshot | `PrintScreen` | N/A | N/A |

#### Character

| Action | Mouse/Keyboard | Gamepad | Touch |
| --- | --- | --- | --- |
| Move forward | `W` `↑` | Press up on primary thumbstick | Press up on virtual thumbstick |
| Move backward | `S` `↓` | Press down on primary thumbstick | Press down on virtual thumbstick |
| Move left | `A` | Press left on primary thumbstick | Press left on virtual thumbstick |
| Move right | `D` | Press right on primary thumbstick | Press right on virtual thumbstick |
| Jump | `Space` |   | Tap virtual jump button |

#### Interface / Inventory

> **Info:** The following action inputs are reserved unless you [disable the respective feature](/docs/en-us/players/disable-ui.md).

| Action | Mouse/Keyboard | Gamepad | Touch |
| --- | --- | --- | --- |
| Open text chat | `/` | N/A | N/A |
| Show/hide players list | `Tab` | N/A | N/A |
| Toggle backpack | ``` | N/A | N/A |
| Equip/unequip tools | `0`-`9` | Swap between tools using front‑left and front‑right triggers (`Enum.KeyCode.ButtonL1\|ButtonL1` and `Enum.KeyCode.ButtonR1\|ButtonR1`) | Tap on-screen tool icons |
| Use equipped tool | Click left mouse button | Back‑right trigger (`Enum.KeyCode.ButtonR2\|ButtonR2`) | Tap on screen |
| Drop equipped tool | `Backspace` | N/A | N/A |
| Toggle **UI selection** mode¹ | `\` | `Select` button (`Enum.KeyCode.ButtonSelect\|ButtonSelect`) | N/A |
| Navigate among interactive UI elements while in **UI selection** mode | `↑` `↓` `←` `→`<br>`W` `S` `A` `D` | Primary thumbstick (`Enum.KeyCode.Thumbstick1\|Thumbstick1`) or D‑pad (`Enum.KeyCode.DPadUp\|DPadUp`; `Enum.KeyCode.DPadDown\|DPadDown`; `Enum.KeyCode.DPadLeft\|DPadLeft`; `Enum.KeyCode.DPadRight\|DPadRight`) | |
| Activate an interactive UI element while in **UI selection** mode | `Enter` | Back‑right trigger (`Enum.KeyCode.ButtonR2\|ButtonR2`) | |
| Scroll up/down/left/right in selected `Class.ScrollingFrame` while in **UI selection** mode | `PageUp`<br>`PageDown`<br>`Home`<br>`End` | Secondary thumbstick (`Enum.KeyCode.Thumbstick2\|Thumbstick2`) | |

_¹ If `Class.GuiService.GuiNavigationEnabled|GuiNavigationEnabled` is enabled (default)_

#### Camera

| Action | Mouse/Keyboard | Gamepad | Touch |
| --- | --- | --- | --- |
| Move camera view around | While holding right mouse button | Move secondary thumbstick | Touch-drag around screen |
| Zoom camera in/out | Mouse scroll wheel<br>`I`/`O` | Press secondary thumbstick | Pinch in/out on screen |
| Rotate camera left or right | `←` `→` | N/A | N/A |
| Toggle mouse lock² | `Shift` | N/A | N/A |

_² If `Class.StarterPlayer.EnableMouseLockOption|EnableMouseLockOption` is enabled (default)_