I have this armour bar GUI that is cloned from ReplicatedStorage and gets put into a ScreenGui in the PlayerGui. Problem is this only works once and if the player dies or resets, it doesn’t clone again. What could be the reason?
local armourBar = game:GetService("ReplicatedStorage"):WaitForChild("armourBar")
local armourMax = 50
function updateGui(gui, armourAmount)
local y = armourAmount / armourMax
gui:WaitForChild("container"):WaitForChild("bar").Size = UDim2.new(y, 0, 1, 0)
end
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local humanoid = character:WaitForChild("Humanoid")
local newGui = armourBar:Clone()
newGui.Parent = player:WaitForChild("PlayerGui"):WaitForChild("MainScreenGui"):WaitForChild("playerBars")
local armour = armourMax
local oldHealth = humanoid.Health
updateGui(newGui, armour)
humanoid.HealthChanged:Connect(function(newHealth)
if armour > 0 and newHealth < oldHealth then
local change = oldHealth - newHealth
humanoid.Health = humanoid.MaxHealth
armour = armour - change
local healthMinus = math.clamp(armour, -humanoid.MaxHealth, 0)
updateGui(newGui, math.clamp(armour, 0, armourMax))
oldHealth = humanoid.MaxHealth + healthMinus
humanoid.Health = oldHealth
end
end)
end)
end)
local armourBar = game:GetService("ReplicatedStorage"):WaitForChild("armourBar")
local armourMax = 50
function updateGui(gui, armourAmount)
local y = armourAmount / armourMax
gui:WaitForChild("container"):WaitForChild("bar").Size = UDim2.new(y, 0, 1, 0)
end
for _, Player in ipairs (game:GetService("Players"):GetPlayers()) do
Player.CharacterAdded:Connect(function(character)
local humanoid = character:WaitForChild("Humanoid")
local newGui = armourBar:Clone()
newGui.Parent = Player:WaitForChild("PlayerGui"):WaitForChild("MainScreenGui"):WaitForChild("playerBars")
local armour = armourMax
local oldHealth = humanoid.Health
updateGui(newGui, armour)
humanoid.HealthChanged:Connect(function(newHealth)
if armour > 0 and newHealth < oldHealth then
local change = oldHealth - newHealth
humanoid.Health = humanoid.MaxHealth
armour = armour - change
local healthMinus = math.clamp(armour, -humanoid.MaxHealth, 0)
updateGui(newGui, math.clamp(armour, 0, armourMax))
oldHealth = humanoid.MaxHealth + healthMinus
humanoid.Health = oldHealth
end
end)
end)
end
In addition to this, you’re only listening to the character being added once. What you need to do is ensure if the character already exists, and then run the callback on that character. Also add a listener for CharacterAdded and that will run if the character didnt exist yet. I provided a code snippet below on how to properly handle PlayerAdded & CharacterAdded
local Players = game:GetService("Players")
-- Player added:
local function playerAdded(player)
-- character added callback
local function characterAdded(character)
-- do the UI clone here
end
if player.Character then
-- will run if character already exists
characterAdded(player.Character)
end
-- runs when character is added
player.CharacterAdded:Connect(characterAdded)
end
-- The for loop gets players in game who were added before the player added listener could connect
for _, player in ipairs(Players:GetPlayers()) do
playerAdded(player)
end
-- Each time a new player is added after for loop
Players.PlayerAdded:Connect(playerAdded)
local Players = game:GetService("Players")
local armourBar = game:GetService("ReplicatedStorage"):WaitForChild("armourBar")
local armourMax = 50
function updateGui(gui, armourAmount)
local y = armourAmount / armourMax
gui:WaitForChild("container"):WaitForChild("bar").Size = UDim2.new(y, 0, 1, 0)
end
-- Player added:
local function playerAdded(player)
-- character added callback
local function characterAdded(character)
local humanoid = character:WaitForChild("Humanoid")
local newGui = armourBar:Clone()
newGui.Parent = player:WaitForChild("PlayerGui"):WaitForChild("MainScreenGui"):WaitForChild("playerBars")
local armour = armourMax
local oldHealth = humanoid.Health
updateGui(newGui, armour)
humanoid.HealthChanged:Connect(function(newHealth)
if armour > 0 and newHealth < oldHealth then
local change = oldHealth - newHealth
humanoid.Health = humanoid.MaxHealth
armour = armour - change
local healthMinus = math.clamp(armour, -humanoid.MaxHealth, 0)
updateGui(newGui, math.clamp(armour, 0, armourMax))
oldHealth = humanoid.MaxHealth + healthMinus
humanoid.Health = oldHealth
end
end)
end
if player.Character then
-- will run if character already exists
characterAdded(player.Character)
end
-- runs when character is added
player.CharacterAdded:Connect(characterAdded)
end
-- The for loop gets players in game who were added before the player added listener could connect
for _, player in ipairs(Players:GetPlayers()) do
playerAdded(player)
end
-- Each time a new player is added after for loop
Players.PlayerAdded:Connect(playerAdded)
It still doesn’t come back after the player dies. Could this be because this script is in ServerScriptService?
Try setting the ResetOnSpawn property for the MainScreen gui to false, and see what happens. It might be resetting when the player dies. Also are there any errors/warning in the output console when they respawn?
I added a for loop before the variables as when the player reset the armor bar wouldn’t get rid of the old one but now the health bar isn’t updating either.
local Players = game:GetService("Players")
local armourBar = game:GetService("ReplicatedStorage"):WaitForChild("armourBar")
local armourMax = 50
function updateGui(gui, armourAmount)
local y = armourAmount / armourMax
gui:WaitForChild("container"):WaitForChild("bar").Size = UDim2.new(y, 0, 1, 0)
end
-- Player added:
local function playerAdded(player)
-- character added callback
local function characterAdded(character)
for _, v in ipairs(player:WaitForChild("PlayerGui"):WaitForChild("MainScreenGui"):WaitForChild("playerBars"):GetChildren()) do
if v.Name == "armourBar" then
v:Destroy()
end
end
local humanoid = character:WaitForChild("Humanoid")
local newGui = armourBar:Clone()
newGui.Parent = player:WaitForChild("PlayerGui"):WaitForChild("MainScreenGui"):WaitForChild("playerBars")
local armour = armourMax
local oldHealth = humanoid.Health
updateGui(newGui, armour)
humanoid.HealthChanged:Connect(function(newHealth)
if armour > 0 and newHealth < oldHealth then
local change = oldHealth - newHealth
humanoid.Health = humanoid.MaxHealth
armour = armour - change
local healthMinus = math.clamp(armour, -humanoid.MaxHealth, 0)
updateGui(newGui, math.clamp(armour, 0, armourMax))
oldHealth = humanoid.MaxHealth + healthMinus
humanoid.Health = oldHealth
end
end)
end
if player.Character then
-- will run if character already exists
characterAdded(player.Character)
end
-- runs when character is added
player.CharacterAdded:Connect(characterAdded)
end
-- The for loop gets players in game who were added before the player added listener could connect
for _, player in ipairs(Players:GetPlayers()) do
playerAdded(player)
end
-- Each time a new player is added after for loop
Players.PlayerAdded:Connect(playerAdded)
Can’t you think by yourself, even a tiny little bit?
When the player respawns, the oldHealth variable will equal to zero and the newHealth variable will equal to a hundred: therefore, the if conditional will return false and won’t execute the code instructions that modify the health bar status.
As a side note, I recommend you to add a tween instead of just resizing the bar.