Text(Label/Box/Button):GetTextScaledApproximateSize()

As a Roblox developer, it is currently impossible to feed TextService:GetTextSize()'s fontSize parameter knowing the actual TextSize of a TextScaled true TextLabel/Box/Button.

TextObject.TextBounds is not a reliable tool for getting text bounds because you have to wait a frame. The only synchronous way is TextService:GetTextSize(). But this poses a big challenge to people who use scaled UI and is trying to find exact text bounds.

Text(Label/Box/Button):GetTextScaledApproximateSize() returns a decimal (number). If TextScaled is false, it will just return the TextSize. This will be good use for the fontSize parameter for the GetTextSize function to get accurate results.

Edit: Not many use cases for this and would lead to API bloat. Probably ignore.

Didn’t I tell you that you don’t have to wait a frame anymore?

Here’s the same script in the reply that I linked, but with TextScaled = true and the size of the frame is changed instead of the text.

local sg = Instance.new("ScreenGui")
sg.Parent = game:GetService("CoreGui")
local label = Instance.new("TextLabel", sg)
label.Text = "Test"
label.Size = UDim2.new(0, 100, 0, 100)
label.TextScaled = true
print(label.TextBounds)
label.Size = UDim2.new(0, 200, 0, 200)
print(label.TextBounds)
wait(1)
print(label.TextBounds)

This will print:

99, 59
165, 100 (x2)

Again, you don’t need to wait a frame anymore for the values of properties to update.

That’s strange. My use case is in a BillboardGui.

???

local sg = Instance.new("BillboardGui") -- Billboard gui
sg.Parent = game:GetService("CoreGui")
sg.Adornee = workspace.Baseplate -- Adorned to Baseplate.
local label = Instance.new("TextLabel", sg)
label.Text = "Test"
label.Size = UDim2.new(0, 100, 0, 100)
label.TextScaled = true
print(label.TextBounds)
label.Size = UDim2.new(0, 200, 0, 200)
print(label.TextBounds)
wait(1)
print(label.TextBounds)

Prints:

99, 59
165, 100 (x2)

If you can whip up a script where changing properties of whatever doesn’t cause TextBounds to update immediately, it would help a lot.

This behavior only happens in studio, but in-game it does not happen.

Try putting it in a script and running it.

LocalScript in a ScreenGui in StarterGui:

wait(2)
local sg = script.Parent
local label = Instance.new("TextLabel", sg)
label.Text = "Test"
label.Size = UDim2.new(0, 100, 0, 100)
label.TextScaled = true
print(label.TextBounds)
label.Size = UDim2.new(0, 200, 0, 200)
print(label.TextBounds)
wait(1)
print(label.TextBounds)

image

Same, but for a BillboardGui adorned to Baseplate

image

The place file:place.rbxl (17.2 KB)

Do you have a test place/script that you can show instead?

Just used your example;


local sg = Instance.new("BillboardGui") -- Billboard gui
sg.Parent = workspace
sg.Adornee = workspace.Baseplate -- Adorned to Baseplate.
local label = Instance.new("TextLabel", sg)
label.Text = "Test"
label.Size = UDim2.new(0, 100, 0, 100)
label.TextScaled = true
print(label.TextBounds)
label.Size = UDim2.new(0, 200, 0, 200)
print(label.TextBounds)
wait(1)
print(label.TextBounds)

I believe its parenting to workspace that doesn’t do this change. Put this in a Server Script in workspace too.

Servers don’t have a screen or camera, so it makes sense that TextBounds (or any other property that depends on the size of the screen directly or indirectly, such as AbsoluteSize of AbsolutePosition) wouldn’t be useful when read from the server.

If, instead, the Size of the label used scale (e.g. UDim2.new(1, 0, 1, 0)) what would the AbsoluteSize (and, indirectly, the TextBounds) of the BillboardGui/Text be when you read it from the server?

EDIT2: I think it’s important to ask why you’re attempting to read the TextBounds on the server in the first place. Do you plan on modifying the client’s UI from the server?

I’m using custom name tags above character’s heads, and a background that sizes based on the text length. I feel its easier to do when the client sends custom user input through a Remote and have the server change their tag.

wrt. editing client gui from the server:

Don’t edit UI form the server. Use remotes. Adding the feature that you want would be a footgun and would just encourage bad coding practices.

The tags (BillboardGuis) I do have in my game were cloned and parented to the heads of characters in workspace through a server script. The examples you put are those for ScreenGuis, which are player-local only. BillboardGuis only display in the workspace.

Therefore, are these BillboardGuis still client GUI?

If I’m understanding your usecase right, since you’re resizing a BillboardGui, and BillboardGuis may resize based on their distance from the camera, and you’re trying to resize them dynamically, I would say that these should be rendered client-side.

If I’m not, then I think you should demo how you intend to use GetTextScaledApproximateSize if it were implemented.

Ah. Here’s a use case in a script.

local Bounds = TextService:GetTextSize("Hello", Label:GetTextScaledApproximateSize(), Enum.Font.SourceSans, Label.AbsoluteSize)

print(Bounds) -- Varies based on the user's screen

Again, Label:GetTextScaledApproximateSize() just simply returns the actual TextSize of a TextScaled label/box.

Label:GetTextScaledApproximateSize()
But what size will the label use if it uses the scale component, the server doesn’t have a camera nor a screen

If the gui is far from the camera, the text size will be small. If it’s close, it will be larger. Since the server doesn’t have a camera, how would it determine the size of the text in the first place?

1 Like

Like how a BillboardGui’s scale is related to the part’s size which is adorned, the label to also have the scale component (with TextScaled) will be related to the BillboardGui.

Therefore, the camera has nothing to do with this.

EDIT2: The camera is needed for TextScaled. My bad.

1 Like

I think this is getting confusing.

Just to clarify, this script:

local Bounds = TextService:GetTextSize("Hello", Label:GetTextScaledApproximateSize(), Enum.Font.SourceSans, Label.AbsoluteSize)

print(Bounds) -- Varies based on the user's screen

Does this run on the server or the client?

It would run on the server, but my reasoning was flawed. It turns out a BillboardGui is both related to the camera and the part size.

Edited OP.

1 Like