Access to thumb-pad / D-pad controls

Hello, thanks for reading!

I’m trying to make my game mobile-compatible, and wish to use the ‘thumb-pad’ / ‘D-pad’. It shows natively when I log into my game on mobile, and works well. I also added some other buttons using the ContextActionService:BindAction by setting the 3rd argument to true.

This all works well. However, at some point I want to use that same control-pad-for-walking to do other things (controlling a car). I tried the following:

ContextActionService:BindAction(“SteerForward”, SteerForward, false, Enum.PlayerActions.CharacterForward)

ContextActionService:BindAction(“SteerForward2”, SteerForward, false, Enum.KeyCode.DPadUp)

ContextActionService:BindAction(“SteerForward3”, SteerForward, false, Enum.KeyCode.Thumbstick1)

But none of these work and capture the signal (I blocked control of the player’s humanoid by setting it to PlatformStand, but that doesn’t seem affect the issue)*.

My question:
Is there a way to capture input from that thumb-stick (and possibly the native jump button too)? Is there a Enum I can use to capture it with the ContextActionService? Or if not, should I maybe make a feature request?

And if all this is impossible, what would be the best/advised alternative to create a smooth movement-control mobile gui (separate, aswd-style buttons are not great for steering).

Sorry if I missed something obvious/simple here… Thanks a real bunch for any advice or help!

Kind regards,

*some last details: the Enum.KeyCode.Thumbstick1 sometimes receives the ‘cancelled’ event (input state), but I put it back at the top of the stack and still never receives any other event. Ideally I need the ‘Enum.UserInputState.Begin’ and ‘Enum.UserInputState.End’ events for each direction, though any axis/directional information would do, it doesn’t have to be through ContextActionService even. Thanks so much for any help!


To elaborate on what I have so far, I found two ways to do it, neither very optimal.

The first way is to simply get the screen-touch coordinates. This doesn’t read from the actual thumb-pad, but you might estimate where it is or simply make an alternative swipe-based interface:

--game:GetService("UserInputService").InputChanged:connect(function(input, processed)
  if input.UserInputType == Enum.UserInputType.Touch then

The second way is pretty hacky, copied and modified from Reddit:

local MasterControl = require(game.Players.LocalPlayer.PlayerScripts:WaitForChild("ControlScript"):WaitForChild("MasterControl"))
local Player = game.Players.LocalPlayer

local screen ="ScreenGui",Player:FindFirstChild("PlayerGui"))
local label ="TextLabel",screen)
label.Size =,200,0,40)
label.Position =,0,0.4,0)
label.TextScaled = true
label.Font = Enum.Font.SourceSans
label.Text = ""

    screen.Parent = Player:FindFirstChild("PlayerGui")

local function floatFormat(x,y)
    return string.format(y and "%."..y.."f" or "%f",x):reverse():match("^0*%.?(.+)$"):reverse()

while true do
    local move = MasterControl:GetMoveVector()
    label.Text = floatFormat(move.x,2)..", "..floatFormat(move.y,2)..", "..floatFormat(move.z,2)

It works though, even while in platformstand. But for how long, until that masterscript is again moved or changed? This is definitely hacky. Does anybody know a more professional way?

Thanks for reading!!


Playerscripts are being rewritten currently and will be released soonish as far as I understand. New playerscripts will break this method, but they will provide on official API to get move vector, which they intend to continue to support.

I would go ahead with the hacky method and just fix it when new playerscripts are released. It will be an easy 1 line change.


Great! Cause MoveDirection is in world coordinates and well, I took me a while to get to this point of understanding X) Though I’m slow. Thanks, it would be awesome to actually have stable public APIs for scripts like this, or just for access to the move vector after processing all sources (the ‘MoveValue variable’), and possibly even each individual input source.

EDIT: Solved, tl;dr: Just use Player.Character.Humanoid.MoveDirection instead, it’s connected to all input types. Or make your own thumb-pad, using ROBLOX’ example scripts.

The thumb-pad is simply created in the Player.PlayerScripts.ControlScript.MasterControl.Thumbstick script. It listens to Enum.UserInputType.Touch, and maps it onto the thumbstick GUI created there. Analogously, the equivalent keyboard control script listens to Enum.PlayerActions.CharacterForward etc. (So controlling the ContextActionService with the Thumb-pad would be the ‘wrong way’.)

In the end, the MasterControl script sends the MoveValue variable to the Player.Move() function. So I found that in the player’s humanoid, this value comes back as Humanoid.MoveDirection, even in Platform stand. Problem solved…!


A post was merged into an existing topic: Off-topic and bump posts