Gamepad Virtual Cursor: APIs

Virtual Cursor Update: APIs!


Do you have a complex, mouse-driven UI in your game, that doesn’t work as well on a gamepad? Our solution, the Gamepad Virtual Cursor, just got even better!

We’re excited to bring you the next major update for Virtual Cursor: APIs! Through the API, developers are given additional options to set the state of the Virtual Cursor within code. This API includes:

  • Toggle the Virtual Cursor On/Off
    • Example - turn on when a popup UI appears, turn off after a selection is made
  • Specify a starting UI object/location when Virtual Cursor when appears
    • If no start object is specified, the cursor starts in the default starting location
  • Query the current state of the Virtual Cursor
  • Combine Virtual Cursor with the default UI selection (highlight) mode
    • Using the API, developers can use Virtual Cursor in specific menus/UI’s and the default UI selection mode everywhere else
  • Several bug fixes and smaller improvements (details below)

Demo Example


VCAPI_Menu_Example.rbxl (40.1 KB)

Previous Posts


Functions

EnableGamepadCursor

GamepadService:EnableGamepadCursor(guiObject: Instance)

For any situation where the cursor starts, it fires a property changed signal on GamepadCursorEnabled.

Input: (guiOjbect: Instance) Cursor Starting Position
nil Default position.
Not a GuiObject Cursor does not appear, errors.
Not a child of BasePlayerGui Cursor does not appear, errors.
GuiObject has Visible set to false or any parent visible set to false. Default position with warning.
Child of ScreenGui with Enabled set to false Default position with warning.
Child of BillboardGui or SurfaceGui Default position with warning.
GuiObject outside the viewport (Or, any part of the gui object that’s off screen) Default position with warning.
Child of ScrollingFrame with clipping set to false: GuiObject outside of scrolling frame (Object child of scrolling frame and not visible on screen) Default position with warning.
Child of ScrollingFrame with clipping set to true: GuiObject outside scrolling frame window but inside viewport GuiObject moves into the scrolling frame and starts the cursor centered over the object.
GuiObject inside the frame and visible Cursor starts centered on the GuiObject.

If the cursor is already active, calling EnableGamepadCursor again will reposition the cursor over that object (if it is valid). If it isn’t valid, it will print the same warning and the cursor will not move position.

DisableGamepadCursor

GamepadService:DisableGamepadCursor()

Turns off the Virtual Cursor if it is on and fires a property changed signal on GamepadCursorEnabled


Property

GamepadCursorEnabled: True when the gamepad cursor is active, false otherwise


Code Examples:

Example 1: Basic toggle


In this example, the user must press buttonX on a gamepad to enable the cursor on the specified UI button and press buttonY to disable the cursor. Paste this into a LocalScript that is a child of a GuiObject (TextButton, ImageButton, etc) under StarterGui.

-- In a LocalScript:
local GamepadService = game:GetService("GamepadService")
local UserInputService = game:GetService("UserInputService")
local button = script.Parent

UserInputService.InputBegan:Connect(function(input, processed)
	if input.KeyCode == Enum.KeyCode.ButtonX then
		GamepadService:EnableGamepadCursor(button)
	end
end)

UserInputService.InputBegan:Connect(function(input, processed)
	if input.KeyCode == Enum.KeyCode.ButtonY then
		GamepadService:DisableGamepadCursor()
	end
end)

Example 2: Start Virtual Cursor on popup


This example starts the Virtual Cursor when a popup appears. Try it out here!
VCAPI_Menu_Example.rbxl (40.1 KB)

This LocalScript under the TextLabel in StarterGui waits for the user to press ButtonX on their gamepad. It then enables the menu and positions the Virtual Cursor over the cancel button.

-- In a LocalScript:
local GamepadService = game:GetService("GamepadService")
local UserInputService = game:GetService("UserInputService")
local button = script.Parent
local teleportMenu = button.Parent.TeleportMenu
local buttonCancel = teleportMenu.Cancel

UserInputService.InputBegan:Connect(function(input, processed)
	if input.KeyCode == Enum.KeyCode.ButtonX then
		teleportMenu.Visible = true
		button.Visible = false
		GamepadService:EnableGamepadCursor(buttonCancel)
	end
end)

When the cancel button is activated, the menu closes and the Virtual Cursor disappears.

-- In a LocalScript
local GamepadService = game:GetService("GamepadService")
local button = script.Parent
local teleportMenu = button.Parent.Parent.TextLabel

button.Activated:Connect(function(obj, num)
	teleportMenu.Visible = true
	button.Parent.Visible = false
	GamepadService:DisableGamepadCursor()
end)

How to Turn On the Virtual Cursor

Use the property on StarterGui called VirtualCursorMode, to opt-in to the Virtual Cursor!

This property includes three settings:

  • Disabled - turns off the Virtual Cursor and uses the current UI navigation behavior
  • Enabled - turns on the Virtual Cursor
  • Default - this is currently set as “Disabled”

image

Set the Virtual Cursor “ Enabled ” to allow your players to use this feature.


Additional Fixes & Improvements

  • TextBox support
  • Virtual Cursor will toggle back on if it was active
    • The new flow is: Virtual Cursor on → other input (keyboard/mouse/etc) disables it → gamepad input → Virtual Cursor will toggle back on
  • Virtual Cursor triggers mouse events
    • Mouse move/enter/leave will fire from left thumbstick inputs
    • Mouse down/up/click/etc will fire from buttonA inputs
    • Suports dragging, billboard and surfacegui, click detector, various API’s
  • Virtual Cursor moves to the bottom of the screen correctly
  • Virtual Cursor can interact with proximity prompts
  • Virtual Cursor is able to equip and activate tools
  • Virtual Cursor can scroll frames with right thumbstick
  • Virtual Cursor doesn’t show the scroll icons if it cannot scroll in that direction

Known Issues:

  • Virtual Cursor APIs not currently active for version of Roblox that is downloaded from the Windows Store
  • The starting position for the Virtual Cursor is slightly off on XBox.

Feedback

The API was the top request we received from the community on this feature.

If you have additional feedback or issues, please reply with the details in a comment on this post. Also, if you enable the Virtual Cursor in your experience, please leave a link to it below as we’d like to test it out in your game!

We are particularly interested in hearing whether you were interested in this feature, but didn’t have enough control over it, and the API now suits your needs.

Your feedback will help us continually improve this feature.

107 Likes

This topic was automatically opened after 11 minutes.

Thank you so much. It’s truly amazing to see Roblox listen to the community. Please keep rolling out features to support XBox and Mobile! Is this automatically possible in every experience or is it to be rolled out?

5 Likes

Hey! Virtual Cursor is only available in experiences that opt in, the steps to do that are here: https://devforum.roblox.com/t/gamepad-virtual-cursor-apis/1798094#how-to-turn-on-the-virtual-cursor-11

5 Likes

I originally stopped using the virtual cursor because of the plethora of issues and barren desert of API that paired with it. These new changes are now kept into consideration when working with console user interface!

2 Likes

Are there any plans to allow customization of the appearance of the cursor? I think in some cases it can be a bit too big - like when trying to use it on a color wheel, for example, the giant circle of darkness kind of detracts from the color that you’re trying to hover over. I’d like to be able to shrink it down as you’re using the color wheel and then scale it back up once you’re done.

6 Likes

sweet now console players no longer have to struggle

2 Likes

OMG Wow! This will make Bloxy Kart’s upcoming Xbox Support even better. Were being spoiled with Roblox updates!

2 Likes

This seems like a major problem since code will error until these apis are enabled for everyone, may be worth requesting people to pcall these methods until then…

2 Likes

When will this get fixed?
image

If you put the virtual cursor over the topbar, you get that warning and you cant click any gui in that area. (The core topbar buttons do work though)

Also, seems like enabling the cursor instantly creates an error.

2 Likes

Seems like minimal changes but i wish there was API to make Gamepad Cursor locking on Textbox because my Controller is PS3 (DualShock type) and the cam wasn’t moving smoothly but instead moving so fast.

2 Likes

I love it, as someone who has fairly complex GUIs, setting it up to work with controllers properly takes a good chunk of time. I wanted to use the virtual cursor but wasn’t sure as it sometimes would stay active after the users left the menu (as there wasn’t the option to toggle it manually) or it wouldn’t appear so the users wouldn’t be able to do anything. The problem is that these 2 problems were being perceived as bugs when it reality they were not. Will definitely use it now, keep up the great work.

2 Likes

Hey! Glad you’re using virtual cursor now. Link your game here please!

1 Like

They won’t error on that platform, calling the APIs error will temporarily produce a warning until the issue can be fixed.

2 Likes

Can we have a way to keep the virtual cursor always enabled?

I know that you can just enable the cursor in a RenderStepped loop, but it feels rather hacky.

I want the player to always use the virtual cursor, and make it so pressing the Back button on the gamepad does not go back to the normal cursor.

EDIT: You can already do this:

game.GuiService.AutoSelectGuiEnabled = false
game.GamepadService:EnableGamepadCursor(nil)
1 Like

Hey, can you provide a screenshot for this please?

1 Like

Can you give a bit more detail for what’s going wrong? Thanks

1 Like

It’s just that it can be a bit distracting and in your face when hovering over UI elements that are a lot smaller than the virtual cursor circle. An easy solution here would be to just scale up the color wheel, but I can think of other situations where I’d like to be able to dynamically scale the cursor up and down. Using a slider, for example, would look a lot smoother to me if I could just shrink the cursor down as you enter the bounds of the element rather than having a giant circle 4x the size of the slider notch.

I feel like I’d be able to create a smoother experience while having to make minimal changes to the UI itself if I were able to do this. The UI below is from a game in which the UI already existed for ages before they decided to add console compatibility. Being able to scale the cursor down dynamically would at the very least allow me a transitional time in which I can replace the older UI with a better design that’d make more sense with a controller.

image

3 Likes

I was waiting for this update and its exciting that its finally here! : )

2 Likes

Are there plans to do something with the gamepad highlight? I personally would like to see it removed when using the virtual cursor, because it really gets in the way of custom hover effects and other things, and it generally doesn’t look very good.
image

2 Likes