Spectating players health and armor bars not updating

I have this spectate LocalScript and what I’m trying to do is to have the player that’s being spectated also show their armor and health values. The issue is that currently only the health bar actively updates according the the spectated players’ health. But for the armor that only updates once the player stops spectating and then goes back to spectate again (video demonstration below).

LocalScript:

local replicatedStorage = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
local Workspace = game:GetService("Workspace")

local player = players.LocalPlayer

local aliveFolder = Workspace:WaitForChild("Alive") --folder containing all currently alive players 
local camera = Workspace.CurrentCamera

local spectateFrame = script.Parent
local nextButton = spectateFrame:WaitForChild("nextButton")
local previousButton = spectateFrame:WaitForChild("previousButton")
local spectateName = spectateFrame:WaitForChild("spectateName")

local currentIndex = 1
local playerList = {}

local totalArmor = 50 --max value for gui sizing

aliveFolder.ChildRemoved:Connect(function()
	local newPlayerList = {}

	for plrs, plr in pairs(players:GetPlayers()) do
		if plr ~= player then
			if plr.Character.Parent == aliveFolder then
				table.insert(newPlayerList, plr.Name)
			end			
		end
	end

	playerList = newPlayerList
end)

function updateSpectator()
	local foundPlayer = players:FindFirstChild(playerList[currentIndex])
	local humanoid = foundPlayer.Character:WaitForChild("Humanoid")
	
	if foundPlayer then
		spectateName.Text = foundPlayer.Name 
		camera.CameraSubject = foundPlayer.Character
		
		if script.Parent.Parent:FindFirstChild("spectatePlayerBars") then
			script.Parent.Parent:FindFirstChild("spectatePlayerBars"):Destroy()
		end
		
		local templateClone = script.spectatePlayerBars:Clone() --template containing the health and armor bars
		templateClone.Parent = script.Parent.Parent
		
		local healthBar = templateClone:WaitForChild("HealthBar"):WaitForChild("container"):WaitForChild("bar")
		local armorBar = templateClone:WaitForChild("ArmorBar"):WaitForChild("container"):WaitForChild("bar")
		
		if foundPlayer:GetAttribute("Premium") then --if spectated player has premium gamepass then adjust max value
			totalArmor = 70
		else
			totalArmor = 50
		end
		
		local armor = humanoid:GetAttribute("armor") --armor is stored in an attribute in the humanoid for all players that is created on the server
		local newArmor = armor / totalArmor
		
		armorBar.Size = UDim2.new(if newArmor > 0.965 then 0.965 else newArmor, 0, 0.8, 0)
		
		humanoid:GetAttributeChangedSignal("armor"):Connect(function()
			print("armor attribute") --this print fires yet the armor bar doesn't adjust until the player stops spectating then goes back
			newArmor = armor / totalArmor

			armorBar.Size = UDim2.new(if newArmor > 0.965 then 0.965 else newArmor, 0, 0.8, 0) 
		end)
		
		local newHealth = humanoid.Health / humanoid.MaxHealth

		healthBar.Size = UDim2.new(if newHealth > 0.965 then 0.965 else newHealth, 0, 0.8, 0)
		
		humanoid.HealthChanged:Connect(function(Damage)
			print("health attribute")
			newHealth = Damage / humanoid.MaxHealth

			healthBar.Size = UDim2.new(if newHealth > 0.965 then 0.965 else newHealth, 0, 0.8, 0)
		end)
	end
end

nextButton.Activated:Connect(function()
	if currentIndex < #playerList then
		currentIndex = currentIndex + 1
	else
		currentIndex = 1
	end

	updateSpectator()
end)

previousButton.Activated:Connect(function()
	if currentIndex > 1 then
		currentIndex = currentIndex - 1
	else
		currentIndex = #playerList
	end

	updateSpectator()
end)

I see the mistake, basically you set newArmor, but the thing is, it doesn’t change anything. Since Armor still is the same, instead you do

newArmor = humanoid:GetAttribute("armor") / totalArmor

This is one way, or in the Connect(function() you put a variable into it. Then it is accurate to the status.

1 Like

As far as I am concerned @nayro007 should be correct. You store the “armor” attribute as variable and get its value but the variables value won’t change when the attribute changes.

Let’s say the armor is 50.

local armor = humanoid:GetAttribute("armor")

could also just be:

local armor = 50

Now let’s say the player gets hit and looses 10 armor.

local armor = humanoid:GetAttribute("armor")
-- *player looses 10 armor*
print(armor) -- this will STILL print "50"
print(humanoid:GetAttribute("armor")) -- this will print "40", as 10 armor was subtracted from the 50

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.