How to disable character movement while gamepad is navigating a GUI?

I have a GUI with a horizontal list of items controlled by a UIPageLayout. When the menu opens I use GuiService:AddSelectionParent(“CharacterMenu”, characterFrame) to indicate that the gamepad navigation should only be able to switch between the buttons in characterFrame, and I set GuiService.SelectedObject to one of the children.

image

When I use the left thumbstick, I want it to simply move between the selected items. However, it also has the side effect of moving my avatar in the game. How do I disable character movement? Setting WalkSpeed to 0 seems like a hack.

It might be a quirk of UIPageLayout, but I also have to move the left thumbstick 100% to the left or right and hold for a second before it starts paging through items, and it when it starts cycling, it cycles really quickly.

1 Like

The easiest solution would be to use the “hack” of setting the WalkSpeed of the player’s character to 0 or even anchoring the HumanoidRootPart of the player’s character.

Or you could disable the ControlScript then re-enable it once you want movement back.

Pretty sure you could go the extra mile and use some functions built in to the MasterControl Module of the ControlScript.
image

If you do end up require()ing the MasterControl module, the functions are :Enable() and :Disable()

2 Likes

I get the DevComputerMovementMode and DevTouchMovementMode properties of the Player instance and set them to scriptable.

Might not be the best way but it works the best for me, plus if you still need it, you can still script the WalkToPoint property and it will work.

1 Like

Disabling MasterControl has a small caveat: if you run any other logic depending on the movement vector you get out of MasterControl, then this won’t work anymore as it will always return (0,0,0) while you have it disabled even when pressing WASD / thumbstick / arrow keys / touch stick. This may or may not be a problem for your use case.

If you are not using MasterControl in your game at all, then it is still the best solution to toggle MasterControl via :Disable() / :Enable().

These two properties of player might be what you’re looking for. I’d set them to Scriptable of their respective enumerations.

http://wiki.roblox.com/index.php?title=API:Class/Player/DevComputerMovementMode
http://wiki.roblox.com/index.php?title=API:Class/Player/DevTouchMovementMode

You can’t actually set these on run-time, they require identity 5. Not sure why it’s not marked as such on the wiki.

16:46:03.813 - Insufficent permissions to set DevComputerMovementMode
16:46:03.813 - The current identity (2) cannot setDevComputerMovementMode (requires 5)

It’ll work fine in Play Solo but not in Test Server or live servers.

I can’t remember what I was doing in my game, but I think you can just unbind the left thumbstick’s action for character movement, then rebind it when you need to move again.

If the API Dump doesn’t report the distinction, then the wiki doesn’t realize it needs to have this flag. They probably hard coded the check on the C++ end.

Also @Merely, I think you can utilize the ContextActionService priority system to stop the inputs going through.

local ContextActionService = game:GetService("ContextActionService")

local function blockInput(actionName, inputState, inputObject)
	inputObject.UserInputState = Enum.UserInputState.Cancel
	return Enum.ContextActionResult.Pass
end

ContextActionService:BindActionAtPriority("StopMovement",blockInput,false,30000,
	-- Keyboard Inputs
	Enum.PlayerActions.CharacterForward,
	Enum.PlayerActions.CharacterBackward,
	Enum.PlayerActions.CharacterLeft,
	Enum.PlayerActions.CharacterRight,
	Enum.PlayerActions.CharacterJump,
	
	-- Shift Lock Inputs
	Enum.KeyCode.LeftShift,
	Enum.KeyCode.RightShift,

	-- Gamepad Inputs
	Enum.UserInputType.Gamepad1,
	Enum.UserInputType.Gamepad2,
	Enum.UserInputType.Gamepad3,
	Enum.UserInputType.Gamepad4
)

This is a bit of a mouth full, but it works.

7 Likes

You could also modify MasterControl's updateMovement function to check for GuiService.SelectedObject. This will work without having to run any code when you enter/exit Gui selection.

Here is some example code I tested. It required only 5 lines added to MasterControl.

The gist is that you intercept MasterControl right before it sends controls to the character and tell it “nothing is being pressed, there is no movement”.