I wrote a simple script in order to resize UIStrokes. Here it is:
--!strict
local PlayerGUI = game.Players.LocalPlayer.PlayerGui :: typeof(game.StarterGui)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local FRAME_SIZE_ATTRIBUTE = "DefaultAbsoluteSizeX"
local STROKE_THICKNESS_ATTRIBUTE = "DefaultThickness"
local containers = {PlayerGUI, ReplicatedStorage.Blaster}
local camera = workspace.CurrentCamera
local StrokeHandler = {}
function StrokeHandler.update(self: StrokeHandler)
for _, container in containers do
for _, child in container:GetDescendants() do
if not child:IsA("UIStroke") then continue end
local defaultThickness = child:GetAttribute(STROKE_THICKNESS_ATTRIBUTE)
local parent = child.Parent
local defaultSize = parent:GetAttribute(FRAME_SIZE_ATTRIBUTE)
child.Thickness = parent.AbsoluteSize.X * defaultThickness / defaultSize
end
end
end
function StrokeHandler.Init(self: StrokeHandler)
self:update()
camera:GetPropertyChangedSignal("ViewportSize"):Connect(function()
print("Updating!")
self:update()
end)
end
type StrokeHandler = typeof(StrokeHandler)
return StrokeHandler
So basically i just have attributes on each UIStroke and each TextLabel, Frame with sizes on my phone and using this data I simply resize it for any other device.
But I got this strange artifact:
If I remove call of self:update(), there is no glitch. Also, if we change this line:
We also don’t have a glitch. It’s really strange. I don’t manipulate any positions of UI or something like that. Glitch also disappears after ScreenGUI with UI was displayed on the screen once. On every other new appearing there will not be this glitch. I got this glitch currently on all UI with tweens. I will appreciate any help
but how? i manipulate stroke thickness, it’s not related to position at all. as you can see in the video, frame appears on the final point of a tween for a one frame
While I can’t comment for sure on what is causing this issue, it might be many things contributing to it. These could be: when you run update, what math you use, or UIStroke just not liking the numbers you give it (as Ryan mentioned, floating point numbers, numbers with very precise decimals which can cause imperfections).
Thankfully, there is an easy way out of this mess. There’s a beta feature for UIStroke which released recently which lets you auto-scale strokes on all devices. Someone wonderful made a post on how to convert your strokes to the new system. I presume their math might be worth comparing with your code for a possible fix, assuming the issue is math related. You could also try out the beta feature and migrate your strokes to auto-scale using the same code. This should have no issues.
Unfortunately I started to do all of that because of the fact that I am experiencing really strange behaviour using stroke update.
I did really easy math right from this topic and it doesn’t work for some of strokes (for me it was TextLabel stroke, you can see my comment being the last in this topic)
Assuming “broken” means the script is not properly converting for auto-scale, we know text rendering is always different than frame rendering. Text size calculation is not straightforward, as it varies between fonts and sizes. So the script I mentioned may not do that.
I ran the script and some of my TextLabels did have wonky scale. In this case, you may just have to manually fix this on a case-by-case basis.
If you prefer not to use the script converting to auto-scale, you can try what Ryan mentioned which is to clamp decimal precision to two points in your code. So a number like 2.12 instead of 2.1254332453.
Roblox UI uses floating-point scaling, but when rendering, pixel rounding can cause ± 1 px jitter. Forcing the final pixel size to an even integer prevents subpixel alignment issues and texture tearing, especially with borders, outlines, or stroked UI elements
Useless to fix, so just leave it like that, or just write a custom roundNumber function
But how it’s related to text size calculation? I thought that what new UI Stroke updates does is simply takes AbsoluteSize of TextLabel and uses the formula to get size of stroke. It’s the same process as with frames.