Detecting User Input

Connecting user's input to actions gives users much better and more intuitive control over your experience's features. In this tutorial, you will bind a reloading action to a specific key.

Getting Started

This tutorial uses the Blaster tool created in Creating 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 experience. To add a model to your experience:

  1. In a browser, open the model page, click the Get button. This adds the model into your inventory.
  2. In Studio, go to the View tab and click on the Toolbox.
  3. In the Toolbox window, click on the Inventory button. Then, make sure the dropdown is on My Models.
  4. Select the Blaster model to add it into the experience.

Creating an Action Handler

First, you'll need a function to handle when user input is detected.

  1. Open the ToolController LocalScript inside of the Blaster.

    View of the Explorer where the ToolController script inside of the Blaster tool is selected

  2. Make a variable to store a name for the action.


    1local tool = script.Parent
    2
    3local RELOAD_ACTION = "reloadWeapon"
    4
    5local function toolEquipped()
    6 tool.Handle.Equip:Play()
    7end
    8
    9local function toolActivated()
    10 tool.Handle.Activate:Play()
    11end
    12
    13tool.Equipped:Connect(toolEquipped)
    14tool.Activated:Connect(toolActivated)
    15
  3. Create a function named onAction that receives three arguments: actionName, inputState, and inputObject. This will be the function that runs when user input is detected.


    1local tool = script.Parent
    2
    3local RELOAD_ACTION = "reloadWeapon"
    4
    5local function onAction(actionName, inputState, inputObject)
    6
    7end
    8
    9local function toolEquipped()
    10 tool.Handle.Equip:Play()
    11end
    12
  4. Inside the function, check that the given actionName matches the reload action name and make sure inputState is UserInputState.Begin (the beginning state). This is important because the function will run every time the inputState changes, but the reload only needs to happen once.


    1local function onAction(actionName, inputState, inputObject)
    2 if actionName == RELOAD_ACTION and inputState == Enum.UserInputState.Begin then
    3
    4 end
    5end
    6
  5. To make it obvious when the user reloads, change the TextureId of the tool to "rbxassetid://6593020923" for a moment, and then change it back to its original value of "rbxassetid://92628145".


    1local function onAction(actionName, inputState, inputObject)
    2if actionName == RELOAD_ACTION and inputState == Enum.UserInputState.Begin then
    3 tool.TextureId = "rbxassetid://6593020923"
    4 wait(2)
    5 tool.TextureId = "rbxassetid://92628145"
    6 end
    7end
    8

Binding 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.KeyCodes to 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.

  1. Get ContextActionService at the top of the script.


    1local ContextActionService = game:GetService("ContextActionService")
    2
    3local tool = script.Parent
    4
    5local RELOAD_ACTION = "reloadWeapon"
    6
  2. Inside of the toolEquipped function, call BindAction and 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)

    1local RELOAD_ACTION = "reloadWeapon"
    2
    3local function onAction(actionName, inputState, inputObject)
    4 if actionName == RELOAD_ACTION and inputState == Enum.UserInputState.Begin then
    5 tool.TextureId = "rbxassetid://6593020923"
    6 wait(2)
    7 tool.TextureId = "rbxassetid://92628145"
    8 end
    9end
    10
    11local function toolEquipped()
    12 ContextActionService:BindAction(RELOAD_ACTION, onAction, true, Enum.KeyCode.R)
    13 tool.Handle.Equip:Play()
    14end
    15
  3. 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:

Unbinding the Action

When the user unequips the tool, the action needs to be unbound so they can't reload without the tool being equipped.

  1. Create a new function called toolUnequipped and call UnbindAction, passing through the action name.


    1local function toolEquipped()
    2 ContextActionService:BindAction(RELOAD_ACTION, onAction, true, Enum.KeyCode.R)
    3 tool.Handle.Equip:Play()
    4end
    5
    6local function toolUnequipped()
    7 ContextActionService:UnbindAction(RELOAD_ACTION)
    8end
    9
    10local function toolActivated()
    11 tool.Handle.Activate:Play()
    12end
    13
    14tool.Equipped:Connect(toolEquipped)
    15tool.Activated:Connect(toolActivated)
    16
  2. Connect the toolUnequipped function to the Unequipped event so the function will run when the event fires.


    1local ContextActionService = game:GetService("ContextActionService")
    2
    3local tool = script.Parent
    4
    5local RELOAD_ACTION = "reloadWeapon"
    6
    7local function onAction(actionName, inputState, inputObject)
    8 if actionName == RELOAD_ACTION and inputState == Enum.UserInputState.Begin then
    9 tool.TextureId = "rbxassetid://6593020923"
    10 wait(2)
    11 tool.TextureId = "rbxassetid://92628145"
    12 end
    13end
    14
    15local function toolEquipped()
    16 ContextActionService:BindAction(RELOAD_ACTION, onAction, true, Enum.KeyCode.R)
    17 tool.Handle.Equip:Play()
    18end
    19
    20local function toolUnequipped()
    21 ContextActionService:UnbindAction(RELOAD_ACTION)
    22end
    23
    24local function toolActivated()
    25 tool.Handle.Activate:Play()
    26end
    27
    28tool.Equipped:Connect(toolEquipped)
    29tool.Unequipped:Connect(toolUnequipped)
    30tool.Activated:Connect(toolActivated)
    31
  3. 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.