Hey so I am making a color block game and I already made the main frame but am struggling to make the game detect when players are dead (1 last left) and if so, gui appears that says “…Won” Thanks in advance :
local roundLength = 180
local intermissionLength = 30
local InRound = game.ReplicatedStorage.InRound
local Status = game.ReplicatedStorage.Status
local Players = game.Players
local LobbySpawn = game.Workspace.LobbySpawn
local GameAreaSpawn = game.Workspace.GameAreaSpawn
InRound.Changed:Connect(function()
if InRound.Value == true then
local playersInRound = {} -- track alive players
local connections = {} -- store connections to disconnect later
for _, Player in pairs(Players:GetChildren()) do
if Player.Character and Player.Character:FindFirstChild('Humanoid') then
table.insert(playersInRound, Player) -- add all players to table
connections[Player.Name] = Player.Character.Humanoid.Died:Connect(function()
table.remove(playersInRound, table.find(playersInRound, Player))
end)
end
end
connections["Removing"] = game.Players.PlayerRemoving:Connect(function(player) -- remove player from list if they leave
local ind = table.find(playersInRound, player)
if ind then
table.remove(playersInRound, ind)
end
end)
for _, player in pairs(game.Players:GetChildren()) do
local char = player.Character
char.HumanoidRootPart.CFrame = GameAreaSpawn.CFrame
end
else
for _, player in pairs(game.Players:GetChildren()) do
local char = player.Character
char.HumanoidRootPart.CFrame = LobbySpawn.CFrame
local playersInRound = {}
local connections = {}
if #playersInRound == 1 then
local success, message = pcall(function()
local player = playersInRound[1]
print("The Winner is: " .. player.Name)
Status.Value = player.Name .. " won the game!"
player.leaderstats.Wins.Value = player.leaderstats.Wins.Value + 1
player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 100
end)
if not success then
warn("An error occurred while rewarding winner: " .. message)
end
else
print("There was no single winner.")
Status.Value = "There was no single winner this round."
end
--Kill the players
for _, connection in pairs(connections) do -- disconnect connections to prevent memory leaks
connection:Disconnect()
end
for _, Player in pairs(playersInRound)do
Player:LoadCharacter()
end
end
end
end)
local function roundTimer()
while wait() do
for i = intermissionLength, 1, -1 do
InRound.Value = false
wait(1)
Status.Value = "Game starting in "..i.." seconds."
end
for i = roundLength, 1, -1 do
InRound.Value = true
wait(1)
Status.Value = "There are "..i.." seconds left for this round."
end
end
end
spawn(roundTimer)
You are declaring playersInRound
separately. It should instead be declared once per round.
local ReplicatedStorage = game:GetService("ReplicatedStorage");
local Players = game:GetService("Players");
local InRound = ReplicatedStorage:WaitForChild("InRound");
local Status = ReplicatedStorage:WaitForChild("Status");
local roundLength = 180;
local intermissionLength = 30;
local LobbySpawn = workspace.LobbySpawn;
local GameAreaSpawn = workspace.GameAreaSpawn;
local playersInRound = {} -- track alive players
local connections = {} -- store connections to disconnect later
local function removePlayer(player)
playersInRound[player.UserId] = nil;
end
local playerRemovingConnection;
InRound.Changed:Connect(function()
if (InRound.Value == true) then
playersInRound = {};
for _, Player in ipairs(Players:GetPlayers()) do
playersInRound[Player.UserId] = Player;
local Character = Player.Character or (Player.CharacterAdded:Wait());
local Humanoid = Character:FindFirstChild("Humanoid");
if (Humanoid) then
connections[Player.UserId] = Humanoid.Died:Connect(function()
removePlayer(Player);
end)
end
end
playerRemovingConnection = Players.PlayerRemoving:Connect(removePlayer);
for _, Player in ipairs(game.Players:GetPlayers()) do
local Character = Player.Character or (Player.CharacterAdded:Wait());
local HRP = Character:FindFirstChild("HumanoidRootPart") or Character.PrimaryPart;
if (HRP) then
HRP.CFrame = GameAreaSpawn.CFrame;
end
end
else
for _, Player in pairs(Players:GetPlayers()) do
local Character = Player.Character or (Player.CharacterAdded:Wait());
local HRP = Character:FindFirstChild("HumanoidRootPart") or Character.PrimaryPart;
if (HRP) then
HRP.CFrame = LobbySpawn.CFrame;
end
if (#playersInRound == 1) then
local success, message = pcall(function()
local player = playersInRound[1]
print("The Winner is: " .. player.Name)
Status.Value = player.Name .. " won the game!"
player.leaderstats.Wins.Value = player.leaderstats.Wins.Value + 1
player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 100
end)
if not success then
warn("An error occurred while rewarding winner: " .. message)
end
else
print("There was no single winner.")
Status.Value = "There was no single winner this round."
end
--Kill the players
playerRemovingConnection:Disconnect();
for _, connection in ipairs(connections) do -- disconnect connections to prevent memory leaks
connection:Disconnect()
end
for _, Player in ipairs(playersInRound)do
Player:LoadCharacter();
end
end
end
end)
local function roundTimer()
while (true) do
for i = intermissionLength, 1, -1 do
InRound.Value = false
wait(1)
Status.Value = "Game starting in "..i.." seconds."
end
for i = roundLength, 1, -1 do
InRound.Value = true
wait(1)
Status.Value = "There are "..i.." seconds left for this round."
end
end
end
coroutine.wrap(roundTimer);
And as good practice, use GetService
instead of indexing a singleton. Use GetPlayers
instead of GetChildren
on the Players singleton.
I’d suggest you take a look at your code, trying to find issues or bad habits. This ultimately will help you more than anyone else could.
Hey thanks for the reply, should I keep this local script under game.StarterGui.Timer.Localscript?
local Status = game.ReplicatedStorage.Status
local TimerDisplay = script.Parent.TimerDisplay
Status.Changed:Connect(function()
TimerDisplay.Text = Status.Value
end)
I fixed the timer and realised I sent you the wrong script.
local Timer = 31
for i = Timer, 0, -1 do
task.wait(1)
print(i)
end -- Intermission timer
local Round = 0
local StarterBlock = game.Workspace.StarterBlock
for i=1,3 do
local Circles = game.Workspace.Circles:GetChildren()
Chosen_Colour = Circles[math.random(1,#Circles)]
game.ReplicatedStorage.Colour.Value = Chosen_Colour.Name
task.wait(6)
-- ROUND 1,2 and 3
StarterBlock.Transparency = 1
StarterBlock.CanCollide = false
wait(2)
for number,Circle_Colours in pairs(Circles) do
for number,Circle_Part in pairs(Circle_Colours:GetChildren()) do
Circle_Part.Transparency = 1
Circle_Part.CanCollide = false
end
end
for number, Circle_Part in pairs(Chosen_Colour:GetChildren()) do
Circle_Part.Transparency = 0
Circle_Part.CanCollide = true
end
wait(3) -- waits again
for number,Circle_Colours in pairs(Circles) do
for number,Circle_Part in pairs(Circle_Colours:GetChildren()) do
print("h")
Circle_Part.Transparency = 0
Circle_Part.CanCollide = true
Round += 1
end
end
end
print("Round 1, 2 and 3 completed")
So this is only part of the script, there are 7 other rounds but as you stated, i need to put the playersInround each round. Could you debug it?
If all players die, no winner
if one left standing, the winning player is teleported back to LobbySpawn without executing the rest of the rounds and the intermission timer goes again and the script loops.