Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Pairs in game loop won't access all player's Guis. Help?

Asked by 9 years ago

I am having issues, Whenever I try to run my Game script (indev), I try to access all the GUIs of the player's through pairs, yet it only accesses 1 player Gui. Can Someone help?

Here's the code Snippet:

--[[QuakeScape MainScript]]--
--=[[All people who See this script other than FOXmcloud021 or Steal this Script will be taxed...]]=--
--With their life...--
local LSounds = game.Lighting.LoseSounds:GetChildren()
local WSounds = game.Lighting.WinSounds:GetChildren()
local Maps = game.Lighting.Maps:GetChildren()

while wait(5) do
    if game.Players.NumPlayers > 1 then
        for i,v in pairs(game.Players:GetChildren())do
            v.PlayerGui.TopBar.Frame.Visible = true
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Intermission..."
            wait(15)
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Choosing Map..."
            wait(10)
        end
        local MapChoose = math.random(1, #Maps)
        local MapChosen = Maps[MapChoose]
        for i,v in pairs (game.Players:GetChildren()) do
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Map Found!"
            wait(5)
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Loading map..."
            for i = 1,1,100 do
                v.PlayerGui.TopBar.Frame.TextLabel.Text ="Loading map... "..i.."%"
                wait(.15)
            end
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Map Loaded!"
        end
        MapChosenClone = MapChosen:Clone(game.Workspace)
    else
        for i,v in pairs(game.Players:GetChildren())do
            v.PlayerGui.TopBar.Frame.Visible = true
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "There must be Another Player in order to Play this Game"
        end
    end
end

2 answers

Log in to vote
1
Answered by
M39a9am3R 3210 Moderation Voter Community Moderator
9 years ago

I am highly assuming you are running this in a Server Side script, under Workspace or ServerScriptService. The reason it is not looping to all player's ScreenGuis is because of this wait() functions. Seriously, that's the problem. I know this because I have tried making a admin script and a laser tag game looping through all players using the same method presented. The way you can have the script loop through all players at once while not removing the waits if a technique called coroutines. Coroutines basically makes lines of code in a function to run almost like a separate script is being used (that's my best explanation of it). For your script you will want to use the following code:

coroutine.resume(coroutine.create(function() --coroutines are kind of functions themselves, so at the end of resume and create, add a "(" and then create a function, hence "function()". You can then add code to the next line.
--Code Here
end)) --You end the function, then you close the coroutine.create parenthesis and coroutine.resume parenthesis.

With coroutines, the wait time will do the wait for that player only. It is a useful technique especially if you know your script may break, due to a person leaving or something along those lines, the coroutine will break but the entire script will not. Though, caution when using coroutines because any errors will be hidden from the developer console.

As a final output your script should look like this when looping through players.

--[[QuakeScape MainScript]]--
--=[[All people who See this script other than FOXmcloud021 or Steal this Script will be taxed...]]=--
--With their life...--
local LSounds = game.Lighting.LoseSounds:GetChildren()
local WSounds = game.Lighting.WinSounds:GetChildren()
local Maps = game.Lighting.Maps:GetChildren()

while wait(5) do
    if game.Players.NumPlayers > 1 then
        for i,v in pairs(game.Players:GetChildren()) do
            coroutine.resume(coroutine.create(function() --You can only resume a created coroutine, that's why it creates one in the parenthesis.
            v.PlayerGui.TopBar.Frame.Visible = true
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Intermission..."
            wait(15)
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Choosing Map..."
            end)) --End the function and coroutines.
        end
        wait(25) --I moved this wait and added time to it because the coroutine is basically a separate script and will not make the script wait to choose a map. Change if you need to.
        local MapChoose = math.random(1, #Maps)
        local MapChosen = Maps[MapChoose]
        for i,v in pairs (game.Players:GetChildren()) do
            coroutine.resume(coroutine.create(function() --And another coroutine was made!
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Map Found!"
            wait(5)
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Loading map..."
            for i = 1,1,100 do
                v.PlayerGui.TopBar.Frame.TextLabel.Text ="Loading map... "..i.."%"
                wait(.15)
            end
            v.PlayerGui.TopBar.Frame.TextLabel.Text = "Map Loaded!"
            end)) --End the function and coroutines.
        end
        MapChosenClone = MapChosen:Clone(game.Workspace)
    else
        for i,v in pairs(game.Players:GetChildren()) do
            --You will not need a coroutine here since it will be virtually simultaneous. But you actually may want to add a WaitForChild function for protection though.
            v:WaitForChild("PlayerGui").TopBar.Frame.Visible = true
            v:WaitForChild("PlayerGui").TopBar.Frame.TextLabel.Text = "There must be Another Player in order to Play this Game"
        end
    end
end

Some people may complain that coroutine.wrap() is more efficient, but I don't use it since I have not had much luck with it. Though I have seen coroutine.wrap() go coroutine.wrap(function --Code end)() in another script, which I haven't tried yet but will intend on doing.

Hopefully this answer helped and explained what coroutines are a bit, and hope that they help in the long run. If you need a further explanation to coroutines, checkout this wiki article.

0
Thank You So much! This fixed everything, great thanks! I gave you credit in the mainscript for helping me :) FOXmcloud021 5 — 9y
0
It'd be nice if the answer were approved, but I guess that works too... M39a9am3R 3210 — 9y
Ad
Log in to vote
2
Answered by
Diitto 230 Moderation Voter
9 years ago

Are you running this in a LocalScript? If so, then the reason why is that LocalScripts can only access the client's PlayerGui. Else if there is an error of joining players, try using Player:waitForChild'PlayerGui'.

0
I am 99% sure he is not using a LocalScript. The problem is that the script is not looping through all players simultaneously. M39a9am3R 3210 — 9y
0
Well then, all he needs to do is set the thread scheduler to run the code once it reprocesses it's contents, using either coroutines, spawn, or delay with 0 as the first argument. Diitto 230 — 9y

Answer this question