Having multiple health bars act as one

Ok, so the concept I have is to split the health bar into multiple ones.
Something like this:
image

Now the problem comes to updating it, because all the “capsules” are separate frames and a simple math.clamp won’t do.

I came up with the idea to have a two dimensional matrix that has values coresponding to the player’s health:

16 15 14 13
12 11 10  9
 8  7  6  5
 4  3  2  1

And another two dimensional matrix that has each capsule represented by a line and the columns are the values to tween to for each hitpoint

{1, 0.75, 0.25, 0}
{1, 0.75, 0.25, 0}
{1, 0.75, 0.25, 0}
{1, 0.75, 0.25, 0}

Now using the first matrix and the HealthChanged event I get the coordinates of the current health of the player and the coordinates of the health after it changed. For example:
Current Health = 16
Row = 1
Column = 1

Health = 12
Row = 2
Column = 1

Then I used a bunch of for loops and if else statements to tween from position [1][1] to position [2][1] in the second matrix.

At first it seemed like it worked fine but after some testing I’ve stumbled upon the following issues:

  1. When the player health changes rapidly the function can’t keep up and the ui bugs out;
  2. By attempting to make the tweens smoother (either with longer tween time or wait() commands) the function won’t respond to the next health change until is hasn’t finished tweening.

I have looked around on the forum but the closest thing I’ve got to a multi health bar system are the layered bars.

The method I used works but it’s too buggy, and I wondered if there could be a better approach

1 Like

I think the matrix way is a bit overkill. You can set the parts’ sizes directly like this:

local humanoid = -- etc.

local guis = {
	script.Parent.BottomBar,
	script.Parent.MidBar,
	script.PArent.TopBar,
	-- etc.
}

local visualHealth = humanoid.Health

local function Update(health)
	visualHealth = health -- I'm setting this directly, but this is where you'd
						  -- lerp the visualHealth value or something
	local per = #guis / max

	for bin, gui in ipairs(guis) do
		local amount = math.clamp(visualHealth - (bin-1)*per, 0, per)
		gui.Size = UDim2.fromScale(amount / per, 1)
	end
end

-- call Update every frame or whatever
3 Likes

Thanks, this method looks much cleaner and waaay smaller than what I had.

what is “max” in this situation

humanoid.MaxHealth or however you track maximum health