This is the current hierarchy of my inventory UI.
The grid frame contains all of the squares you see in the inventory.
The newly created button is the ImageButton.
These two, as well as the individual frames inside the grid, are sized and position with offset, not scale.
The scrolling frame on the other hand is scaled.
This is the code that positions the image button to a grid.
function InventoryUI:PositionToSpace(ItemFrame, FirstGrid)
local FirstGrid = tonumber(FirstGrid.Name) + 1 -- Add one as the first child of backpack is GridUILayout
local pos = BackpackGrid:GetChildren()[FirstGrid].AbsolutePosition - ItemFrame.AbsolutePosition
return UDim2.fromOffset(pos.X, pos.Y)
end
Kon’nichiwa!
It might be useful to you to use the UIGridLayout (roblox.com) API.
Its use is pretty simple and straightforward and should save you some effort as it was developed specifically for this purpose.
I should mention the individual squares inside of the grid frame do use UIGridLayout, and I doubt that’s the problem.
I’d like to think the problem has to do with the fact I’m using absolute positions to calculate the position for the image button. But I have no idea how else to find the position of a frame when their being controlled by a UIGridLayout.
You can add this to a local script which should be a child of the UIGridLayout object.
It will automatically put the newest object first in the UI.
It changes the LayoutOrder of new Frame added in order to achieve the desired order you want.
local Max_Horizontal_Direction_Fill = 5
local Grid = script.Parent
Grid.FillDirectionMaxCells = Max_Horizontal_Direction_Fill
Grid.SortOrder = Enum.SortOrder.LayoutOrder
Grid.StartCorner = Enum.StartCorner.TopLeft
Grid.VerticalAlignment = Enum.VerticalAlignment.Top
Grid.HorizontalAlignment = Enum.HorizontalAlignment.Left
Grid.FillDirection = Enum.FillDirection.Horizontal
Grid.Parent.ChildAdded:Connect(function(Child)
if Child:IsA("Frame") then
Child.LayoutOrder = -(#Grid.Parent:GetChildren()+1)
end
end)
Grid.Parent.ChildRemoved:Connect(function()
for i,Child in pairs(Grid.Parent:GetChildren()) do
if Child:IsA("Frame") then
Child.LayoutOrder = Child.LayoutOrder+1
end
end
end)
I don’t think you understand what I’m trying to do here.
I don’t want the UIGridLayout to apply to the item button, I want to position the item button on the grids, like in a grid inventory, e.g:
So my original code works completely fine, except, the problem seems to emerge when the scrolling frame CanvasPosition is not at 0,0 (as in it hasn’t been scrolled down).
I tried adding the CanvasPosition to my calculation of a new UDim2 in this line:
local pos = BackpackGrid:GetChildren()[FirstGrid].AbsolutePosition - ItemFrame.Parent.AbsolutePosition + Backpack.ScrollingFrame.CanvasPosition
However, this doesn’t seem to work.
Adding onto this, I think my problem might be very similar to this person’s problem,
however, his solution didn’t work for me.
This line prints the normal calculation without considering the CanvasPosition.
The result with scrolling frame scrolled all the way down.
Keep in mind, the normal position should be 72,72
This line prints out the CanvasPosition of the scrolling frame.
With the scrolling frame scrolled down, this is the result:
And so, this is the calculation I’m doing, see how I consider the offset of the scrolling frame by adding its CanvasPosition.
I’m not exactly sure why I need to do this. But separating the X and Y values into different lines of calculations seems to have made it work perfectly.
function InventoryUI:PositionToSpace(ItemFrame, FirstGrid)
local FirstGrid = tonumber(FirstGrid.Name) + 1 -- Add one as the first child of backpack is UILayout
local X = BackpackGrid:GetChildren()[FirstGrid].AbsolutePosition.X + Backpack.ScrollingFrame.CanvasPosition.X - ItemFrame.Parent.AbsolutePosition.X
local Y = BackpackGrid:GetChildren()[FirstGrid].AbsolutePosition.Y + Backpack.ScrollingFrame.CanvasPosition.Y - ItemFrame.Parent.AbsolutePosition.Y
return UDim2.fromOffset(X, Y)
end