Hello there guys, I have a script where I want a GUI to display saying "Not enough players" if there aren't a certain amount of players in the game, while also removing the GUI if enough players are met. The script is in ServerScriptService, and with FilteringEnabled set to on, scripts in ServerScriptService are not able to read PlayerGuis. So I have to use a for i, v to clone a GUI into the player. The problem with this is that with the while true do running, it is constantly cloning GUIs into the player and the game becomes INCREDIBLY laggy.
How can I make it so while true do only runs ONCE and then restarts the loop? Do I include a break somewhere?
while true do wait() if game.Players.NumPlayers >= MinPlayers then for i, v in pairs(game.Players:GetChildren()) do local playergui = v:FindFirstChild("PlayerGui") if playergui then local somegui = playergui:FindFirstChild("playercheckgui") if somegui then somegui:Destroy() print("Destroyed first GUI in PlayerGui") end end end else for i, v in pairs(game.Players:GetChildren()) do local player = v:FindFirstChild("PlayerGui") local screengui = Instance.new('ScreenGui', player) screengui.Name = "playercheckgui" ---- Create textLabel local imageLabel = Instance.new('ImageLabel', player.playercheckgui) imageLabel.Position = UDim2.new(0.3, 0, 0, 0) imageLabel.Size = UDim2.new(0.35, 0, 0.15, 0) imageLabel.BackgroundTransparency = 1 end end
The other alternative is to place this script in Workspace and call it a day? But that is bad security wise, yes?
The correct solution is to not use an infinite loop at all. Instead, connect a callback function to the Players.PlayerAdded event. That callback will be fired each time a new player joins.
So, each time a player joins, check if there are enough players;
If there are, hide the gui for all players by disabling its Visible
property;
If not, show the gui by enabling its Visible
property.
However, as you mentioned, gui elements located in StarterGui are cloned over to PlayerGui by none other than the client. If network filtering is enabled then the server will refuse to acknowledge the existance of the cloned gui elements, meaning they can only be accessed from clientside scripts.
But this isn't a problem for us, as gui elements should be manipulated from clientside anyway. This is assuming the original gui element is located in StarterGui:
local players = game:GetService("Players") local player = players.LocalPlayer local playerGui = player:FindFirstChild("PlayerGui") local minPlayers = 8 players.PlayerAdded:connect(function() --[[ We make sure the gui exists, as exploiters can edit the DataModel of their client as they wish; which may break clientside scripts, if not written properly. ]] if playerGui:FindFirstChild("ScreenGui") and playerGui.ScreenGui:FindFirstChild("Frame") then frame.Visible = players.NumPlayers >= minPlayers end end)