BillboardGui Growing and Shrinking with Distance

Hello Developers!

I’m trying to reasonably scale a BillboardGui.

At first I was using offset (pixel units) to define the width and height, which worked very well up close, but the gui started growing abnormally large the further away I moved.

Which is why I converted the size to scale (stud units in case of BillboardGuis). As expected, the gui remained of the same size at all times, and seemingly shrinked with increasing distance. This time it quickly became unacceptably small.

I looked up for possible solutions and found out BillboardGuis have DistanceStep, DistanceLowerLimit and DistanceUpperLimit properties. You can view them here, accessible via scripts, and not in the properties window: BillboardGui | Documentation - Roblox Creator Hub. Supposedly the step should allow the gui to grow and shrink within distances defined by the other two properties.

Nevertheless, they don’t seem to work at all. I’ve tried using them on the server side and in a local script, both when the gui is inside the part and when the gui is in StarterGui with Adornee set to the said part.

Am I missing something?

Is there any alternative way other than using a script to manually handle what those three properties (to my understanding) should?

Thank you in advance. :slight_smile:

UPDATE 1

I just found this post (Show missing distance BillboardGui properties in the Properties widget). These properties are most likely still not functional. After some additional testing I realized CurrentDistance always remains zero.

using an UiListLayout fixed that issue for me

1 Like

Unfortunately I don’t understand how UiListLayout can do this.

Here’s an exaple of how the gui growth might look on a chart.

Simply Make the Size of the BillboardGui Relative instead of using an offset. For Example Set the Size of the Billboard Gui to 6,0,6,0 (Not the Children, the BillboardGUI itself)

[https://gyazo.com/93d1f1221fba6bd245758988d462e04e](https://Example BillBoard)

@RafehPvP, thank you for your reply. To get the individual benefits of using both, offset (growing with distance) and scale (seeming shrinking with distance), I ended up writing a simple script which achieves what DistanceStep, DistanceLowerLimit and DistanceUpperLimit would, had they were implemented.

I’m aware that using my script on a high number of guis can cause performance concerns. That is why I will:

  1. only process a limited number of selected BillboardGuis;
  2. only update guis in reasonable range and
  3. only update guis in the player’s visual field (maybe, or one at a time).

I kept the example I’m posting as simple as possible. DistanceLowerLimit and DistanceUpperLimit have reversed roles.

local RunService = game:GetService("RunService")

local LocalPlayer = game:GetService("Players").LocalPlayer
local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")

local camera = workspace.CurrentCamera
local guiPart = workspace:WaitForChild("GuiPart")
local gui = PlayerGui:WaitForChild("BillboardGui")
gui.Adornee = guiPart

local DISTANCE_LOWER_LIMIT = 20 -- studs
local DISTANCE_UPPER_LIMIT = 35 -- studs
local GROWTH = 2 -- 200%

local UDim2FromScale = UDim2.fromScale
local Clamp = math.clamp

local originalSize = gui.Size
local interval = DISTANCE_UPPER_LIMIT - DISTANCE_LOWER_LIMIT

-- Scaling is set to true to initialize the size.
local scaling = true

local function ShouldApplyScaling(): (number, boolean)
	local magnitude = (camera.CFrame.Position - guiPart.CFrame.Position).Magnitude
	return magnitude, magnitude >= DISTANCE_LOWER_LIMIT and magnitude <= DISTANCE_UPPER_LIMIT
end

local function UpdateGuiSize(dt)
	local magnitude, isInInterval = ShouldApplyScaling()

	if isInInterval then
		scaling = true
		local factor = 1 + ((magnitude - DISTANCE_LOWER_LIMIT)/interval) * (GROWTH - 1)
		gui.Size = UDim2FromScale(
			originalSize.X.Scale * factor, originalSize.Y.Scale * factor
		)
	-- Once outside the interval (limits), only update once.
	elseif scaling then
		scaling = false

		local factor
		if Clamp(magnitude, DISTANCE_LOWER_LIMIT, DISTANCE_UPPER_LIMIT) == DISTANCE_LOWER_LIMIT then
			factor = 1
		else
			factor = GROWTH
		end
		gui.Size = UDim2FromScale(
			originalSize.X.Scale * factor, originalSize.Y.Scale * factor
		)
	end
end

RunService.Heartbeat:Connect(UpdateGuiSize)
2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.