Spectator GUI not working in "team lobby"

Hello,
I have a Spectate GUI that is not working properly…

When we join the game in the “Team lobby” the spectate works very well.

When the round starts “Team Playing” we can click on the button (which I don’t want) but the interface does not work.

When a player is dead and returns to the “Team lobby” we can click on the spectate button but nothing works.
here is the video:
robloxapp-20220908-2155403.wmv (2.4 MB)

What I would like is to be able to have access to the spectate only in the “Team Lobby” lobby and not during the game.

Here is the LocalScript placed in the GUI:

local cam = game.Workspace.CurrentCamera
local but = script.Parent
local visible = false
local toggleFrame = but.Parent.Toggle
local plrName = toggleFrame.Player
local plr = game.Players.LocalPlayer

local LobbyTeam = "Lobby"

toggleFrame.Position = UDim2.new(0.5,0,1.5,0)

local plrNum = 1

local function checkPlayers()
	
	local plrs = game.Players:GetPlayers()
	
	local InRound = {}
	
	for i, p in pairs(plrs) do
		if p.Team.Name == LobbyTeam then
			table.insert(InRound, p)
			print(p.Name .. " Is Lobby")
		end 
	end
	
	return InRound
end

but.MouseButton1Click:Connect(function()
	
	plrNum = 1
	
	if not visible then
		
		
		toggleFrame:TweenPosition( UDim2.new(0.5,0,0.9,0), Enum.EasingDirection.Out, Enum.EasingStyle.Sine, 0.3, false)
		
		wait(.4)
		visible = true
		
		
	else
		
		toggleFrame:TweenPosition( UDim2.new(0.5,0,1.3,0), Enum.EasingDirection.Out, Enum.EasingStyle.Sine, 0.3, false)

		wait(.4)
		visible = false
		
		cam.CameraSubject = plr.Character.Humanoid
	end
end)

toggleFrame.Next.MouseButton1Click:Connect(function()

	local PlrsInRound = checkPlayers()

	if #PlrsInRound > 0 then
				
		plrNum += 1
		
		if plrNum <= #PlrsInRound then
		else
			plrNum = 1
		end
		
		
		local currentPlr = PlrsInRound[plrNum]
		
		if currentPlr ~= nil then
			local human =  currentPlr.Character.Humanoid
			
					cam.CameraSubject = human
					
					plrName.Text = currentPlr.Name
		end
	end
end)

toggleFrame.Previous.MouseButton1Click:Connect(function()

	local PlrsInRound = checkPlayers()

	if #PlrsInRound > 0 then
		
		plrNum -= 1
		
		if plrNum >= 1 then
		else
			plrNum = #PlrsInRound
		end

		local currentPlr = PlrsInRound[plrNum]

		if currentPlr ~= nil then
				local human =  currentPlr.Character.Humanoid

				cam.CameraSubject = human
				
				plrName.Text = currentPlr.Name
		end
	end
end)

Thank you !

Here is where it starts, because it returns as players who are in team “Lobby”. Thats why when it starts, it returns nothing because there is nobody in team “Lobby”.

Try changing this:

To this:

if p.Team.Name ~= LobbyTeam then

So that it checks for players who are not in “Lobby” Team.

Also, if you want for the players who are in “Lobby” Team to spectate and not players who are Playing then after this:

Add this:

if plr.Team.Name ~= LobbyTeam then return end

it works but this time, I can also spectate during the round, which I don’t want.

Have you tried adding this?

If not then put it after this:

oh sorry ! I hadn’t seen it, so yes it works, the only problem is that once the round is over and everyone is in the lobby, I can click on the spectate button, which is problematic because If I don’t close it before, once a new round started I get stuck in the spectate, is it possible that once the round is over and everyone finds themselves in the lobby, we can’t click on spectate?

Use a Remote Event or a Value that indicates if the round is done and set all players’ camera who are in the “Lobby” team to this:

how can i add this to the script? sorry i’m newbie :sweat_smile:

Create a BoolValue in the workspace and name it “IsRound” then:

--Place this at the start of the script
local isround = workspace:WaitForChild("IsRound")

isround.Changed:Connect(function()
	if plr.Team.Name == LobbyTeam then
		cam.CameraSubject = plr.Character.Humanoid
	end
end)

nothing changes I can always open the spectate when all the players have finished the round.

--Place this at the start of the script
local isround = workspace:WaitForChild("IsRound")

isround.Changed:Connect(function()
	if plr.Team.Name == LobbyTeam and not isround.Value then
		cam.CameraSubject = plr.Character.Humanoid
	end
end)

And change the value if the round started to true
else change the value to false if the round finished

still the same problem, it doesn’t work what do you mean by

Put this on the round script where after the round starts:
workspace:FindFirstChild("IsRound").Value = true
Put this after where the round ends:
workspace:FindFirstChild("IsRound").Value = false

well I must be doing something wrong because it makes absolutely no difference no matter where I place these lines…

Can you show me the script for starting the round and ending it?

Oh you mean this script?

local intermission = 20
local roundLength = 150

local inRound = game.ReplicatedStorage.InRound
local staus = game.ReplicatedStorage.Status

local playingTeam = game.Teams.Playing
local lobbyTeam = game.Teams.Lobby

inRound.Changed:Connect(function()
	
	if inRound.Value == true then
		
		for i, plr in pairs(game.Players:GetChildren()) do
			
			local char = plr.Character
			local humanRoot = char:WaitForChild("HumanoidRootPart")
						
			
			plr.Team = playingTeam
			
			char:WaitForChild("Humanoid").Died:Connect(function()
				
				plr.Team = lobbyTeam
				
				
			end)
			
		end	
		
	else
		
		for i, plr in pairs(game.Players:GetChildren()) do

			local char = plr.Character
			local humanRoot = char:WaitForChild("HumanoidRootPart")

			humanRoot.CFrame = game.Workspace.lobbySpawn.CFrame
			
			plr.Team = lobbyTeam
			
		end
	end	
end)



local function round()	
	while true do
		
		local requiredPlayers = 2
		
		repeat
			wait(1)
			staus.Value = "Atleast ".. requiredPlayers.." players are needed to start a round"
			
		until #game.Players:GetChildren() >= requiredPlayers
		
		inRound.Value = false
		
		
		for i = intermission, 0, -1 do
			
			staus.Value = "Game will start in "..i.." seconds"
			
			wait(1)
			
		end
		
		inRound.Value = true
		
		wait(3)

		for i = roundLength, 0, -1 do
			
			wait(1)
			
			staus.Value = "Game will end in "..i.." seconds"
			
			local playing = {}
			
			for i, plr in pairs(game.Players:GetChildren()) do
				
				if plr.Team.Name == "Playing" then
					
					
					table.insert(playing, plr.Name)
					
					
				end	
			end
			
			
			if #playing == 0 then
				
				staus.Value = "Everyone Has Died"
				
				wait(3)
				break
				
			end
			
			
			if #playing == 1 then
				
				staus.Value = playing[1].." Has Won The Game!"
				
				for i, plr in pairs(game.Players:GetChildren()) do
					if playing[1] == plr.name then
						plr.leaderstats.Wins.Value += 1
					end
				end

				
				wait(3)
				
				
				
				break
				
			end
			
			wait(1)
		end
		wait(3)
	end
end


spawn(round)

I see the CameraSubject but are you changing the player’s camera CFrame?
Because to correctly find where you’re looking you would need to find the “current player being spectated” player’s head camera CFrame so when you press the button you go to their head instead of just the subject. Might not be fully correct but I’m pretty sure this is a thing you need to do in Camera Manipulation.

Seems like you already have the inRound Value
you can remove the isRound Value in workspace

You can remove these ^ ^

And change this:

To this:

local isround = game:GetService("ReplicatedStorage"):WaitForChild("InRound") --This one

I tried changing wait() to task.wait() and some things.

local intermission = 20
local roundLength = 150

local inRound = game.ReplicatedStorage.InRound --Seems like you already have a value
local staus = game.ReplicatedStorage.Status

local playingTeam = game.Teams.Playing
local lobbyTeam = game.Teams.Lobby

inRound.Changed:Connect(function()
	
	if inRound.Value then
		
		for i, plr in pairs(game.Players:GetChildren()) do
			
			local char = plr.Character
			local humanRoot = char:WaitForChild("HumanoidRootPart")
						
			
			plr.Team = playingTeam
			
			char:WaitForChild("Humanoid").Died:Connect(function()
				
				plr.Team = lobbyTeam
				
				
			end)
			
		end	
		
	else
		
		for i, plr in pairs(game.Players:GetChildren()) do
			local char = plr.Character
			local humanRoot = char:WaitForChild("HumanoidRootPart")
			humanRoot.CFrame = game.Workspace.lobbySpawn.CFrame
			plr.Team = lobbyTeam
		end
	end	
end)



local function round()	
	while task.wait(3) do -- Not Really recommended
		local requiredPlayers = 2
		repeat
			task.wait(1)
			staus.Value = "Atleast ".. requiredPlayers.." players are needed to start a round"
		until #game.Players:GetChildren() >= requiredPlayers
		
		inRound.Value = false
		for i = intermission, 0, -1 do
			staus.Value = "Game will start in "..i.." seconds"
			task.wait(1)
			
		end
		inRound.Value = true
		task.wait(3)
		for i = roundLength, 0, -1 do
			task.wait(1)
			staus.Value = "Game will end in "..i.." seconds"
			
			local playing = {}
			
			for i, plr in pairs(game.Players:GetChildren()) do
				if plr.Team.Name == "Playing" then
					table.insert(playing, plr.Name)
				end	
			end
			if #playing == 0 then
				staus.Value = "Everyone Has Died"
				task.wait(3)
				break
			end
			if #playing == 1 then
				staus.Value = playing[1].." Has Won The Game!"
				for i, plr in pairs(game.Players:GetChildren()) do
					if playing[1] == plr.name then
						plr.leaderstats.Wins.Value += 1
					end
				end
				task.wait(3)
				break
			end
			wait(1)
		end
	end
end


task.spawn(round) -- You may use coroutine or just call the round without spawn

no change, I still have access to the spectate once everyone is in the lobby… And this is what happens if I leave the viewer gui open:

robloxapp-20220909-1750381.wmv (2.6 MB)

is it possible to make the spectator button invisible once the round is over and all players return to the lobby? Then the round restarts and players who die and return to the lobby can access it again?

I don’t know if you understand what I want :sweat_smile:, but basically I want no one to have access to the spectate button during the intermission, only those who die during the round.