GUI not updating

I came across a fairly annoying issue trying to make a simple changing gui.
whenever I have the text change through the script it doesn’t actually change the text ingame, is there any way I can fix it? also btw there are no errors in the output and this is not done in a local script.

Code
while true do
if game.Players.NumPlayers < 2
	then
		game.StarterGui.ServerGui.Frame.TextLabel.Text = "Waiting for 2 players"
		wait(.5)
		game.StarterGui.ServerGui.Frame.TextLabel.Text = "Waiting for 2 players..."
		wait(.5)
elseif game.Players.NumPlayers >= 2
	then
        --other stuffs		
end
end
2 Likes

I assume this is in a LocalScript

Here is the problem:

You’re indexing the StarterGui. Contents of the StarterGui are cloned into a player’s PlayerGui.

Instead index the PlayerGui of your LocalPlayer!

Example code:

local client = playersService.LocalPlayer
local playerGui = client:WaitForChild("PlayerGui")

local serverGui = playerGui:WaitForChild("ServerGui")

--// and so on
6 Likes

so what you’re saying is that I should do this in a localscript instead of a normal script?
I really wouldn’t like to do that because I just want one core script that does everything

Yes, and you should be indexing the PlayerGui folder inside the client’s Player instance.

2 Likes

Remember that when a game starts, everything found in StarterGui is cloned locally, to each player, in PlayerGui.

Also remember that in infinite loops, you must add a wait():

while true do
if game.Players.NumPlayers < 2
	then
		game.StarterGui.ServerGui.Frame.TextLabel.Text = "Waiting for 2 players"
		wait(.5)
		game.StarterGui.ServerGui.Frame.TextLabel.Text = "Waiting for 2 players..."
		wait(.5)
elseif game.Players.NumPlayers >= 2
	then
        --other stuffs		
end
wait(0.5) -- Change it for what you consider necessary.
end

Anyway, game.Players.NumPlayers is not valid, to get the number of players you should do the following.

while true do
local plrs = game.Players:GetPlayers()
if #plrs < 2 then
-- Your code
elseif #plrs  >= 2 then
-- Your code
end
wait()
end
1 Like

wait, this still doesn’t solve my problem, you’re cleaning up my code, not helping me figure out how to make the gui update properly, it changes like every 30 seconds instead of every .5 seconds. printing does work though

1 Like

In the case of wait(0.5) it is just an example, so I have commented that you can change it to the number you consider necessary.
But tell me how I can continue to help you. I think what I told you, along with what EpicMetatableMoment told you, should solve your problem correctly :slight_smile:


To help you solve this a little more, can we know where the LocalScript is? (assuming it is a LocalScript)
Since if it were inside the ScreenGui that contains the Frame, and the TextLables, this could be done:

local txtLabel = script.Parent.TextLabel

while true do
local plrs = game.Players:GetPlayers()
if #plrs < 2
	then
		txtLabel.Text = "Waiting for 2 players"
		wait(.5)
		txtLabel.Text = "Waiting for 2 players..."
		wait(.5)
elseif #plrs >= 2
	then
        --other stuffs		
end
wait(30) -- Change it for what you consider necessary.
end

And having the script inside the ScreenGui, on the client, should completely solve your problem.

this is not a localscript, as I said in my original post this is a normal script, that may have been why I was getting so confused.

  1. @nanitook’s advice is perfectly relevant; they’re ensuring that your while loop actually works (adding the wait()) and providing you with the proper method (as opposed to a deprecated method) of getting the number of players in the server.

  2. I’d recommend against using a while loop in this case, since you’re repeating the same action until a certain condition is met. This can be solved using a repeat loop, as such:

local label = PATH_TO_LABEL

repeat
    label.Text = "Waiting for 2 players"
    wait(.5)
    label.Text = "Waiting for 2 players..."
    wait(.5)
until #game.Players:GetPlayers() >= 2
2 Likes

Try this.

local Players = game:GetService("Players")


Players.Changed:Connect(function()
local amount = Players:GetChildren()
if #amount < 2 then
for i,v in in ipairs(amount) do
v.PlayerGui.ServerGui.Frame.TextLabel.Text = "Waiting for 2 players"
		wait(.5)
		v.PlayerGui.ServerGui.Frame.TextLabel.Text = "Waiting for 2 players..."
		wait(.5)
elseif #amount >= 2 then
--stuff :D
end
end
end)


Using a changed function, to see if a player added, this will work!, and no need for a loop!

1 Like

Ok, and where is that script? (StarterGui, SSS, etc.)

I have the script currently located in SSS (serverscriptservice)

I don’t think this works, since you are declaring the variable at the beginning of the script, which means that the variable will be executed only when the script starts. Therefore, if the number of players changes while the script is running, the variable will not be updated.

That’s right, I fixed it, I made the script on studio, didn’t checked that

I don’t think .Changed event would fire once player is added to the game.

That is the problem, you cannot access PlayerGui from the server.

btw the reason I have the script in a while loop Is so that I can have the script repeat itself after the elseif ends

Yes you can access PlayerGui from the server.

I believe the intended effect of the label is to consistently notify the player that there’s not enough players in the server, so a loop would make sense (in order to continually add/remove the ellipsis after the sentence).

You should be using Players.PlayerAdded and Players.PlayerRemoved to detect when players enter/leave the server. In addition to that, there is a built-in method to retrieve an array of the current players in the server – Players:GetPlayers().

You can access PlayerGui From server, also, they could make a :FireClient() or :FireAllClients()