Hi,
Lately while making my game Balls Simulator I decided it’s time to make my inventory system. I played couple of games in roblox and from my expirience the game “Pet Simulator X” had the best inventory layout I saw in any game. Main thing I wanted to achive was dynamically changing size of the graphics of items in the inventory. I searched forum, internet, and roblox assets but couldn’t find anything that worked or it met my assumptions. So I had to create my own script to achive this.
This topic is to present you my resoults and give you the script of the best inventory GUI ( you will decide by yourself if that statement it’s real ).
Ok so this is how hierarchy and inventory looks like for this simple project:
In StarterGui we must create ScreenGui, inside we make Frame that will be our inventory and also will contain all objects we need. Inside we put our LocalScript that will be responsible for the entire layout, Button, and ScrollingFrame. In ScrollingFrame we create couple of images (this also can be buttons like in my example or any other GUI element) that will represent our inventory items.
The script itself looks like this:
local Inventory = script.Parent
local ScrollingFrame = Inventory.ScrollingFrame
local LayoutButton = Inventory.LayoutButton
-- Paddings
local PADDING_BOTTOM = 25
local PADDING_LEFT = 15
local PADDING_RIGHT = 25 -- I usually set bigger right padding cause of scroll in "ScrollingFrame"
local PADDING_TOP = 25
-- Big icons
local CELL_PADDING_BIG = 20
local CELL_MIN_SIZE_BIG = 70
local CELL_MAX_SIZE_BIG = 120
-- Small icons
local CELL_PADDING_SMALL = 5
local CELL_MIN_SIZE_SMALL = 30
local CELL_MAX_SIZE_SMALL = 60
-- Current icons
local cellPadding = CELL_PADDING_BIG
local cellMinSize = CELL_MIN_SIZE_BIG
local cellMaxSize = CELL_MAX_SIZE_BIG
local layout = "big" -- "big" / "small"
function RefreshInventoryLayout()
local numberOfCells = #(ScrollingFrame:GetChildren())
local scrollFrameASX = math.floor( ScrollingFrame.AbsoluteSize.X )
local frameASXNoPadding = scrollFrameASX - PADDING_LEFT - PADDING_RIGHT
local cellsNumberRow = 1
while true do -- calc how many cells will be in single row
-- formula for width explained
-- x = number of cells
-- x * CELL_MIN_SIZE + (x-1) * CELL_PADDING = x * (CELL_MIN_SIZE + CELL_PADDING) - CELL_PADDING
local cellsWithPaddingsMin = cellsNumberRow * (cellMinSize + cellPadding) - cellPadding
local cellsWithPaddingsMax = cellsNumberRow * (cellMaxSize + cellPadding) - cellPadding
if frameASXNoPadding < cellsWithPaddingsMax then
if cellsWithPaddingsMin < frameASXNoPadding then
break
else
print("Cant find proper size of cells for given parameters") -- if you give too small range for MIN/MAX cell size, a solution may not be found
return nil
end
else
cellsNumberRow = cellsNumberRow + 1
end
end
local frameCellsSize = frameASXNoPadding - (cellsNumberRow - 1) * cellPadding
local cellSize = math.floor(frameCellsSize/cellsNumberRow)
local numberOfRows = math.ceil(numberOfCells/cellsNumberRow)
local frameCanvasSizeY = PADDING_TOP + numberOfRows * (cellSize + cellPadding) - cellPadding + PADDING_BOTTOM
ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, frameCanvasSizeY)
local allCells = ScrollingFrame:GetChildren()
local actualCell
if(#allCells > 0) then
for j=0, numberOfRows - 1 do
for i=0, cellsNumberRow - 1 do
if j*cellsNumberRow + i + 1 <= numberOfCells then
actualCell = allCells[j*cellsNumberRow + i + 1]
actualCell.Size = UDim2.new(0, cellSize, 0, cellSize)
actualCell.Position = UDim2.new(0, PADDING_LEFT + i * (cellSize + cellPadding), 0, PADDING_TOP + j * (cellSize + cellPadding))
else
return
end
end
end
end
end
function SwapIconsSize()
if layout == "big" then
layout = "small"
cellMinSize = CELL_MIN_SIZE_SMALL
cellMaxSize = CELL_MAX_SIZE_SMALL
cellPadding = CELL_PADDING_SMALL
RefreshInventoryLayout()
else
layout = "big"
cellMinSize = CELL_MIN_SIZE_BIG
cellMaxSize = CELL_MAX_SIZE_BIG
cellPadding = CELL_PADDING_BIG
RefreshInventoryLayout()
end
end
ScrollingFrame:GetPropertyChangedSignal("AbsoluteSize"):Connect(RefreshInventoryLayout) -- Connect scrolling frame size change
LayoutButton.MouseButton1Click:Connect(SwapIconsSize) -- Connect the layout button
And this is final result of this attempt:
You can set all sizes (paddings, item cell size etc) by changing all constant values at top of script. Items cell size will change itself between MIN/Max values and if scrolling frame is too wide or too narrow then it will increse/decrese number of item icons in single row. Pretty simple and pretty cool!
You are free to use it for your own projects. Inform me in comments if you find any bugs. You can also check how this system works in my game Balls Simulator which I am currently developing: