How to solve UIStroke appearing too big on mobile devices [FIXED]

Good day developers. So many of you may remember my old tutorial. It was clearly inconvenient and if you have multiple UIStrokes in your game that aren’t all the same size, it’ll just set them all to 1. Which we don’t want.

So to fix that, we need to get the player’s screen/viewport resolution. So let’s begin.

Firstly, in the Explorer Panel, insert a ScreenGui into StarterGui:

Tutorial 0.01

Tutorial 0.02

Next, insert a TextLabel into that ScreenGui.

Tutorial 0.03

Insert a UIStroke into the TextLabel.

And you can see when you hover over long enough, it gives you the definition/idea of what an instance does.

Now, it’s time to script. Insert a local script into the TextLabel. Not a script or a module script. A local script.

Alright, so start by defining some variables.

local Player = game.Players.LocalPlayer -- This gets the LocalPlayer.

local CurrentCamera = game.Workspace.CurrentCamera -- This basically gets the camera.

local PlayerGui = Player.PlayerGui.ScreenGui

local Thickness = 1.5

local ViewportRatio = CurrentCamera.ViewportSize.X / CurrentCamera.ViewportSize.Y -- ViewportSize is basically the resolution of the client's screen. (a Vector2 value)
-- To find the viewport ratio, we need to do A divided by B. 

local UserInputService = game:GetService("UserInputService")
local TouchEnabled = UserInputService.TouchEnabled -- We can use this to check if the player is on a mobile device or not.

A for loop lets us go through each and every single object, and change the UIStrokes’ thickness property without needing to set each and every single one. This saves us a lot of time.

for i, v in pairs(PlayerGui:GetDescendants()) do -- What :GetDescendants() does is it gets the children of the children in an instance.
if TouchEnabled then -- This is the same as saying if true then or if false then. If the player is on a mobile device, then it'll be true, but if they're not on a mobile device then this won't run
end
end
for i, v in pairs(PlayerGui:GetDescendants()) do
if TouchEnabled then
print("This user is on a mobile device!") -- This will print if you emulate on a mobile device.
end
end
for i, v in pairs(PlayerGui:GetDescendants()) do
if v:IsA("UIStroke") then -- This checks if the Instance is of the given class.
if TouchEnabled then
print("This user is on a mobile device!") -- This will print if you emulate on a mobile device.
v.Thickness = v.Thickness / (Thickness * ViewportRatio) -- Takes the thickness of your UIStroke, and divides it by thickness variable we made earlier (1.5) multiplied by the ViewportRatio.
-- The ViewportRatio prints out a long decimal.  1.7796610169491525
-- ViewportRatio Rounded: 1.78
-- So, 8 (my UIStroke's thickness) / (1.5 *  1.7796610169491525)
-- This makes the thickness smaller, which IS what we want.

-- Here is just an equation with the rounded off numbers:
-- Order of Operations applies here as well. (Parentheses/Brackets, Exponents, Multiplication/Division) and Addition/Subtraction.)
-- 8 / (1.5 * 1.78) -- By the way the parentheses don't really change anything.
-- Answer: 2.9968254566192627
-- Rounded Answer: 2.997

-- Apologies for the mistakes earlier. (The corrected version is above.)
end
end
end

And, here are the results.

Before

After

Side note: If you print the the UIStroke’s thickness after the for loop has finished, it will give you a number smaller than the original thickness.

for i, v in pairs(PlayerGui:GetDescendants()) do
	if v:IsA("UIStroke") then
		if TouchEnabled then
			v.Thickness = v.Thickness / (Thickness * ViewportRatio)
		end
	end
end


print(script.Parent.UIStroke.Thickness) -- This gave me 2.9968254566192627.

Thickness change: 8 > 2.997

Here, we are given two images of 3 TextLabels, with UIStrokes applied on all of them.
From ascending to descending, they get smaller.

Before

After

If you made it this far, thank you for reading this, and have a great day! Thanks to @bluebxrrybot for the original script. Thanks to @Misterx113 for correcting me on my mistake last time.

Rate this tutorial.

Edit: A few changes will be made to the tutorial like more comments in the scripting sections for beginners to better understand what’s going on. As well as spelling errors.

Key Ideas

• UIStroke Instance - Applies a stroke when parented to a GuiObject. UIStroke
• IntValue Instance - Only holds whole numbers as values. IntValue
• NumberValue Instance - Holds both whole numbers and decimals. NumberValue
• CurrentCamera Property - The camera object being used by the local player. CurrentCamera
• ViewportSize Property - The resolution of the local player’s device. ViewportSize
• Vector2 - A datatype which you can store 2 values, usually an x and a y. Vector2

More about Vector2

Remember,
• x axis represents left and right
• y axis represents up and down

  • 1 (Needs work)
  • 2 (Okay)
  • 3 (Good)
  • 4 (Great)

0 voters

Bonus! Here’s also proof that this works! If you try and print out the client’s screen resolution, it gives you something close to it.

local Player = game.Players.LocalPlayer
local CurrentCamera = game.Workspace.CurrentCamera

print(CurrentCamera.ViewportSize) -- This will print the screen resolution of whatever you're emulating your game on.

This is the current screen resolution I’m emulating my game on.

Tutorial 0.11

And here is what the output printed.

Tutorial 0.12

It’s not exact, but it’s very close to the resolution of the client.

3 Likes