The problem: https://gyazo.com/1f41d525cad55ad06710cc6528f0286b
The solution: https://gyazo.com/70496a9614a7e51cb4bb1b96c5494e06
What I ended up doing was finding the “right” size for all 9 boxes while using a 2:1 aspect ratio on the screen (the “desired aspect ratio”). This “right size” was UDim2.new(0.8, 0, 0.8, 0)
: Screenshot by Lightshot
I then had a script automatically resize the boxes based on
- the screen’s current aspect ratio,
- the desired aspect ratio, and
- the initial size of each box.
Please note that you do not have to use a 2:1 aspect ratio. You can use any, as long as you record it to the variable that denotes your desired aspect ratio.
In the script, the boxes are referred to as frames.
local Frames={}
local OriginalSizes = {}
local DesiredAspectRatio, CurrentAspectRatio = 2, nil
-- The DesiredAspectRatio here is 2 because the ratio during which the borders were measured was 2:1. If you measured the borders while using a 16:9 ratio, you would simply replace 2 with 16 / 9.
local function RatioAdjustedSize(Frame)
local ScaleDown = CurrentAspectRatio / DesiredAspectRatio
return UDim2.new(OriginalSizes[Frame].X.Scale * ScaleDown, OriginalSizes[Frame].X.Offset, OriginalSizes[Frame].Y.Scale * ScaleDown, OriginalSizes[Frame].Y.Offset)
-- The offset properties are not particularly important
end
local function ResizeBoxes()
CurrentAspectRatio = workspace.CurrentCamera.ViewportSize.X / workspace.CurrentCamera.ViewportSize.Y
if CurrentAspectRatio <= DesiredAspectRatio then
-- I do not scale any of the boxes up if the current aspect ratio is more than the desired because I don't want the boxes spilling out of the top and bottom borders
-- This however has the side effect of making really tiny boxes exist within the frame, having very large top and bottom borders for users with unusually low aspect ratios.
-- For me personally, that is an OK trade-off to not have any spill-over at all.
for _,Frame in pairs(Frames) do
Frame.Size = RatioAdjustedSize(Frame)
end
end
end
I am aware that it would be easier to have one table with each Frame having its own index and a table as the value, which itself would contain an OriginalSize entry. However, this would require an unfortunate amount of restructuring on my part. It isn’t important to this topic regardless.
Later on in the script, after having filled the Frames
table and created entries in the OriginalSizes
table for each of them, I run our resizing function for when the user joins the game and also add a listener for changes in screen size in case the user was to resize their window.
ResizeBoxes()
workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(ResizeBoxes)
And that’s that. Everything stays within its border, and nothing gets clipped, no matter the screen size or aspect ratio.