How to make a resetting healthbar gui of npc from a player screen?

So, I’m creating a Healthbar GUI for this NPC in my game, I tried using localscript to make the healthbar works. Yes it works but when the NPC respawns the whole healthbar doesn’t reset completely to full width.

Are there any ways I could possibly make a fully working Boss HP Thingy like GUI?

This is my localscript:

local boss = game.Workspace:WaitForChild("NPC"):WaitForChild("Humanoid")

boss:GetPropertyChangedSignal("Health"):Connect(function()
	script.Parent.Size = UDim2.new(boss.Health/ boss.MaxHealth, 0, 1, 0)
end)

This is in-game (Which is right):
pb1

The NPC is dead and the Healthbar is 0 value too:
pb2

The NPC respawn again but the healthbar didn’t reset:
pb3

This is what it looks like on the explorer:
pb4

This is probably due to the fact that when the NPC respawns, the boss variable would need to be redefined so that it knows the new humanoid. The humanoid your variable is currently directed to will be nil once the NPC respawns.

1 Like

Hey there, when the character dies, it is deleted and readded, thus a new humanoid is instanced into the game. On death, you need to yield and wait for the character to respawn fully, and then reactivate the code you have. So here is how I would do it.

workspace.DescendantAdded:Connect(function(des)
    if des.Name == "NPC" then
        local boss = des:WaitForChild("Humanoid")

        local signal = boss:GetPropertyChangedSignal("Health"):Connect(function()
	    script.Parent.Size = UDim2.new(boss.Health/ boss.MaxHealth, 0, 1, 0)
        end)
        local deathsig = boss.Humanoid.Died:Connect(function()
            signal:Disconnect()
        end)
        deathsig:Disconnect()
    end
end)
2 Likes

I’d change it to a loop, like such-

while wait() do
script.Parent.Size = UDim2.new(boss.Health/ boss.MaxHealth, 0, 1, 0)
end

No you should not do this. While wait() loops are incredibly inefficient and should not be used whenever possible (99% of the time).

I think it depends on what you’re using the loop for. But I don’t really know

Property changed signal works as intended. Your code would also not work after the NPC died as the boss no longer exists. Plus, you are running that code constantly, which is a waste of resources. By using propertychangedsignal, you are only running the code when it has to run.

I tried pasting your text on the localscript but now the healthbar doesn’t work.

Hey, are there any errors in the log? If not, it is likely because the npc was in the workspace on start. Try killing it and seeing if it works the next time around.

Like Official_MrBob101 said, loops aren’t great but try this-

while wait() do
if game.Workspace:WaitForChild(“NPC”) then
local boss = game.Workspace:WaitForChild(“NPC”):WaitForChild(“Humanoid”)
script.Parent.Size = UDim2.new(boss.Health/ boss.MaxHealth, 0, 1, 0)
end
end

Again this wont work. When the NPC dies, it will be reinstanced into the game. Again a while loop is not needed here and is incredibly inefficient.

-This thing works but, Do I need to kill it first to make the healthbar works?
-Also when it respawn the greenbar doesnt appear, it appears only when the npc takes damage.

(Im sorry, Im new in programming)

No that is ok! I thought this would happen. Here is the updated code, which should work. Good luck :slight_smile:

local boss = workspace:WaitForChild("NPC"):WaitForChild("Humanoid") --We need to run the code without a property changed signal for the first time it is in the game
script.Parent.Size = UDim2.new(boss.Health/ boss.MaxHealth, 0, 1, 0)
local signal = boss:GetPropertyChangedSignal("Health"):Connect(function()
    script.Parent.Size = UDim2.new(boss.Health/ boss.MaxHealth, 0, 1, 0)
end)
local deathsig = boss.Humanoid.Died:Connect(function()
    signal:Disconnect()
end)
deathsig:Disconnect()
boss = nil

workspace.DescendantAdded:Connect(function(des)
    if des.Name == "NPC" then
        local boss = des:WaitForChild("Humanoid")
        script.Parent.Size = UDim2.new(boss.Health/ boss.MaxHealth, 0, 1, 0)
        local signal = boss:GetPropertyChangedSignal("Health"):Connect(function()
	    script.Parent.Size = UDim2.new(boss.Health/ boss.MaxHealth, 0, 1, 0)
        end)
        local deathsig = boss.Humanoid.Died:Connect(function()
            signal:Disconnect()
        end)
        deathsig:Disconnect()
    end
end)

i tested my loop in my own studio world and it works completely fine with no flaws.

Using that type of loop is incredibly inefficient as I have said multiple times. You should rely on a robust method for handling this sort of stuff. Just because it is easy to do doesn’t mean it is the best way. And just because it works fine once does not mean it will always be fine. :WaitForChild() is only meant to be used when needed, so running it every possible tick in that form of loop is bad practice and slow.

You’re right but if it has no flaws there’s no reason to not try it.

it said nil

image

Try removing the line boss = nil which I had below it.

i’ll leave you two to it

30 charssss

You want to provide the most insightful feedback with scripting support. This person is a learner, so it is best to give them advice that will set them up well. If I were to tell them to do what you are suggesting, they will then use that method in the future. Unbeknownst to them, they won’t realize it is madly inefficient and when making a more complex game, they could suffer from severe performance issues. That is why it is important to not take the quick route when providing a suggestion.

1 Like