LayoutUtil: Automatically sizes a ScrollingFrame's UIGridLayout/UIListLayout

LayoutUtil

GitHub Repository
LayoutUtil Wiki/Documentation

INSTALLATION

Roblox Library Download
GitHub Releases Download Page

ABOUT

In many games I played, I’ve noticed that most of them seem to disregard the CanvasSize of a ScrollingFrame and leave tons of empty space. This library was designed to help developers easily scale the size of their ScrollingFrames and UILayouts. It’s compatible with UIGridLayouts and UIListLayouts. After you construct a new class with the desired UILayout, your ScrollingFrame will automatically resize it’s CanvasSize, CellPadding, CellSize, and Padding accordingly.

NOTICE

  • It’s is still important to be using a UIAspectRatioConstraint in the main frame relative to each ScrollingFrame so that your UI doesn’t stretch.
  • Make sure that the default CanvasSize of the ScrollingFrame is set to (0, 0, 0, 0).
  • Everything including the CellSize/CellPadding/Padding and every child must be set to scale so that there are no inconsistencies across different resolutions.

Documentation is provided within the module as well as on the wiki.

SETUP

It’s relatively basic to setup and you only need to call a simple function. There are more advanced features provided if necessary.

local LayoutUtil = require(PATH) -- define the path to the module

LayoutUtil.new(UILAYOUT) -- define the path to the UILayout

WITHOUT LAYOUTUTIL

This game doesn’t automatically scale their UILayout and you can see how there is a lot of blank space and when you change resolutions, the children of the ScrollingFrame don’t size with it.

WITH LAYOUTUTIL

CONTACT

If I missed anything or there are any issues, be sure to DM me or leave a reply here.

Discord - Nickuhhh#0331
Roblox - iiNemo

46 Likes

Pretty useful for making GUIs. I would give this a try.

1 Like

We used it for Minion Simulator and Combo Clickers, works really well.

1 Like

Does this module account for UI elements inside the frame that use Scale as the size (eg a button inside that frame that has its size set to {0.1,0}, {0.1,0}? I want my buttons to size down for mobile and size up for bigger screens, and all of the code I’ve used to try and do this unintentionally makes the UI elements bigger/smaller than intended.

If not, an alternative would be neat because I’ve been stuck on this for a bit now.

For that you should be using UIAspectRatioConstraints, they will automatically resize a GuiObject based off the aspect ratio of your screen. If using it alters the size of the GuiObject, then keep tweaking the AspectRatio property until it seems to align with how it was before.

1 Like

Added GitHub Repository as well as a Wiki.
New features, performance optimizations, and bug fixes described on the Latest Releases.

3 Likes

Thank you I used it for my games, it works :slight_smile:

I’m confused on how to use your API for my Scrolling Frame.
When I run the script nothing is happening. Please let me know what I’m doing wrong!

Here is my Setup:
Screenshot_23

Here is my code:

--// Modules //
local LayoutUtil = require(game.StarterGui.Modules.LayoutUtil)

--// Variables //
local Player = game.Players.LocalPlayer
local UILAYOUT = Player.PlayerGui.ScreenGui.ScrollingFrame.UIGridLayout

Config = {
Bind = false, -- Removes instant binding.
ResizeCanvas = false, -- Removes canvas resizing.
ResizeContent = false, -- Removes content resizing.
OnResize = false, -- Updates when it's resized.
OnWindowResize = false, -- Updates when the content size changes.

-- UIGridLayout Exclusives
CellPadding = UDim2.new(1,1), -- Default CellPadding.
CellSize = UDim2.new(1,1), -- Default CellSize.

-- UIListLayout Exclusives
Padding = UDim.new(), -- Default Padding.
OnAxisChange = false, -- Updates when FillDirection changes.
OnAdd = false, -- Adds object to the resize cache.
OnRemove = false, -- Removes object from the resize cache.
}

--// Script //
LayoutUtil:ConvertToScale(UILAYOUT)

local Class = LayoutUtil.new(UILAYOUT,Config) -- define the path to the UILayout
Class:ResizeCanvas()
Class:ResizeContent()
Class:Bind()
1 Like

The config parameter is just for extra functionality, I should probably make that more clear. If you read up on the example page, all you have to do is require the module and then do .new(UILayout).

local LayoutUtil = require(PATH) -- define the path to the module

LayoutUtil.new(UILAYOUT) -- define the path to the UILayout

Above is all you need to do to get it to work automatically.

1 Like

This is a godsent, i was about to complain about how scrolling frame is a joke in developer discussion

Small bug relating to UIListLayouts was fixed, read more on the latest release.
If anyone has feature requests or problems with bugs, be sure to lmk.

1 Like

How can I use this in combination with UIPadding? The padding is messing up the calculations and making the sizes inaccurate. Any solution?

I believe you can hard-code custom padding using the module.

Not really necessary anymore, I ended up just changed the structure of my UI. Thanks for the suggestion though!

He was talking about an actual UIPadding object I believe, which really shouldn’t affect LayoutUtil. With your statement though, that brings up an idea where I shouldn’t restrict users from having to change the padding directly from my module.

This is simply a game-changer! This has become so essential in UI development. It’s simple to set up and had saved me so much time! Thank you for releasing LayoutUtil!

  • eiz_a

Am I doing something wrong here? I’m trying to use this with a UIListLayout, with all items using Scale for size and position. Testing it in the command bar first.

https://gyazo.com/7de64ee85e53bf1241b8aab0e7089fd4

  1. X scroll direction being created when I don’t want it to.

  2. Resizing the window too much seems to create an issue where the items dont fit the ScrollingFrame, and this change seems irreversible (as seen in the gif).

I can provide more information if you need.

Does this module convert offset values to scale, should i use scale or offset for my elements? I am currently making custom chat and im really stuck i mean literally scrolling frame is just a joke for me and its practically impossible to make responsive design with it

I’ve gone out to test it myself and I noticed that a previous fix ended up causing the problems described in your gif. I just released a new version which should fix your issue here. Also don’t forget to use a UIAspectRatioConstraint on top of everything.

1 Like

The ScrollingFrame should be set to a CanvasSize of (0, 0, 0, 0). With that you should be setting all the children to scale from inside studio, there should be no offset.