Help with billboardGUI healthbar

ive been trying make a healthbar with billboardGUI for my game, and as it a healthbar, the fill have to be with offset, so far i got the offset sizing part right, using the absolute size from the billboard to account for camera changing distance, but it have a small delay when trying to! anyone know why?

so far ive been using runservice.renderstepped and runservice.heartbeat

2 Likes

what are you using runservice for? updating the health??

1 Like

To add on to this reply, if you are updating the UI with RunService, I would instead recommend using :GetPropertyChangedSignal()

Example code:

local humanoid = nil --Reference the humanoid here

humanoid:GetPropertyChangedSignal("Health"):Connect(function()
	local newHealth = humanoid.Health

	--Update the UI
end)

You can just use while true do with a task.wait(0.1) to stop it from crashing/lagging your game.

I have wrote a example on how to achieve this

local Humanoid = script.Parent.Parent.Parent.Parent.Parent.Humanoid

while true do
wait(0.1)
		script.Parent.Healthbar.Visible = true
		script.Parent.HealthNum.Text = math.floor(Humanoid.Health) .. " / " .. math.floor(Humanoid.MaxHealth)
	
		local pie = (Humanoid.Health / Humanoid.MaxHealth)
		script.Parent.Healthbar.Size = UDim2.new(pie, 0, 1, 0)
	end

This won’t lag your server as it is client side and does not cause any lag/minimal lag on lower end devices.

yeah exactly what i was gonna say. delay’s probably caused because OP maybe added a wait() or something. idk it’s just an educated guess.

its meant to change everyone’s HP bar size every frame, as billboard with offset sizes makes it for some reason scale up when farter away, so i have to constantly set it to the billboard absolute size

here is how its currently structured:

game["Run Service"].Heartbeat:Connect(function(delta)
	for i,v:Player in pairs(players:GetChildren()) do
		local char = v.Character
		if not char then return end
		local cutoff:Frame = frames[char].cutoff
		local fill:ImageLabel = frames[char].fill
		if not (cutoff or fill) then return end
		local human = char:FindFirstChildOfClass("Humanoid")
		if not human then return end
		local absolSize:Vector2 = cutoff.Parent.Parent.AbsoluteSize
		fill.Size = UDim2.fromOffset(absolSize.X, absolSize.Y)
		cutoff.Size = UDim2.new(human.Health / human.MaxHealth, 0, 1, 0)
	end
end)

the main problem is basically: when the camera is still, its scaled correctly and fits the background perfectly, when i move the camera away, the fill for a second is too small and have to wait a bit to get to the intended size

To get rid of that delay, instead of connecting to heartbeat, connect to Humanoid.Health.Changed() inside a local script, This should get rid of the delay and be less laggy.

I cannot currently test this as I do not have access to a computer with studio on it.

(but it should work)

the problem isnt scaling based on health, its adjusting for absolute size, as i said, moving camera away make it smaller for a split second

I’m confused as to why you are using offset for the Gui? Why can you not use scale?

I’ll correct it a little: Health.Changed:Connect()
By the way, I already have a working HP Bar that I found in the toolbox and edited it, you can try it if you want.

it uses image labels, so it have one background, one frame for cropping the fill with ClipInDescendants, and the fill, which have to be with offset size

screenshot of the problem, again, not related health changing


when zooming camera in

when zooming camera away

intended size

Sorry, I was answering the question as you asked it, You mentioned a small delay when resizing, not the camera moving away making it smaller for a split second, As for a solution, this happens because of how you coded it, I suggest rewriting your script (and formatting it), You could also always find a tutorial if needed.

1 Like

i didnt notice i had forgot to mention camera moving away, sorry

As for your mentioned issue, I am pretty sure this happens based on the Billboard GUI.

Try messing around with studsoffset and extentsoffset to fix your problem.

You can cutoff the health bar without having to use a cutoff Frame with ClipDescendants. You can do this by inserting a UIGradient as a child of the fill image, and setting the transparency to a number sequence.

Here is how you could do that:

--Set your fill image size to use scale instead of offset
local fill = script.Parent --Replace this with the actual address of your fill image
local uiGradient = fill.UIGradient --Replace this with what the name of the UIGradient is set to

local humanoid = Instance.new("Humanoid", workspace) --Again, replace this with the actual address

humanoid.HealthChanged:Connect(function(newHealth)
	local maxHealth = humanoid.MaxHealth
	local healthPercent = newHealth/maxHealth
	
	local startKeypoint = NumberSequenceKeypoint.new(0, 0)
	local opaqueEnd = NumberSequenceKeypoint.new(healthPercent, 0)
	local invisibleStart = NumberSequenceKeypoint.new(healthPercent + 0.001, 1)
	local endKeypoint = NumberSequenceKeypoint.new(1, 1)
	
	local transparencySequence = NumberSequence.new({startKeypoint, opaqueEnd, invisibleStart, endKeypoint})
	
	uiGradient.Transparency = transparencySequence
end)

For example, here is how the transparency number sequence would look like when your health is at 50%:

1 Like