"Easy" way for UIGridLayout Xbox support?

Hi!

I was wondering if an easier way exists to make the GridLayout constraint not so painful to use on Xbox remotes?

Here’s an example of what I mean:

I’m aware that buttons have properties inside them for the selection to the right, left, up, and down, but I am changing the UI’s in my frame a lot so it is really inconvenient to have to write to all of those values.

Thank you in advance,

New_Item

Heyo :grinning:
I don’t think there’s a built-in way to do this, and I realized that I also need this functionality soon, so I went and wrote a module for it.

function indexOf(t, val)
    for i,v in pairs(t) do
        if v == val then
            return i 
        end
    end
end

return function(grid) --grid is the frame containing your grid items and gridconstraint
    local Objects = {}
    local Ys = {}
    local Xs = {}
    local ObjectGrid = setmetatable({}, {
        __index = function(this, index)
            local newrow = {}
            rawset(this, index, newrow) --rawset is redundant here, but I like it this way
            return newrow
        end
    })

    for i, obj in pairs(grid:GetChildren()) do
        if obj:IsA("GuiObject") then
            local pos = obj.AbsolutePosition
            
            if not indexOf(Ys, pos.Y) then
                table.insert(Ys, pos.Y)
            end

            if not indexOf(Xs, pos.X) then
                table.insert(Xs, pos.X)
            end

            table.insert(Objects, obj)
        end
    end

    table.sort(Xs)
    table.sort(Ys)

    for i, obj in pairs(Objects) do
        local pos = obj.AbsolutePosition
        ObjectGrid[indexOf(Ys, pos.Y)][indexOf(Xs, pos.X)] = obj
    end

    for y, row in pairs(ObjectGrid) do
        for x, obj in pairs(row) do
            obj.NextSelectionUp = ObjectGrid[y - 1][x] or ObjectGrid[y - 1][1]
            obj.NextSelectionDown = ObjectGrid[y + 1][x] or ObjectGrid[y + 1][1]
            --
            obj.NextSelectionLeft = ObjectGrid[y][x - 1] --or <put in your other logic here>
            obj.NextSelectionRight = ObjectGrid[y][x + 1] -- ^
        end
    end
end

Just put this in a module somewhere

local OrganizeGrid = require(path.to.the.module)

--whenever the grid changes:
OrganizeGrid(Frame) -- the grid with the GridConstraint and elements

Let me know how this goes for you!

Edit: For being able to enter/leave the grid, you’d probably hook up ButtonA and ButtonB

Example:

--on button B press:
if GuiService.SelectedObject.Parent == Frame then
     --close frame or exit
     GuiService.SelectedObject = <default guiobject outside of frame>
end

For entering, I’d set GuiService.SelectedObject to the object in you frame with the lowest LayoutOrder

6 Likes

Awesome thank you so much I’ll give it a go later today!!

Works like an absolute miracle, thank you so much!

1 Like