Creating a spectate system that removes the player from a table when they have died/left the game

hello! I have made a simple spectate system and I would like to know how you would add and remove players efficiently from player table when they have died/left the game in a round (using the humanoid.Died function each time a player dies or the player.PlayerRemoving).

LocalScript:

script.Parent.Parent.OpenButton.MouseButton1Click:Connect(function()
	if not spectating then
		spectating = true
		print(spectating)
	elseif spectating then
		spectating = false
	end
end)

local plrs = {}

script.Parent.NextButton.MouseButton1Click:Connect(function()
	number = number + 1
	if players[number] ~= nil then
		camera.CameraSubject = players[number].Character.Humanoid
		script.Parent.TextLabel.Text = "Spectating" ..players[number].Name
	end
	
	if players[number] == nil then
		number = 1
		camera.CameraSubject = players[number].Character.Humanoid
		script.Parent.TextLabel.Text = "Spectating" ..players[number].Name
	end
end)

frame.Changed:Connect(function()
	if not frame.Visible then
		camera.CameraSubject = game.Players.LocalPlayer.Character:WaitForChild("Humanoid")
	end
end)

inRound.Changed:Connect(function()
	print("inround change triggered")
	if inRound.Value == true then
		if frame.Visible then
		frame.Visible = false
		camera.CameraSubject = game.Players.LocalPlayer.Character:WaitForChild("Humanoid")
			print("frame visible = false")
		end
		if script.Parent.Parent.OpenButton.Visible == true then
		script.Parent.Parent.OpenButton.Visible = false
		print("openbutton false")
		end
	end
end)

game.Players.LocalPlayer.CharacterAdded:Connect(function()
	if script.Parent.Parent.OpenButton.Visible == false then
	script.Parent.Parent.OpenButton.Visible = true
	print("character added function ran")
	end
	print("connected to character")
end)

If there are better ways to write the script, I would like to know that as well. Thank you!

Yeah, use a server script to track when players join/leave the game when those events occur use a RemoteEvent instance to fire all clients informing them as such.

local players = game:GetService("Players")
local replicated = game:GetService("ReplicatedStorage")
local joinedRemote = replicated.JoinedRemote
local leftRemote = replicated.LeftRemote

local playersInRound = {} --Example table which stores players currently in the round.

players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local humanoid = character:WaitForChild("Humanoid")
		humanoid.Died:Connect(function() --This is fired whenever a player's character's humanoid's health reaches 0.
			local roundPlayer = table.find(playersInRound, player) --Check if player was still in round.
			if roundPlayer then
				table.remove(playersInRound, roundPlayer) --Remove player from round players table.
			end
		end)
	end)
	joinedRemote:FireAllClients(player) --Send the player instance which triggered the added event to fire to all clients.
end)

players.PlayerRemoving:Connect(function(player)
	leftRemote:FireAllClients(player) --Send the player instance which triggered the removing event to fire to all clients.
	local roundPlayer = table.find(playersInRound, player) --Check if player was still in round.
	if roundPlayer then
		table.remove(playersInRound, roundPlayer) --Remove player from round players table.
	end
end)

Here’s a relatively concise example of what you could add. This would need to be in a server script as the “PlayerAdded” and “PlayerRemoving” events do not fire in local scripts.

1 Like

Thank you! But if I wanted to stop spectating a specific player and move on to the next player when they have died or left the game, would I have to create a table in a local script as well and insert the player into that table whenever a round starts or do I just do everything in the server script and use the fireallclients event?