Health Meter sometimes dissapears and reappears when health is changed

So i made a health meter gui that plays a tween and changes image at the same time when health is lost or gained. However, sometimes instead of playing the tween and changing images, it just dissapears and then reappears with the different image. Basically it’s not playing the tween, it just dissapears and reappears.

--//Variables//--
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local PlayerGui = script.Parent
local MainGui = PlayerGui:WaitForChild("MainGui")
local HMFolder = MainGui.HealthMeters
local TweenService = game:GetService("TweenService")
local TweenInform = TweenInfo.new(0.25, Enum.EasingStyle.Linear, Enum.EasingDirection.In)
--//Function//--
local function switchHealthMeter(Meter)
	for __, Img in pairs(HMFolder:GetChildren()) do
		if Img.Name == Meter.Name then
			Img.Visible = true
			Img.Size = UDim2.new(0, 120, 0, 160)
			local TweenHM = TweenService:Create(Img, TweenInform, {Size = UDim2.new(0,100,0,140)})
			TweenHM:Play()
		else
			Img.Visible = false
		end
	end
end
---------------------------------------------------------
local function onHealthChanged(Health)
	if Health > 90 and Health < 100 or Health == 100 or Health == 90 then
		switchHealthMeter(HMFolder.HealthMeter1)
	elseif Health >= 80 and Health < 90 then
		switchHealthMeter(HMFolder.HealthMeter2)
	elseif Health >= 70 and Health < 80 then
		switchHealthMeter(HMFolder.HealthMeter3)
	elseif Health >= 60 and Health < 70 then
		switchHealthMeter(HMFolder.HealthMeter4)
	elseif Health >= 50 and Health < 60 then
		switchHealthMeter(HMFolder.HealthMeter5)
	elseif Health >= 40 and Health < 50 then
		switchHealthMeter(HMFolder.HealthMeter6)
	elseif Health >= 30 and Health < 40 then
		switchHealthMeter(HMFolder.HealthMeter7)
	elseif Health >= 1 and Health < 30 then
		switchHealthMeter(HMFolder.HealthMeter8)
	elseif Health <= 0 then
		switchHealthMeter(HMFolder.HealthMeter9)
	end
end
--//Connection//--
Humanoid.HealthChanged:Connect(onHealthChanged)
2 Likes

Can you explain in more detail how the health bar is actually setup in the game or provide screenshots of it?

1 Like

--//Function//--
local function switchHealthMeter(Meter)
	for __, Img in pairs(HMFolder:GetChildren()) do
		if Img.Name == Meter.Name then
			Img.Visible = true
			Img.Size = UDim2.new(0, 120, 0, 160)
			local TweenHM = TweenService:Create(Img, TweenInform, {Size = UDim2.new(0,100,0,140)})
			TweenHM:Play()
		else
			Img.Visible = false
		end
	end
end
---------------------------------------------------------
local function onHealthChanged(Health)
	if Health > 90 and Health < 100 or Health == 100 or Health == 90 then
		switchHealthMeter(HMFolder.HealthMeter1)
	elseif Health >= 80 and Health < 90 then
		switchHealthMeter(HMFolder.HealthMeter2)
	elseif Health >= 70 and Health < 80 then
		switchHealthMeter(HMFolder.HealthMeter3)
	elseif Health >= 60 and Health < 70 then
		switchHealthMeter(HMFolder.HealthMeter4)
	elseif Health >= 50 and Health < 60 then
		switchHealthMeter(HMFolder.HealthMeter5)
	elseif Health >= 40 and Health < 50 then
		switchHealthMeter(HMFolder.HealthMeter6)
	elseif Health >= 30 and Health < 40 then
		switchHealthMeter(HMFolder.HealthMeter7)
	elseif Health >= 1 and Health < 30 then
		switchHealthMeter(HMFolder.HealthMeter8)
	elseif Health <= 0 then
		switchHealthMeter(HMFolder.HealthMeter9)
	end
end
--//Connection//--
Humanoid.HealthChanged:Connect(onHealthChanged)

Basically, for example, if the player’s health > 90 and health < 100 or his health == 100 or health == 90,
then use the custom switchHealthMeter function to make the FULL HEALTH meter GUI visible, while all the other ones aren’t. Then, same thing with the rest, except replace the FULL HEALTH meter GUI with the one that fits the amount of health.

image

What did you want the tween to do? Sorry, I’m new to tweens and stuff like that.

1 Like

Basically i just wanted it to grow in size instantly, then reduce back to it’s original size. Like this :

1 Like

Bump for this post, please answer.

1 Like

The issue with the first function is that you set the HP window size to 0 initially, then increase it through a Tween afterward. Provide an additional Tween option if the window already exists
I misunderstood slightly, try to give it a shot

local function switchHealthMeter(Meter)
	local ThisImg = nil
	for __, Img in pairs(HMFolder:GetChildren()) do
		if Img.Name == Meter.Name then
			ThisImg = Img
		else
			Img.Visible = false
		end
	end
	ThisImg.Visible = true
	ThisImg.Size = UDim2.new(0, 120, 0, 160)
	local TweenHM = TweenService:Create(ThisImg, TweenInform, {Size = UDim2.new(0,100,0,140)})
	TweenHM:Play()
end
1 Like

It still doesn’t work for some reason?

1 Like

I apologize, I might have done something wrong. It’s probably correct this way
If this isn’t right, please explain or show what’s happening

local function switchHealthMeter(Meter)
	local ThisImg = nil
	for __, Img in pairs(HMFolder:GetChildren()) do
		if Img.Name == Meter.Name then
			ThisImg = Img
		else
			Img.Visible = false
		end
	end
	ThisImg.Size = UDim2.new(0, 0, 0, 0)
	ThisImg.Visible = true
	local TweenHM = TweenService:Create(ThisImg, TweenInform, {Size = UDim2.new(0,100,0,140)})
	TweenHM:Play()
end
1 Like

It won’t work, also the problem is described at the beginning of the post :+1:

1 Like

How your health changes? Like this 8/sliced pie - is it just images for 1, 2, 3, 4… pie pieces TOGETHER or separate?

1 Like

It’s 9 image labels which are the exact same except one slice of health is gone for each of them

1 Like

Then your problem is that they are loading. Try to preload them.
ContentProvider:PreloadAsync()

2 Likes

Where should i put that line in the code?

It could be because of the for loop. For loops don’t do things straight away and this is a problem I’ve had before. Instead of a for loop you could do this:

local ui = HMFolder:FindFirstChild(Meter.Name)
if ui then
—code
end

This might not be the problem, BUT it is better to do this since it uses less ram or is better for performance.
And plus it gives like a slight delay anyways, so it’s better to do this

Try getting rid of this line and see what happens. It may not be ideal but it may help us diagnose the issue.

Img.Visible = false

In separate script, parented under ReplicatedFirst. That line usually used to make loading. To make it work, you need use it like this:

local ContentProvider = game:GetService("ContentProvider")

local Img1 = "rbxassetid://YOURID"
local Img2  = "rbxassetid://YOURID"

local assets = {Img1 , Img2}

ContentProvider:PreloadAsync(assets)

I replaced it with print(“cool”) and it when i take damage it waits around a second and switches to the corresponding health meter, but with no tween, and also it prints cool multiple times in the output.

ofc it would print cool multiple times because there are multiple health meters, no? also, try @GamEditoPro’s solution

you could also try setting the transparency to 0 and 1 instead of changing the visibility as that shouldn’t unload the image

Much better solution if image is unloads is using sprite sheets. Like, single image with all images combined. Then with use of RectSize/Offset you can change health meter like you want. Personally I use sprite sheets a lot:


(Example of sprite sheet)

1 Like