Best Inventory GUI ever

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:

obraz

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:

11 Likes

That’s nice.
I’m guessing that’s only the template? So like you will start actually designing the UI later?

2 Likes

Yes.
Here I want just to present one specific thing. So I kept it as simple as I could, I deleted all other stuff that I already have in my game.

2 Likes

Bro, you know this is just a template, right?

2 Likes

This is just system that should controll your inventory items layout. I created it ugly intentionally. If you want you can use it in the most beautiful UI you can create. This all thing is about script not GUI by itself. I added GUI elements here so you know how to use it in the most simple way.

3 Likes

This should fall under the #resources:community-resources catergory since it is a script that makes developing easier, and not a support issue. Thanks.

2 Likes

Oh, sorry, my bad. It’s my first topic. Can I somehow move it or anyone from administration? Or should I just create new topic there and delete this one?

2 Likes

Try editing the post, you can move it to the category like that.

2 Likes

Ok, I moved the topic. Thanks for your help <3

1 Like

Thank you so much for this, it looks really useful!

2 Likes