mcpField
R
roblox-input

roblox-input

github.com/el4cteoDevelopment61577 installsUpdated 2w ago
Repository

About roblox-input

A Roblox development skill covering input handling and cameras, aimed at developers building gameplay controls across devices. It explains the recommended Input Action System alongside lower-level and legacy alternatives, plus camera implementation and cross-platform checks.

Key features

  1. 01Cross-device Input Action System
  2. 02Raw input and legacy bindings
  3. 03Input contexts and action states
  4. 04Device-aware control prompts
  5. 05Custom camera update patterns
  6. 06Cross-platform testing checklist

Use cases

  1. 01Building keyboard, gamepad, and touch controls
  2. 02Switching control schemes for menus or vehicles
  3. 03Displaying prompts for the active device
  4. 04Implementing a custom camera or screen-to-world ray

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/el4cteo/roblox-skills --skill roblox-input

After installing, type/roblox-inputin Claude Code to confirm it loaded.

Details

From the project README

Roblox input and camera

Choose an approach

ApproachUse when
Input Action System (InputContext → InputAction → InputBinding)New gameplay controls. Cross-device bindings configured as instances, contexts you enable/disable, built-in on-screen button binding, prompt display. Recommended.
UserInputService eventsRaw input, text-free hotkeys, mouse position/delta, touch gestures, device detection.
ContextActionService:BindActionLegacy/simple bind-with-mobile-button; existing code.

All input handling is client-side. Send intent to the server via remotes; the server validates.

Input Action System

Structure (typically in ReplicatedStorage.Inputs, or created from a client script):

Inputs (Folder)
  PlayContext (InputContext, Priority 1000)      -- gameplay controls
    Sprint (InputAction, Type = Bool)
      Keyboard (InputBinding, KeyCode = LeftShift)
      Gamepad  (InputBinding, KeyCode = ButtonL3)
      Touch    (InputBinding, UIButton = <on-screen TextButton>)
  MenuContext (InputContext, Priority 2000, Sink = true, Enabled = false)
  • InputAction.Type: Bool (press/release), Direction1D (triggers, zoom), Direction2D (move, camera), Direction3D (flying), ViewportPosition (pointer position).
  • Events: Pressed, Released (Bool only), StateChanged(value) for every type. action:GetState() reads the current value.
  • InputBinding fields: KeyCode; composite directions Up/Down/Left/Right/Forward/Backward; Scale (e.g. 0.01 for MouseDelta/TouchDelta); PressedThreshold/ReleasedThreshold for analog triggers; PrimaryModifier/SecondaryModifier for chords (Ctrl+S); UIButton to drive the action from a GUI button; DisplayName/DisplayImage for prompts.
  • InputContext.Enabled switches whole control schemes (gameplay ↔ menu ↔ vehicle); Priority + Sink lets a higher context consume keys so lower contexts don't also fire.
  • Set Workspace.PlayerScriptsUseInputActionSystem = Enabled to have Roblox's default player/camera scripts use the system too (required for server authority).
--!strict
-- Client: build a Sprint action in code and react to it.
local Players = game:GetService("Players")

local player = Players.LocalPlayer

local context = Instance.new("InputContext")
context.Name = "PlayContext"
context.Priority = 1000

local sprint = Instance.new("InputAction")
sprint.Name = "Sprint"
sprint.Type = Enum.InputActionType.Bool
sprint.Parent = context

local keyboard = Instance.new("InputBinding")
keyboard.KeyCode = Enum.KeyCode.LeftShift
keyboard.Parent = sprint

local gamepad = Instance.new("InputBinding")
gamepad.KeyCode = Enum.KeyCode.ButtonL3
gamepad.Parent = sprint

context.Parent = player:WaitForChild("PlayerScripts")

local function setSprinting(on: boolean)
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.WalkSpeed = if on then 24 else 16 -- server should validate/own real speed limits
	end
end

sprint.Pressed:Connect(function()
	setSprinting(true)
end)
sprint.Released:Connect(function()
	setSprinting(false)
end)

Show the right key/button: an InputActionLabel (beta) auto-renders the binding for the current device, or read action.PreferredBinding (+ its DisplayName/KeyCode) and UserInputService:GetStringForKeyCode / GetImageForKeyCode, updating on GetPropertyChangedSignal("PreferredBinding").

UserInputService essentials

--!strict
local UserInputService = game:GetService("UserInputService")

UserInputService.InputBegan:Connect(function(input: InputObject, gameProcessedEvent: boolean)
	if gameProcessedEvent then
		return -- typing in a TextBox, clicking UI, or a core-script action consumed it
	end
	if input.KeyCode == Enum.KeyCode.E then
		print("interact")
	elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
		print("click at", input.Position)
	end
end)

local function onPreferredInputChanged()
	local preferred = UserInputService.PreferredInput -- KeyboardAndMouse | Touch | Gamepad
	print("show prompts for", preferred)
end
UserInputService:GetPropertyChangedSignal("PreferredInput"):Connect(onPreferredInputChanged)
onPreferredInputChanged()
  • Always honor gameProcessedEvent or players trigger abilities while typing in chat.
  • PreferredInput reflects what the player is actually using (phone + Bluetooth gamepad → Gamepad); don't branch on TouchEnabled/KeyboardEnabled alone.
  • Mouse: UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter for FPS (set every frame while in first person if other scripts may reset it), GetMouseLocation() (includes top-bar inset), MouseDeltaSensitivity, MouseIconEnabled.
  • Gamepad: GetConnectedGamepads, GamepadConnected/Disconnected, thumbstick input.Position in InputChanged (apply a dead zone ≈ 0.15). Haptics: HapticService / HapticEffect.
  • Touch: TouchTap, TouchLongPress, TouchPinch, TouchSwipe; hide default controls only if you replace them (GuiService.TouchControlsEnabled).
  • Reserved keys you can't override: Esc/Start (menu), F9 (console), F11, F12, PrintScreen; chat /, Tab (player list), backpack and tool-number keys unless you disable those core features.

ContextActionService (legacy-compatible)

ContextActionService:BindAction(name, handler, createTouchButton, ...inputs) with handler (actionName, inputState, inputObject) -> Enum.ContextActionResult?; return Pass to let other bindings see the input. Use BindActionAtPriority for ordering and UnbindAction when the context ends (e.g. tool unequipped). Prefer the Input Action System for new work.

Custom cameras

--!strict
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local camera = workspace.CurrentCamera
local OFFSET = Vector3.new(0, 30, 20)

camera.CameraType = Enum.CameraType.Scriptable

RunService:BindToRenderStep("TopDownCamera", Enum.RenderPriority.Camera.Value + 1, function()
	local character = Players.LocalPlayer.Character
	local root = character and character:FindFirstChild("HumanoidRootPart") :: BasePart?
	if root then
		local target = root.Position
		camera.CFrame = CFrame.lookAt(target + OFFSET, target)
	end
end)

-- Restore: RunService:UnbindFromRenderStep("TopDownCamera"); camera.CameraType = Enum.CameraType.Custom
  • Update cameras in BindToRenderStep (runs before render, ordered), not Heartbeat/task.wait loops.
  • Smooth with camera.CFrame:Lerp(goal, 1 - math.exp(-speed * deltaTime)) (frame-rate independent).
  • First person: player.CameraMode = Enum.CameraMode.LockFirstPerson; zoom limits with player.CameraMinZoomDistance/CameraMaxZoomDistance. Shake: offset the CFrame, don't move parts.
  • Screen → world: camera:ViewportPointToRay(x, y) / ScreenPointToRay + workspace:Raycast.

Cross-platform checklist

  • Every action has keyboard, gamepad, and touch bindings (touch via UIButton or on-screen buttons).
  • Prompts/hints update when PreferredInput changes. Console UI is navigable with D-pad and closes with B.
  • No hover-only interactions (touch has no hover). Hold-to-confirm for destructive actions.
  • Test in Studio's Device Simulator (touch hints included) and Controller Emulator.

Related skills

roblox-ui (buttons, gamepad selection), roblox-characters-animation (movement, abilities), roblox-networking (sending intents), roblox-physics (vehicles).

Comments

Markdown supported