Updating StarterGui across all clients


local StarterGui = game:GetService("StarterGui")
local PlayerListGui = StarterGui:FindFirstChild("PlayerListGui")

game.Players.PlayerAdded:Connect(function(Player)
	
	local TextLabel = Instance.new("TextLabel", PlayerListGui.ScrollingFrame)
	TextLabel.Text = Player.Name
	TextLabel.BackgroundTransparency = 0.5
	TextLabel.BorderSizePixel = 0
	TextLabel.TextSize = 15
	TextLabel.Font = Enum.Font.ArialBold
	
	PlayerListGui.ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, #PlayerListGui.ScrollingFrame:GetChildren() * 50)
	
end)

game.Players.PlayerRemoving:Connect(function(Player)
	
	for _,TextLabel in pairs(PlayerListGui.ScrollingFrame:GetChildren()) do
		if TextLabel:IsA("TextLabel") and TextLabel.Text == Player.Name then
			TextLabel:Destroy()
		end
	end
	
	PlayerListGui.ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, #PlayerListGui.ScrollingFrame:GetChildren() * 50)
	
end)

Trying to make a custom player lists, it works but only after the player resets does it update the list. Can someone help me out here? No idea what to do.

StarterGui is cloned to player.PlayerGui when they join the game and if the player is reset.

so instead of using StarterGui, you’ll want to use player.PlayerGui
because every player has their own GUI.

game.Players.PlayerAdded:Connect(function(Player)

    for i = 1, #game.Players:GetChildren() do
        local p = game.Players:GetChildren[i]
        local playerGui = p.PlayerGui
	local PlayerListGui = playerGui:FindFirstChild("PlayerListGui")
	local TextLabel = Instance.new("TextLabel", PlayerListGui.ScrollingFrame)

        --place a copy into starter gui, so new players will automatically gain previous textlabels.
        local TextLabel2 = TextLabel:Clone()
        TextLabel2.Parent = game.StarterGui.PlayerListGui

         --set the name of the textlabel to player.Name, so you wont need a sub loop to find it.
        TextLabel.Name = Player.Name
        
	TextLabel.Text = Player.Name
	TextLabel.BackgroundTransparency = 0.5
	TextLabel.BorderSizePixel = 0
	TextLabel.TextSize = 15
	TextLabel.Font = Enum.Font.ArialBold
	
	PlayerListGui.ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, #PlayerListGui.ScrollingFrame:GetChildren() * 50)
    end
end)

game.Players.PlayerRemoving:Connect(function(Player)
    for i = 1, #game.Players:GetChildren() do
        local p = game.Players:GetChildren()[i]
	local playerGui = p.PlayerGui
	local PlayerListGui = playerGui.PlayerListGui
        local TextLabel = PlayerListGui:FindFirstChild(player.Name)
        local TextLabel2 = game.StarterGui.PlayerListGui:FindFirstChild(player.Name)

        if(TextLabel) then
	    TextLabel:Destroy()
	end

        if(TextLabel2)then
            TextLabel2:Destroy()
        end

	PlayerListGui.ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, #PlayerListGui.ScrollingFrame:GetChildren() * 50)
    end
end)


Its not recommended to directly update Player GUIs from the server. Use a remote event and :FireAllClients() to achieve what you need.

agreed, especially when your talking about input, viewport frames, image labels or 2d animations.
i don’t think adding simple GuiObjects (like text labels) would be much of an issue though.

also using the server would be easier in this case, considering he has to grab other players’ names, and its nice sometimes to use StarterGui so you can quickly give new players the up-to-date gui. (instead of running a separate loop for the new player and another loop for the rest of the players)

@JamieWallace_RBLX just remember that every player has their own GUI and you can grab player.PlayerGui to update it, even on the server.

You can use a local script to update the player list in the player’s PlayerGui.

game.Players.PlayerAdded:Connect(function(Player)
    local PlayerGui = game.Players.LocalPlayer.PlayerGui
    local PlayerListGui = PlayerGui.PlayerListGui
   --do updates
end)

--do the same for the PlayerRemoving event

I don’t think PlayerAdded and PlayerRemoving work in LocalScripts, because the player loads before their local scripts do. (someone correct me if im wrong)

1 Like

How the StarterGui works

Let’s say there’s a salesman, and he’s selling hats. People are constantly walking down the road and they all buy a hat from him when they pass him. Now one of those people wants to write his name on his hat, what would he do? He wouldn’t write his name on the salesman’s hats, he would write his name on his own hat. Think of the StarterGui as the salesman and the people walking buy as players who just joined the game or just reset. Every player gets a copy of everything in StarterGui when they join, and they can only see and interact their copy. What you’re doing is changing the startergui’s hats, not the players’ hats, so they don’t see the difference until they reset and buy the new version.

How can you get access to the player’s copy?

Pretty simple, whenever someone joins the game their player instance is added to the players service. You can test this out yourself, playtest and you’ll see your player inside “Players.” Now inside your player there are a couple folders, one of them is called “PlayerGui.” If you check inside the playergui, you’ll see an exact copy of everything in the StarterGui, those are the ones you bought when you joined the game. Now if you go to the StarterGui while you’re playtesting and delete one of the GUIs there, you would still see that GUI as if you never deleted it. But if you delete one of the GUIs in your playergui, it will disappear.

How can I get my script to work?

Right now all you’re doing is changing the Startergui’s version, you’ll have to also change all the players’ versions, like this:


local StarterGui = game:GetService("StarterGui")
local PlayerListGui = StarterGui:FindFirstChild("PlayerListGui")

game.Players.PlayerAdded:Connect(function(Player)
	-- This will change the StarterGui's version
	local TextLabel = Instance.new("TextLabel", PlayerListGui.ScrollingFrame)
	TextLabel.Text = Player.Name
	TextLabel.BackgroundTransparency = 0.5
	TextLabel.BorderSizePixel = 0
	TextLabel.TextSize = 15
	TextLabel.Font = Enum.Font.ArialBold
	PlayerListGui.ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, #PlayerListGui.ScrollingFrame:GetChildren() * 50)
	
      -- This will change the players' versions
      for _, Player in pairs(game.Players:GetChildren()) do
    
 local PlayerGui = Player:WaitForChild("PlayerGui")
 local PlayerListGui = PlayerGui:WaitForChild( "PlayerListGui")

	local TextLabel = Instance.new("TextLabel", PlayerListGui.ScrollingFrame)
	TextLabel.Text = Player.Name
	TextLabel.BackgroundTransparency = 0.5
	TextLabel.BorderSizePixel = 0
	TextLabel.TextSize = 15
	TextLabel.Font = Enum.Font.ArialBold
	PlayerListGui.ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, #PlayerListGui.ScrollingFrame:GetChildren() * 50)
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	--The StarterGui's version
local PlayerListGui = StarterGui.PlayerListGui

	for _,TextLabel in pairs(PlayerListGui.ScrollingFrame:GetChildren()) do
		if TextLabel:IsA("TextLabel") and TextLabel.Text == Player.Name then
			TextLabel:Destroy()
		end
	end
	
	PlayerListGui.ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, #PlayerListGui.ScrollingFrame:GetChildren() * 50)
	
      -- The players' versions 
for _, Player in pairs(game.Players:GetChildren()) do

local PlayerListGui = Player.PlayerGui.PlayerListGui

for _,TextLabel in pairs(PlayerListGui.ScrollingFrame:GetChildren()) do
		if TextLabel:IsA("TextLabel") and TextLabel.Text == Player.Name then
			TextLabel:Destroy()
		end
	end
	
	PlayerListGui.ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, #PlayerListGui.ScrollingFrame:GetChildren() * 50)
end
end)

Hope this helps! :slight_smile:

2 Likes

Simple. Get all players, go to all there PlayerGui folder, locate the gui and edit it.