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?
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)
@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:
only process a limited number of selected BillboardGuis;
only update guis in reasonable range and
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)