Health script doesnt work

hey there, I have a health script that should disappear using a tween once the players health is full,
and once the player is damaged, or health goes below full, then the bar reappears, but nothing is working, ive tried debugging and others. no errors in the output either. here is the script:

local runService = game:GetService("RunService")
local players = game:GetService("Players")
local character = players.LocalPlayer.Character
repeat runService.Heartbeat:Wait() until players.LocalPlayer
local humanoid = character.Humanoid

runService.Heartbeat:Connect(function()
	local hp = game.Players.LocalPlayer.Character.Humanoid.Health/100
	script.Parent:TweenSize(UDim2.new(hp,0,1,0),Enum.EasingDirection.In,Enum.EasingStyle.Bounce,0.15)
	runService.Heartbeat:Wait()
end)

local TweenService = game:GetService("TweenService")
local HealthBar = players.LocalPlayer.PlayerGui.Health.HealthFrame.HealthBar
local HealthBackground = players.LocalPlayer.PlayerGui.Health.HealthFrame


local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween = TweenService:Create(HealthBar, tweenInfo, {Transparency = 1})

HealthBackground.Transparency = HealthBackground.Transparency

local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween2 = TweenService:Create(HealthBackground, tweenInfo, {Transparency = 1})

humanoid.HealthChanged:Connect(function(health)
if health >= 99 then
	tween:Play()
	tween2:Play()

else
	HealthBar.Visible = false
	HealthBackground.Visible = false
	end
end)

I have a question why are you doing while true do then runservice.Heartbeat

its a way better alternative then wait()

You know what you should be doing right, while true do is a worse version of RunService.Heartbeat. You shouldn’t be using both. While true do runs on every frame, Heartbeat is better and what you should be using instead of While true do RunService | Roblox Creator Documentation you can read it here for better explanation

1 Like

i have no idea how (maybe because while runs on frame), but that solved it, thanks!
EDIT: nevermind, lol

wait, wait, for some reason, now the tweens wont work. here is the code again:

local runService = game:GetService("RunService")
local players = game:GetService("Players")
local character = players.LocalPlayer.Character
repeat runService.Heartbeat:Wait() until players.LocalPlayer
local humanoid = character.Humanoid

runService.Heartbeat:Connect(function()
	local hp = game.Players.LocalPlayer.Character.Humanoid.Health/100
	script.Parent:TweenSize(UDim2.new(hp,0,1,0),Enum.EasingDirection.In,Enum.EasingStyle.Bounce,0.15)
	runService.Heartbeat:Wait()
end)

local TweenService = game:GetService("TweenService")
local HealthBar = players.LocalPlayer.PlayerGui.Health.HealthFrame.HealthBar
local HealthBackground = players.LocalPlayer.PlayerGui.Health.HealthFrame
HealthBar.Transparency = HealthBar.Transparency

local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween = TweenService:Create(HealthBar, tweenInfo, {Transparency = 1})

HealthBackground.Transparency = HealthBackground.Transparency

local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween2 = TweenService:Create(HealthBackground, tweenInfo, {Transparency = 1})

humanoid.HealthChanged:Connect(function(health)
if health >= 99 then
	tween:Play()
	tween2:Play()

else
	HealthBar.Visible = false
	HealthBackground.Visible = false
	end
end)

I see you’re tweening the transparency but I can help you make this shorter

1 Like

Why are you defining health bars transparency? That’s the issue, Transparency is a property already of the bar

1 Like

This is also a local script right? Just to be sure

You could just connect it like this:

local humanoid -- define the humanoid
humanoid:GetPropertyChangedSignal("Health"):Connect(function()
   -- tween the bar here to health amount
end)

The reason it won’t work is because you have 2 loops before the actual healing. Also, use this as wait()

local RunService = game:GetService(“RunService”)
local HB = RunService.Heartbeat

local function wait(number)
    local start = os.clock()
    
    while os.clock() - start < number do
        HB:Wait()
    end

    return os.clock() - start
end
wait(5)

Edit:

I commented what you need to fix:

local runService = game:GetService("RunService")
local players = game:GetService("Players")
local character = players.LocalPlayer.Character
repeat runService.Heartbeat:Wait() until players.LocalPlayer
local humanoid = character.Humanoid
--while true do
--	hp = game.Players.LocalPlayer.Character.Humanoid.Health/100
--	script.Parent:TweenSize(UDim2.new(hp,0,1,0),Enum.EasingDirection.In,Enum.EasingStyle.Bounce,0.15)
--	runService.Heartbeat:Wait()
--end

local TweenService = game:GetService("TweenService")
local HealthBar = players.LocalPlayer.PlayerGui.Health.HealthFrame.HealthBar
local HealthBackground = players.LocalPlayer.PlayerGui.Health.HealthFrame
HealthBar.Transparency = HealthBar.Transparency

local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween = TweenService:Create(HealthBar, tweenInfo, {Transparency = 0})

HealthBackground.Transparency = HealthBackground.Transparency

local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween2 = TweenService:Create(HealthBackground, tweenInfo, {Transparency = 0})
humanoid.HealthChanged:Connect(function(health)
if health <= 99 then
	--tween:Play()
	--tween2:Play()
	print("health is about full")
	game.StarterGui.Health.HealthFrame.Visible = true
	HealthBar.Visible = true
	HealthBackground.Visible = true
else
	game.StarterGui.Health.HealthFrame.Visible = false
	HealthBar.Visible = false
	HealthBackground.Visible = false
	print("healh is less than full")
	end
end)

local script in starter character scripts

ill try that, but here is the updated script;

local runService = game:GetService("RunService")
local players = game:GetService("Players")
local character = players.LocalPlayer.Character
repeat runService.Heartbeat:Wait() until players.LocalPlayer
local humanoid = character.Humanoid

runService.Heartbeat:Connect(function()
	local hp = game.Players.LocalPlayer.Character.Humanoid.Health/100
	script.Parent:TweenSize(UDim2.new(hp,0,1,0),Enum.EasingDirection.In,Enum.EasingStyle.Bounce,0.15)
	runService.Heartbeat:Wait()
end)

local TweenService = game:GetService("TweenService")
local HealthBar = players.LocalPlayer.PlayerGui.Health.HealthFrame.HealthBar
local HealthBackground = players.LocalPlayer.PlayerGui.Health.HealthFrame


local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween = TweenService:Create(HealthBar, tweenInfo, {Transparency = 1})

HealthBackground.Transparency = HealthBackground.Transparency

local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween2 = TweenService:Create(HealthBackground, tweenInfo, {Transparency = 1})

humanoid.HealthChanged:Connect(function(health)
if health >= 99 then
	tween:Play()
	tween2:Play()

else
	HealthBar.Visible = false
	HealthBackground.Visible = false
	end
end)

the reason this exist:

runService.Heartbeat:Connect(function()
	local hp = game.Players.LocalPlayer.Character.Humanoid.Health/100
	script.Parent:TweenSize(UDim2.new(hp,0,1,0),Enum.EasingDirection.In,Enum.EasingStyle.Bounce,0.15)
	runService.Heartbeat:Wait()
end)

makes the health bar look smoother; im pretty sure it doesnt have anything to do with the problem

that doesnt do anything; im pretty sure humanoid.HealthChanged:Connect(function(health) is better for what im trying to do

Updated script

repeat wait() until game:IsLoaded() -- Better way to do this. If you are waiting for the player to exist, please use this instead. 

local runService = game:GetService("RunService")
local players = game:GetService("Players")
local plr = players.LocalPlayer
local character = plr.Character or plr.CharacterAdded:Wait()

local function wait(number) -- This is the most accurate way to use wait(), also, you don't need to be afraid of normal wait()
	local start = os.clock()

	while os.clock() - start < number do
		runService.Heartbeat:Wait()
	end

	return os.clock() - start
end

local humanoid = character.Humanoid

local function healthBar() -- add healthBar() to your code to do this function. 
	local hp = game.Players.LocalPlayer.Character.Humanoid.Health/100
	script.Parent:TweenSize(UDim2.new(hp,0,1,0),Enum.EasingDirection.In,Enum.EasingStyle.Bounce,0.15)
	wait(0.01)
end


local TweenService = game:GetService("TweenService")
local HealthBar = players.LocalPlayer.PlayerGui.Health.HealthFrame.HealthBar
local HealthBackground = players.LocalPlayer.PlayerGui.Health.HealthFrame

local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween = TweenService:Create(HealthBar, tweenInfo, {Transparency = 1})

HealthBackground.Transparency = HealthBackground.Transparency

local tweenInfo = TweenInfo.new(
	1, -- Time
	Enum.EasingStyle.Quad, -- EasingStyle
	Enum.EasingDirection.In, -- EasingDirection
	0, -- RepeatCount (when less than zero the tween will loop indefinitely)
	false, -- Reverses (tween will reverse once reaching it's goal)
	0 -- DelayTime
)

local tween2 = TweenService:Create(HealthBackground, tweenInfo, {Transparency = 1})

humanoid.HealthChanged:Connect(function(health)
	if health >= 99 then
		tween:Play()
		tween2:Play()
	else
		HealthBar.Visible = false
		HealthBackground.Visible = false
	end
end)

Actually it does.

It’s redundant to have a loop connected when the data remains idle. It’s better to connect it so it fires only when it changes. Yes you can use HealthChanged since it’ll give you the health as a parameter. Then just tween the instance with override set to true in :TweenSize().

local tick_ = os.clock()
local thread_exists = false

humanoid.HealthChanged:Connect(function(health)
   tick_ = os.clock()
   bar:TweenSize(UDim2.new(health/100,0,1,0), "Out", "Linear", 0.1, true)
   if not thread_exists then
      thread_exists = true
      -- tween transparency to 0 (visible)
      while math.abs(os.clock()-tick_)<=3 do -- a 3 second wait time to set to invisible
         wait()
      end
      -- tween transparency to 1 (invisible)
      thread_exists = false
   end
end)

Instead of tick(), you should use os.clock(). tick is going to be deprecated soon.

2 Likes

still, that doesnt work. also, i would rather use RunService for Wait()

You’re right, thanks. I updated the script accordingly