Source: Roblox Creator Hub · CC BY 4.0 · View source · Code samples: MIT Imported 2026-10-03. Formatting adapted for this site.
Detect user input
Connecting user input to actions gives users much better and more intuitive control over your game's features. In this tutorial, you will bind a reloading action to a specific key.
Get started
This tutorial uses the Blaster tool created in Create Player Tools. You can follow those instructions to create the tool or you can download the Blaster model and insert it into StarterPack.
Models can be added into your Inventory to be used between any game. To add a model to your game:
- In a browser, open the model page, click the Get button. This adds the model into your inventory.
- From Studio's Window menu or Home tab toolbar, open the Toolbox and select the Inventory tab.
- Make sure the dropdown is on My Models.
- Select the Blaster model to add it into the game.
Create an action handler
First, you'll need a function to handle when user input is detected.
Open the ToolController
LocalScriptinside of the Blaster.
Make a variable to store a name for the action.
local tool = script.Parent local RELOAD_ACTION = "reloadWeapon" local function toolEquipped() tool.Handle.Equip:Play() end local function toolActivated() tool.Handle.Activate:Play() end tool.Equipped:Connect(toolEquipped) tool.Activated:Connect(toolActivated)Create a function named onAction that receives three arguments:
actionName,inputState, andinputObject. This will be the function that runs when user input is detected.local tool = script.Parent local RELOAD_ACTION = "reloadWeapon" local function onAction(actionName, inputState, inputObject) end local function toolEquipped() tool.Handle.Equip:Play() endInside the function, check that the given
actionNamematches the reload action name and make sureinputStateisUserInputState.Begin(the beginning state). This is important because the function will run every time theinputStatechanges, but the reload only needs to happen once.local function onAction(actionName, inputState, inputObject) if actionName == RELOAD_ACTION and inputState == Enum.UserInputState.Begin then end endTo make it obvious when the user reloads, change the
TextureIdof the tool to"rbxassetid://6593020923"for a moment, and then change it back to its original value of"rbxassetid://92628145".local function onAction(actionName, inputState, inputObject) if actionName == RELOAD_ACTION and inputState == Enum.UserInputState.Begin then tool.TextureId = "rbxassetid://6593020923" task.wait(2) tool.TextureId = "rbxassetid://92628145" end end
Bind the action
ContextActionService can be used to bind a function to a specific input by using the BindAction function, which accepts several arguments:
- The name of the action.
- The function to handle the action (also called a "callback").
- Whether or not a touchscreen button should be displayed.
- Any amount of
Enum.KeyCodesto detect and associate with the action.
KeyCodes are values that represent different input buttons, such as keyboard keys or controller buttons. A full list of codes is available here.
Get
ContextActionServiceat the top of the script.local ContextActionService = game:GetService("ContextActionService") local tool = script.Parent local RELOAD_ACTION = "reloadWeapon"Inside of the
toolEquippedfunction, callBindActionand pass through the following arguments:- The name of the action (
RELOAD_ACTION) - The action handler (
onAction) - A value to create a touch button (
true) - A key press to detect (
KeyCode.R)
local RELOAD_ACTION = "reloadWeapon" local function onAction(actionName, inputState, inputObject) if actionName == RELOAD_ACTION and inputState == Enum.UserInputState.Begin then tool.TextureId = "rbxassetid://6593020923" task.wait(2) tool.TextureId = "rbxassetid://92628145" end end local function toolEquipped() ContextActionService:BindAction(RELOAD_ACTION, onAction, true, Enum.KeyCode.R) tool.Handle.Equip:Play() end- The name of the action (
Playtest by equipping the tool and pressing the R key on your keyboard. The backpack icon should momentarily change to a waiting symbol to signal that the weapon is reloading:
Unbind the action
When the user unequips the tool, the action needs to be unbound so they can't reload without the tool being equipped.
Create a new function called
toolUnequippedand callUnbindAction, passing through the action name.local function toolEquipped() ContextActionService:BindAction(RELOAD_ACTION, onAction, true, Enum.KeyCode.R) tool.Handle.Equip:Play() end local function toolUnequipped() ContextActionService:UnbindAction(RELOAD_ACTION) end local function toolActivated() tool.Handle.Activate:Play() end tool.Equipped:Connect(toolEquipped) tool.Activated:Connect(toolActivated)Connect the
toolUnequippedfunction to theUnequippedevent so the function will run when the event fires.local ContextActionService = game:GetService("ContextActionService") local tool = script.Parent local RELOAD_ACTION = "reloadWeapon" local function onAction(actionName, inputState, inputObject) if actionName == RELOAD_ACTION and inputState == Enum.UserInputState.Begin then tool.TextureId = "rbxassetid://6593020923" task.wait(2) tool.TextureId = "rbxassetid://92628145" end end local function toolEquipped() ContextActionService:BindAction(RELOAD_ACTION, onAction, true, Enum.KeyCode.R) tool.Handle.Equip:Play() end local function toolUnequipped() ContextActionService:UnbindAction(RELOAD_ACTION) end local function toolActivated() tool.Handle.Activate:Play() end tool.Equipped:Connect(toolEquipped) tool.Unequipped:Connect(toolUnequipped) tool.Activated:Connect(toolActivated)Playtest to confirm that everything works correctly. You should be able to reload when the tool is equipped, but not when it is unequipped.
Your reloading animation is now complete - for an extra challenge, try counting down an ammo counter each time the blaster is fired. You can then deactivate the toolActivated function when the gun has no ammo, then reactivate it once the reload animation is finished.