Leaderboard GUI script isn't working in PlayerGUI

I am creating a leaderboard UI for a game that keeps up with the top 8 players in-game on the server. It went all good until I took the frame to the PlayerGUI. The script only changes 1 TextLabel and that’s it. The rest of the script doesn’t work however there’s no errors or outputs of the issue that would give me a idea of what went wrong.

leaderboard

 local Stat = script.Parent.Parent.Stat.Value

script.Parent.PlayerFrame.Wins.Text=Stat

function CreateGui()
	return script.Parent.PlayerFrame:clone()
end

function GetTopPlayers()
	local TopPlayers={}
	local Numbers={}
	local PossiblePlayers={}
	
	local function GetPlayerWins(Player)
		if Player and Player:FindFirstChild("Checkpoints") and Player.Checkpoints:FindFirstChild(Stat) then
			return Player.Checkpoints[Stat].Value
		end
		return 0
	end
	
	for i,v in pairs(game.Players:GetPlayers()) do
		table.insert(Numbers,GetPlayerWins(v))
		table.insert(PossiblePlayers,v)
	end
	
	local function GetBiggest()
			local Biggest=math.max(unpack(Numbers))
			local Player
			
			for index,value in pairs(PossiblePlayers) do
				if Biggest==GetPlayerWins(value) then
					Player=value
					table.remove(PossiblePlayers,index)
					break
				end
			end
			for i,v in pairs(Numbers) do
				if v==Biggest then
					print("Removed: "..v.." "..Numbers[i])
					table.remove(Numbers,i)
					break
				end
			end
			return Player
	end
	
	for i = 1,#game.Players:GetPlayers() do
		local Biggest=GetBiggest()
		table.insert(TopPlayers,i,Biggest)
	end
	
	return TopPlayers
end

function UpdateGui()
	local TopPlayers=GetTopPlayers()
	
	local function ClearGuis()
		for i,v in pairs(script.Parent:GetChildren()) do
			if v.Name=="Player" then v:Destroy() end
		end
	end
	
	ClearGuis()
	
	if #TopPlayers>0 then
		for i,v in pairs(TopPlayers) do
			if i>10 then break end
			pcall(function()
			local Frame=CreateGui()
			Frame.BackgroundColor3=Color3.new(1,1,1)
			Frame.Name="Player"
			Frame.Parent=script.Parent
			Frame.Position=UDim2.new(0.05,0,i*.08,0)
			Frame.PlayerName.Text=v.Name
			Frame.Place.Text=i
			Frame.Wins.Text=tostring(v.Checkpoints[Stat].Value)
			end)
		end
	end
end

game.Players.PlayerAdded:connect(function(Player)
	UpdateGui()
	
	Player:WaitForChild("Checkpoints"):WaitForChild(Stat).Changed:connect(function()
		UpdateGui()
	end)
	
	UpdateGui()
	
end)

game.Players.PlayerRemoving:connect(function(Player)
	UpdateGui()
end)
1 Like

This is really weird. I got it to work on a Surface GUI, however it won’t work on a normal GUI which is where I want the UI to be shown at.
leaderboradguiglitch

1 Like

Players.PlayerAdded doesn’t fire for the player of the client of which the local script is executing for, nor does it execute for existing players. You can account for both of these issues by iterating over Players:GetPlayers() and executing the same ‘player joined’ code for those players, here’s a short example.

for _, Player in ipairs(game.Players:GetPlayers()) do
	--Execute code that should be ran whenever a player joins here.
end

This should be done after the ‘PlayerAdded’ and ‘PlayerRemoving’ connections have been made.

Like this?

game.Players.PlayerAdded:connect(function(Player)
	for _, Player in ipairs(game.Players:GetPlayers()) do
		Player:WaitForChild("Checkpoints"):WaitForChild(Stat).Changed:connect(function()
		UpdateGui()
	end)

	UpdateGui()
		end
end)

game.Players.PlayerRemoving:connect(function(Player)
	for _, Player in ipairs(game.Players:GetPlayers()) do
		UpdateGui()
	end
end)

I apologize btw, it’s been awhile since I’ve done scripting.

Not inside Players.PlayerAdded, it’d just be a stand-alone for loop.

Doing all of this caused a huge headache but at least it works. Thanks!