Hello everyone!
I’ve seen many people (and games) having trouble with having ScrollingFrame’s elements not being visible because the frame doesn’t go down all the way or maybe it goes down too far.
Well there may be many solutions, but I’ll be explaining the one I use all the time. It may not make sense at first like it did to me but you’ll get used to it and will be happy with the result. The reason I say it may not make sense is because you should use offset
instead of scale
when setting the CanvasSize
. Note that I’m only referring to the CanvasSize; dont use Offset for Size, Position, etc…
Wait, why not use AutomaticCanvasSize
? I don’t recommend that you use AutomaticCanvasSize because it dynamically scales the elements so it fits the scrollingFrame’s size. However my way that I’ll explain makes it so the CanvasSize of the scrollingFrame dynamically adjusts which is quite the opposite of using AutomaticCanvasSize.
I’ll go step-by-step and then link the file for the example place I’m showing below.
STEPS:
- Make sure you have a your Gui ready and then insert a ScrollingFrame
-
I suggest that you set the Anchor Point to (0.5, 0.5) and Position and Size to a scale value. As. you can see, I have many other elements like AspectRatios, I suggest using these anywhere in your developmental UI to make it consistent.
-
Here, the real work beings:
-
Add a Gui formatter to your ScrollingFrame (ie. UIListLayout, UITableLayout, UIGridLayout, UIPageLayout). Do note that this is an important step in making it possible to use offset as a size.
-
Set the
AutomaticCanvasSize
to Y or X depending on the desired scroll direction of the ScrollingFrame. Also set the CanvasSize property of the scrollingFrame to {0, 0, 0, 0} -
Insert a LocalScript into your game somewhere that is acceptable. I prefer to have a Folder named ‘Gui’ in StarterPlayerScripts. Then name your LocalScript as this will keep your game organized.
Example
Okay, let’s start coding. I will provide 2 scripts that are slightly different depending on the ScrollingDirection. Then I will explain how the script operates in general.
Make sure to read the comments; they may be really far off to the right.
Y scrollingFrame Code
--This is for a scrollingFrame in the Y direction.
--// INITALIZE GUI VARIABLES \\--
local player = game:GetService("Players").LocalPlayer
local exampleGui = player.PlayerGui:WaitForChild("ExampleGui")
local container = exampleGui.Container
local scrollingFrame = container.ScrollingFrame -- Set equal to your scrollingFrame
local UIListLayout = scrollingFrame.UIListLayout -- Should be a child of your scrollingFrame
--// INITALIZE WORKSPACE VARIABLES \\--
local currentCamera = game:GetService("Workspace").CurrentCamera
local function updateCanvasSizeBasedOnAbsoluteContentSize()
local viewportYSize = currentCamera.ViewportSize.Y -- This is an offest value, not an Udim2 value. Will return the Y size of the screen in pixels.
local offset = viewportYSize * 0.025 -- It's sometimes a good idea to have an offset so there is some wiggle room/gap near the ends of the scrollingFrame even if you have a UIPadding element.
local AbsoluteContentSize_Y = UIListLayout.AbsoluteContentSize.Y -- Will get the amount of pixels on the y-axis that the items within the scrollingFrame takes up.
-- Set the CanvasSize of the scrollingFrame
scrollingFrame.CanvasSize = UDim2.fromOffset(0, AbsoluteContentSize_Y + offset)
end
updateCanvasSizeBasedOnAbsoluteContentSize() -- It's a good idea to initalize the size of the Canvas at the start of the session.
-- Now we will need to change the CanvasSize if the amount of items within the scrollingFrame changes or when the size of the user's window changes (like if they resize the game's window on PC).
currentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(updateCanvasSizeBasedOnAbsoluteContentSize)
UIListLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(updateCanvasSizeBasedOnAbsoluteContentSize)
X scrollingFrame Code:
--This is for a scrollingFrame in the X direction.
--// INITALIZE GUI VARIABLES \\--
local player = game:GetService("Players").LocalPlayer
local exampleGui = player.PlayerGui:WaitForChild("ExampleGui")
local container = exampleGui.Container
local scrollingFrame = container.ScrollingFrame -- Set equal to your scrollingFrame
local UIListLayout = scrollingFrame.UIListLayout -- Should be a child of your scrollingFrame
--// INITALIZE WORKSPACE VARIABLES \\--
local currentCamera = game:GetService("Workspace").CurrentCamera
local function updateCanvasSizeBasedOnAbsoluteContentSize()
local viewportXSize = currentCamera.ViewportSize.X -- This is an offest value, not an Udim2 value. Will return the X size of the screen in pixels.
local offset = viewportXSize * 0.025 -- It's sometimes a good idea to have an offset so there is some wiggle room/gap near the ends of the scrollingFrame even if you have a UIPadding element.
local AbsoluteContentSize_X = UIListLayout.AbsoluteContentSize.X -- Will get the amount of pixels on the x-axis that the items within the scrollingFrame takes up.
-- Set the CanvasSize of the scrollingFrame
scrollingFrame.CanvasSize = UDim2.fromOffset(AbsoluteContentSize_X + offset, 0)
end
updateCanvasSizeBasedOnAbsoluteContentSize() -- It's a good idea to initalize the size of the Canvas at the start of the session.
-- Now we will need to change the CanvasSize if the amount of items within the scrollingFrame changes or when the size of the user's window changes (like if they resize the game's window on PC).
currentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(updateCanvasSizeBasedOnAbsoluteContentSize)
UIListLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(updateCanvasSizeBasedOnAbsoluteContentSize)
Why this works:
-
Scale
is based on the parent UI element’s size, which makes it unpredictable for dynamic content inside a scrollingFrame. WhereasOffset
uses exact pixel values, ensuring that the CanvasSize expands properly based on the content inside the scrollingFrame.
Okay, let’s test it out. I’m going to add some UI elements to my scrollingFrame and see how they work. Remember to only use offset for the CanvasSize, every other thing should be using Scale like Position and Size (in my opinion).
Video (720p because file limit)
Here is the file for the place shown in the images/video.
ScrollingFrameExample.rbxl (71.6 KB)
Hopes this helps you with your journey in creating epic Roblox games!
7eoeb