Source: Roblox Creator Hub · CC BY 4.0 · View source · Code samples: MIT Imported 2026-10-03. Formatting adapted for this site.
Input Action System
The cross-platform Input Action System lets you connect actions and arrange bindings across various hardware inputs at edit time. Combined with 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 InputContext is a collection of actions which holds related input actions, for example PlayContext for in‑game character controls and NavContext for controls to navigate around UI menus. You can enable/disable contexts (and their corresponding actions) through their 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 a game 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.
Create a Folder named Inputs inside ReplicatedStorage to hold various input contexts.

Insert a new
InputContextinto the folder and rename it toPlayContext.
In the Properties window, set Priority to 2000 and enable Sink. A context with Sink enabled consumes input events for its bound 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 Priority to sink its bound inputs before the default PlayerScripts contexts process them.

Input actions
An InputAction defines a gameplay action mechanic such as "Jump," "Sprint," or "Shoot." These actions are then mapped to hardware inputs using input bindings.
An InputAction can be of several variations depending on its Type property (InputActionType). The default is Bool, designed to receive true/false values from press/release of inputs such as ButtonA, E, or MouseLeftButton.
Note
InputAction also exposes a read-only PreferredBinding property that returns the child InputBinding best matching the player's current input device (keyboard/mouse, gamepad, or touch). It updates dynamically as the player's device configuration changes and is the basis for displaying bindings to players.
| Input Action Type | Example Usage |
|---|---|
| [`Bool`](/docs/enum-inputactiontype) | Triggered actions such as jump, shoot, sprint, etc. with support for pressed/released thresholds on analog inputs. |
| [`Direction1D`](/docs/enum-inputactiontype) | Variable zero-to-full actions such as a car's accelerator pedal or a view scope's zoom level. |
| [`Direction2D`](/docs/enum-inputactiontype) | 2D directional movement such as camera rotation, or the standard Roblox character movement. |
| [`Direction3D`](/docs/enum-inputactiontype) | 3D directional movement like an airborne vehicle that can levitate up/down, accelerate/decelerate, and drift left/right. |
| [`ViewportPosition`](/docs/enum-inputactiontype) | 2D viewport coordinates like mouse input, such as for custom cursors or raycasting to select world objects. |
Character Sprint
To test an InputAction for simple character sprinting:
Select the top-level Workspace object in the Explorer and then, in the Properties window, set the PlayerScriptsUseInputActionSystem property to Enabled.
Create a new
InputActioninside thePlayContextcontext withinReplicatedStorage. Rename it toCharacterSprintto indicate its dedicated action.
In the Properties window, notice that the action's
TypeisBool(default). This is a logical type for simple character sprinting as a booleantrue/falseaction (character is either sprinting or not sprinting).
Camera Rotation
To test an InputAction for camera rotation:
Create a new
InputActioninside thePlayContextcontext withinReplicatedStorage. Rename it toCameraRotateto indicate its dedicated action.
In the Properties window, set the action's
TypetoDirection2D. This reflects that camera rotation is a continuous 2D analog input rather than a discrete press/release.
Input bindings
An InputBinding defines which hardware binding should trigger the parent InputAction, for example a key press, gamepad button, or tap on a touch‑enabled device. For cross‑platform compatibility, each InputAction should have an InputBinding for gamepad, keyboard/mouse, and touch as illustrated here.

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 ([`ButtonStart`](/docs/enum-keycode)) | N/A |
| [Developer Console](/docs/roblox-studio-developer-console) | F9 | N/A | N/A |
| Fullscreen mode (Windows) 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
Note
The following action inputs are reserved unless you disable the respective feature.
| 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 ([`ButtonL1`](/docs/enum-keycode#buttonl1) and [`ButtonR1`](/docs/enum-keycode#buttonr1)) | Tap on-screen tool icons |
| Use equipped tool | Click left mouse button | Back‑right trigger ([`ButtonR2`](/docs/enum-keycode#buttonr2)) | Tap on screen |
| Drop equipped tool | Backspace | N/A | N/A |
| Toggle **UI selection** mode¹ | \ | Select button ([`ButtonSelect`](/docs/enum-keycode#buttonselect)) | N/A |
| Navigate among interactive UI elements while in **UI selection** mode | ↑ ↓ ← → W S A D |
Primary thumbstick ([`Thumbstick1`](/docs/enum-keycode#thumbstick1)) or D‑pad ([`DPadUp`](/docs/enum-keycode#dpadup); [`DPadDown`](/docs/enum-keycode#dpaddown); [`DPadLeft`](/docs/enum-keycode#dpadleft); [`DPadRight`](/docs/enum-keycode#dpadright)) | |
| Activate an interactive UI element while in **UI selection** mode | Enter | Back‑right trigger ([`ButtonR2`](/docs/enum-keycode#buttonr2)) | |
| Scroll up/down/left/right in selected [`ScrollingFrame`](/docs/scrollingframe) while in **UI selection** mode | PageUp PageDown Home End |
Secondary thumbstick ([`Thumbstick2`](/docs/enum-keycode#thumbstick2)) |
¹ If 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 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 EnableMouseLockOption is enabled (default)
The Type assigned to the parent InputAction directly affects which general input types (key/button/tap, analog trigger, thumbstick, etc.) are valid for child InputBinding instances. In turn, values sent to the parent action's connected events depend on a binding's chosen input type. See input events for details on the correlation between action types, bindings, and return values.
Character Sprint
To hook up bindings for simple character sprinting:
Insert a new
InputBindinginto theCharacterSprintaction and rename it toKeyboardBinding. Then set the binding'sKeyCodeproperty toLeftShift.

Insert a second
InputBindinginto theCharacterSprintaction and rename it toGamepadBinding. Then set the binding'sKeyCodeproperty toButtonY.

Inside a
ScreenGuicontainer insideStarterGui, create an on-screen button, rename it toSprintButton, and position/resize it as desired.
Insert a third
InputBindinginto theCharacterSprintaction and rename it toTouchBinding. Then, in the Properties window, link the binding'sUIButtonproperty to theSprintButtonbutton you created previously insideStarterGui.

Camera Rotation
To hook up bindings for camera rotation:
Insert a new
InputBindinginto theCameraRotateaction and rename it toKeyboardBinding. LeaveKeyCodeempty and instead set the four composite directional properties —Left,Right,Up, andDown— toLeft,Right,Up, andDownrespectively.

Insert a second
InputBindingand rename it toGamepadBinding. Then set the binding'sKeyCodeproperty toThumbstick2(right thumbstick).

Insert a third
InputBindingand rename it toMouseBinding. Set the binding'sKeyCodeproperty toMouseDeltaand itsScaleto0.01.MouseDeltareports values in pixels, so the scale converts them to a reasonable rotation range.

Insert a fourth
InputBindingand rename it toTouchBinding. Set the binding'sKeyCodeproperty toTouchDeltaand itsScaleto0.01. LikeMouseDelta,TouchDeltareports values in pixels.

Input events
The InputAction instance has three built-in events to handle player input coming from InputBindings.
Pressed— This event fires only when the input action'sTypeis set toBool, and only when the state transitions fromfalsetotrue.Released— This event fires only when the input action'sTypeis set toBool, and only when the state transitions fromtruetofalse.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 Type (Bool, Direction1D, Direction2D, Direction3D, or ViewportPosition) and the general input type coming from a child InputBinding (key/button/tap, analog trigger, thumbstick, etc.), different values are returned to the Pressed, Released, and StateChanged event handlers. Examine the following tables to better understand the correlation.
Bool
The 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 [`InputBindings`](/docs/inputbinding) | Returned to the [`InputAction`](/docs/inputaction) Event(s) |
|---|---|
| Boolean inputs from keyboard keys or basic mouse/gamepad buttons through the binding's [`KeyCode`](/docs/inputbinding#inputbinding-keycode) property, or a [`GuiButton`](/docs/guibutton) press/release through the binding's [`UIButton`](/docs/inputbinding#inputbinding-uibutton) property. |
|
| Variable input amounts from analog inputs like gamepad triggers ([`ButtonL2`](/docs/enum-keycode#buttonl2)/[`ButtonR2`](/docs/enum-keycode#buttonr2)) through the binding's [`KeyCode`](/docs/inputbinding#inputbinding-keycode) property. |
|
Direction1D
The 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 [`InputBindings`](/docs/inputbinding) | Returned to the [`InputAction`](/docs/inputaction) Event(s) |
|---|---|
| Variable input amounts from analog inputs like gamepad triggers ([`ButtonL2`](/docs/enum-keycode#buttonl2)/[`ButtonR2`](/docs/enum-keycode#buttonr2)) through the binding's [`KeyCode`](/docs/inputbinding#inputbinding-keycode), [`Up`](/docs/inputbinding#inputbinding-up), and [`Down`](/docs/inputbinding#inputbinding-down) properties. |
|
| Boolean inputs from keyboard keys or basic mouse/gamepad buttons through the binding's [`KeyCode`](/docs/inputbinding#inputbinding-keycode), [`Up`](/docs/inputbinding#inputbinding-up), and [`Down`](/docs/inputbinding#inputbinding-down) properties. |
|
Direction2D
The Direction2D type is best for 2D directional movement such as camera rotation, or the standard Roblox character movement.
| Valid Input Types on [`InputBindings`](/docs/inputbinding) | Returned to the [`InputAction`](/docs/inputaction) Event(s) |
|---|---|
| Variable input amounts from 2D analog inputs like gamepad thumbsticks ([`Thumbstick1`](/docs/enum-keycode#thumbstick1)/[`Thumbstick2`](/docs/enum-keycode#thumbstick2)) through the binding's [`KeyCode`](/docs/inputbinding#inputbinding-keycode) property. |
|
| Variable input amounts from analog inputs like gamepad triggers ([`ButtonL2`](/docs/enum-keycode#buttonl2)/[`ButtonR2`](/docs/enum-keycode#buttonr2)) through the binding's [`Up`](/docs/inputbinding#inputbinding-up), [`Down`](/docs/inputbinding#inputbinding-down), [`Left`](/docs/inputbinding#inputbinding-left), and [`Right`](/docs/inputbinding#inputbinding-right) properties. |
|
| Boolean inputs from keyboard keys or basic mouse/gamepad buttons through the binding's [`Up`](/docs/inputbinding#inputbinding-up), [`Down`](/docs/inputbinding#inputbinding-down), [`Left`](/docs/inputbinding#inputbinding-left), and [`Right`](/docs/inputbinding#inputbinding-right) properties. |
|
Direction3D
The 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 [`InputBindings`](/docs/inputbinding) | Returned to the [`InputAction`](/docs/inputaction) Event(s) |
|---|---|
| Variable input amounts from analog inputs like gamepad triggers ([`ButtonL2`](/docs/enum-keycode#buttonl2)/[`ButtonR2`](/docs/enum-keycode#buttonr2)) through the binding's [`Up`](/docs/inputbinding#inputbinding-up), [`Down`](/docs/inputbinding#inputbinding-down), [`Left`](/docs/inputbinding#inputbinding-left), [`Right`](/docs/inputbinding#inputbinding-right), [`Forward`](/docs/inputbinding#inputbinding-forward), and [`Backward`](/docs/inputbinding#inputbinding-backward) properties. |
|
| Boolean inputs from keyboard keys or basic mouse/gamepad buttons through the binding's [`Up`](/docs/inputbinding#inputbinding-up), [`Down`](/docs/inputbinding#inputbinding-down), [`Left`](/docs/inputbinding#inputbinding-left), [`Right`](/docs/inputbinding#inputbinding-right), [`Forward`](/docs/inputbinding#inputbinding-forward), and [`Backward`](/docs/inputbinding#inputbinding-backward) properties. |
|
ViewportPosition
The 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 [`InputBindings`](/docs/inputbinding) | Returned to the [`InputAction`](/docs/inputaction) Event(s) |
|---|---|
| Variable input amounts from positional inputs such as a mouse pointer ([`MousePosition`](/docs/enum-keycode#mouseposition)) or touch ([`Touch`](/docs/enum-keycode)). |
|
Character Sprint
To connect events for simple character sprinting:
Insert a new
Scriptinto theCharacterSprinttree, alongside the various input bindings. Then set itsRunContexttoClientand rename it toOnActivate.
Paste the following code into the
OnActivatescript. Note thePressedevent connection on lines13‑15which doubles the character's walk speed when a sprint input binding is pressed, and the correspondingReleasedevent connection on lines16‑18which resets the walk speed to default when a sprint input binding is released.```lua title="OnActivate (Client Script)" 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) ```Playtest your game and test the character sprint action with the bindings you chose previously:
LeftShiftfor keyboard,ButtonYfor gamepad, and the on‑screenSprintButtonfor touch‑enabled devices. Remember that you can use the Controller Emulator to test gamepad inputs directly in Roblox Studio.
Camera Rotation
For continuous analog inputs like camera rotation, 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 GetState() each frame and multiply by delta time for frame-rate-independent behavior.
Insert a new
Scriptinto theCameraRotatetree, alongside the various input bindings. Then set itsRunContexttoClientand rename it toOnInput.
Paste the following code into the
OnInputscript.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 camera.CameraType = Enum.CameraType.Scriptable 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 such as PlayContext, you can enable/disable it during gameplay through scripting, change its Priority to determine which actions take precedence over others, and Sink inputs from being processed within contexts of lower priority.
To make it easier to switch contexts from other scripts, insert a new
BindableEventinto your inputs folder withinReplicatedStorageand rename it toContextEvent.
Create a new
Scriptat the same level, set itsRunContexttoClient, and rename it toUpdateContext.
Inside the
UpdateContextscript, paste the following code:```lua title="UpdateContext (Client Script)" 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) ```With the
UpdateContextscript in place, you can now update a namedInputContextby firing the bindable event, for example from aLocalScriptthat powers aGuiButtoninside aScreenGuicontainer.
```lua title="Button Script" 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) ```
Displaying bindings
Once you've set up actions and bindings, you'll typically need to show players, via on‑screen assistive hints, which key or button triggers each action:
Keyboard Input

Gamepad Input

The Input Action System provides two approaches:
InputActionLabel — A no-code, drag-and-drop GuiObject that automatically displays the correct input per platform.
PreferredBinding — A read-only InputAction property for creators who want full control over how bindings are displayed in custom UI.
InputActionLabel
Note
This class/object is currently in beta. Enable it through File 〉 Beta Features 〉 InputActionLabel.
InputActionLabel is a GuiObject that you can insert into any ScreenGui or SurfaceGui. Once its InputAction property is set to reference an existing InputAction instance, it automatically resolves and displays the correct keybinding for the player's current input device — no scripting required. When the player switches devices (for example, picking up a gamepad after using a keyboard) or rebinds a control, the label updates instantly.
To add an InputActionLabel:
Inside a
ScreenGuicontainer insideStarterGui, insert anInputActionLabeljust like any otherGuiObject.In the Properties window, set its
InputActionproperty to theInputActioninstance you want to display (for example, your "Sprint" action underReplicatedStorage) and position/resize it as desired.When the label resolves what to show, it checks the following in order:
Custom Images — If child
InputBindingshave theirDisplayImageproperty set, the label renders those images directly.Platform Key Images — Lacking custom images, the label renders platform-provided images for child
InputBindingsthroughUserInputService:GetImageForKeyCode(), if such images are available. Composite bindings with modifiers show multiple icons with+separators.Custom Names — Lacking available images, if child
InputBindingshave theirDisplayNameproperty set, the label renders that text using the label's style properties.Platform Key Strings — Lacking all of the above, the label renders platform-provided strings through
UserInputService:GetStringForKeyCode().If no
InputActionis assigned or no childInputBindingexists, the label renders a placeholder icon.
PreferredBinding
For customized use cases where you need full control over hint display (custom animations, conditional visibility, composited layouts), you can use InputAction.PreferredBinding to query the current binding and build your own UI. PreferredBinding is a read-only property that returns the child InputBinding which best matches the player's current input device.
The following two InputBinding properties provide the custom display overrides used for PreferredBinding. If neither is set, fall back to platform-provided values via GetStringForKeyCode() and GetImageForKeyCode().
DisplayName— A read/write string for custom text, for example, "Sprint."DisplayImage— A read/writeContentvalue for a custom image.
The following examples assume a client Script parented to the InputAction and a hint UI object (TextLabel or ImageLabel) inside a ScreenGui within the player's PlayerGui. Both connect to changes to PreferredBinding so that the hint refreshes whenever the player switches input devices.
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local inputAction = script.Parent
local player = Players.LocalPlayer
local screenGui = player:WaitForChild("PlayerGui"):WaitForChild("ScreenGui")
local label = screenGui:FindFirstChildWhichIsA("TextLabel")
local function updateHintText()
if not label then
warn("Label UI object not found!")
return
end
local binding = inputAction.PreferredBinding
if binding and binding.DisplayName ~= "" then
label.Text = binding.DisplayName
elseif binding and binding.KeyCode ~= Enum.KeyCode.None then
label.Text = UserInputService:GetStringForKeyCode(binding.KeyCode)
else
label.Text = ""
end
end
inputAction:GetPropertyChangedSignal("PreferredBinding"):Connect(updateHintText)
updateHintText()
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local inputAction = script.Parent
local player = Players.LocalPlayer
local screenGui = player:WaitForChild("PlayerGui"):WaitForChild("ScreenGui")
local label = screenGui:FindFirstChildWhichIsA("ImageLabel")
local function updateHintImage()
if not label then
warn("Label UI object not found!")
return
end
local binding = inputAction.PreferredBinding
if binding and binding.DisplayImage.SourceType ~= Enum.ContentSourceType.None then
label.ImageContent = binding.DisplayImage
elseif binding and binding.KeyCode ~= Enum.KeyCode.None then
local keyImage = UserInputService:GetImageForKeyCode(binding.KeyCode)
label.ImageContent = (keyImage ~= "") and Content.fromUri(keyImage) or Content.none
else
label.ImageContent = Content.none
end
end
inputAction:GetPropertyChangedSignal("PreferredBinding"):Connect(updateHintImage)
updateHintImage()
Input Action Manager
Note
This tool is currently in beta. Enable it through File 〉 Beta Features 〉 Input Action Manager.
The Input Action Manager tool is a unified, matrix-style interface to design, audit, and scale your input architecture.
To access it, navigate to the Window menu in Studio and select Input ⟩ Input Action Manager. If your game already uses input contexts, actions, or bindings, the manager will automatically scan the DataModel and extract those existing instances into the editor grid. Any new input‑related instances will automatically populate into an Inputs folder within ReplicatedStorage.

To configure an input setup for character sprint as outlined in the sections above:
Select the top-level Workspace object in the Explorer and then, in the Properties window, set the PlayerScriptsUseInputActionSystem property to Enabled.
Inside a
ScreenGuicontainer insideStarterGui, create an on-screen button, rename it toSprintButton, and position/resize it as desired.
In the Input Action Manager, hover over the Context column header and click the + button. Enter an appropriate name for the new context such as
PlayContextand press Enter. AnInputContextof the matching name appears inReplicatedStorage.

Hover over the new context and click the + button. From the popup menu, select
Bool, enterCharacterSprintfor the action's name, and press Enter. AnInputActionof the matching name appears under the context.

In the new
CharacterSprintrow, assign bindings for each input type:- Keyboard and Mouse — Click the arrow button and select
LeftShiftfrom the picker menu. - Touch — Click the cell and then, in the Explorer hierarchy, click the
SprintButtonobject that you previously inserted into theScreenGui. - Gamepad — Click the arrow button and select
ButtonYfrom the picker menu.

- Keyboard and Mouse — Click the arrow button and select
Note
As you assign bindings, watch for warning/error icons in the UI. Yellow warnings (⚠) indicate a missing binding for cross‑platform compatibility, while red warnings (⚠) indicate a duplicate binding for actions within the same context.
Insert a new
Scriptinto theCharacterSprinttree, alongside the various input bindings. Then set itsRunContexttoClientand rename it toOnActivate.
Paste the following code into the
OnActivatescript. Note thePressedevent connection on lines13‑15which doubles the character's walk speed when a sprint input binding is pressed, and the correspondingReleasedevent connection on lines16‑18which resets the walk speed to default when a sprint input binding is released.```lua title="OnActivate (Client Script)" 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) ```