The Problem:
Virtual Cursor does not cooperate well with buttons inside of buttons.
In the repro I’ve provided, there’s a list of buttons on the left side of the screen controlled by a UIGridLayout. Two of these buttons have an additional ImageButton inside of them. This is selectable just fine on PC and mobile, but Virtual Cursor will skip over them or select the wrong one.
Changing the size of the UI or adding padding makes it slightly better, but does not actually fix it. I’d have to make every single UI element gigantic to get around this.
This issue occurs on all platforms; the only requirement for it to break is to use a controller and enable Virtual Cursor mode.
This issue isn’t just limited to UI Grid Layout. It seems to essentially be any nested layout recently where a button is within a button, regardless of z-index. And it previously wasn’t as prevalent as it has been the past week.
In our game we’ve had Sibling set for ScreenUI Zindex Behavior for a couple months now with just over 10% of console players from the tens of thousands that play daily (roughly 2K of those console), and they’ve only just started encountering virtual cursor issues with our existing menu on interacting with a UI Layout of image buttons in a frame atop a text button row for a list of items to equip in a scroll-frame. And it’s intermittent on the row and screen location as to whether it works correctly or not at all even though they’re all sized the same.
Mind you, this has worked fine all of October and into November with no menu changes, and now the past week we’re getting mass reports. And of course, it’s not a platform specific issue. It’s simply the console players who are essentially the ones who mostly need to use a controller. But I can easily reproduce this behavior on my laptop or mobile device by connecting my controller.
I think I have a solution at least for my circumstance that may also work for you as well. In my case of having the Scrollframe of TextButton rows with a Frame under each TextButton that has the Image Layout of ImageButtons, I changed the Active property for them all and got a better result.
What I’ve done is in the Activate connection of the selected TextButton row, I have a function that sets the Active property to false for all other TexButton rows. And then I have its MouseLeave connection have a function that makes it so all the other TextButtons can become true for the Active property again. That coupled with the Frame that has the UILayout of ImageButtons being set with its size scale of X and Y to be 1.2 so its slightly larger than the ImageButton row seems to make it so the ImageButtons for the selected TextButton always work now for the Virtual Cursor.
for index1, rowbutton in pairs(ScrollFrame:GetChildren()) do
-- Make it so only the clicked button is active
rowbutton.Activated:Connect(function()
for index2, button in pairs(ScrollFrame:GetChildren()) do
if button:IsA("TextButton") then
if button ~= rowbutton then
button.Active = false
else
button.Active = true
end
end
end
end)
-- Make it so all other buttons become active in scroll frame
rowbutton.MouseLeave:Connect(function()
for index, button in pairs(ScrollFrame:GetChildren()) do
if button:IsA("TextButton") then
if button ~= rowbutton then
button.Active = true
else
button.Active = false
end
end
end
end)
-- Added protection to ensure we don't leave the previously active button inactive
rowbutton.MouseEnter:Connect(function()
for index, button in pairs(ScrollFrame:GetChildren()) do
if button:IsA("TextButton") then
button.Active = true
end
end
end)
end