Spectating Button Sort of working

I made a working spectate button while kind of theres a few big problems. The game is a obby so people die alot but when you die it stops spectating and its annoying. The next is there is no option to spectate nobody after you spectate someone. You can play here with a buddy to see what I mean The Game. Could you help

local camera = game.Workspace.CurrentCamera
local number = 1

local plr = game.Players.LocalPlayer
local players = game.Players:GetPlayers()

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

You are getting a table of players only once? when the script runs for first time
local players = game.Players:GetPlayers()

You are not handling the chance a new player joins or leaves server.
I would suggest create an empty table, then on PlayerJoin event add it to the table, on player leaves event remove it from the table, then on player die event, fire a remote to allClients with the name of the player who died, in the client’s local script make the espectator players to check if the player who died is the same one that they are expectating, and change the camera subject to the next one on the table.

I would probably add a bool into the dictionary, to allow or not allow that player to be spectated, in that way, if player dies, set that bool to false, when they respawn change it true

local espectables = {}
espectables[userID] = true

COuld you edit this in to the current script?

Thats a client script, the script I mean should be done on a new server script in ServerScriptService. I’d love to help you if you start with some of the script :3

I am sorry I really bad at scripting if you cant help thats ok.

The Script is a local script attached to a frame btw.

Yup I can help you, let me make some basic system.

1 Like

ServerScriptService (Script)

local SpectatorClientUpdate = Instance.new("RemoteEvent", game.ReplicatedStorage)
SpectatorClientUpdate.Name = "SpectatorClientUpdate"
game.Players.PlayerAdded:Connect(function()
	SpectatorClientUpdate:FireAllClients(game.Players:GetPlayers())
end)
game.Players.PlayerRemoving:Connect(function()
	SpectatorClientUpdate:FireAllClients(game.Players:GetPlayers())
end)

SpectateGui (Localscript)

local Spectating = script.Parent.Visible
local Players = game.Players:GetPlayers()
local LocalPlayer = game.Players.LocalPlayer
local Camera = workspace.CurrentCamera


function StopSpectating()
	if not Spectating then return end
	script.Parent.Visible = not script.Parent.Visible
	Spectating = not Spectating
	if not Spectating then
		local Character = LocalPlayer.Character
		if Character then
			local Humanoid = Character:WaitForChild("Humanoid")
			Camera.CameraSubject = Humanoid
		else
			Character = LocalPlayer.CharacterAdded:Wait()
			local Humanoid = Character:WaitForChild("Humanoid")
			Camera.CameraSubject = Humanoid
		end
	end
end
script.Parent.Parent.OpenClose.MouseButton1Click:Connect(function()
	if not Spectating then
		if #Players <= 0 then
			return
		end
	end
	script.Parent.Visible = not script.Parent.Visible
	Spectating = not Spectating
	if not Spectating then
		local Character = LocalPlayer.Character
		if Character then
			local Humanoid = Character:WaitForChild("Humanoid")
			Camera.CameraSubject = Humanoid
		else
			Character = LocalPlayer.CharacterAdded:Wait()
			local Humanoid = Character:WaitForChild("Humanoid")
			Camera.CameraSubject = Humanoid
		end
	else
		Update()
	end
end)


for i,v in pairs(Players) do
	if v == game.Players.LocalPlayer then
		table.remove(Players, i)
	end
end


local PlayerIndex = 1
local LastConnections = {}
function Update()
	local Player = Players[PlayerIndex]
	if Player then
		local Character = Player.Character
		if Character == nil then return false end
		local Humanoid = Character.Humanoid
		if Humanoid == nil then return false end
		for i,v in pairs(LastConnections) do v:Disconnect() end
		local function RePick()
			if (PlayerIndex+1) > #Players then
				if (PlayerIndex-1) < #Players then
					StopSpectating()
				else
					PlayerIndex -= 1
					Update()
				end
			else
				PlayerIndex += 1
				Update()
			end
		end
		table.insert(LastConnections, Humanoid.Died:Connect(function()
			RePick()
		end))
		table.insert(LastConnections, Player.CharacterAdded:Connect(function()
			RePick()
		end))
		table.insert(LastConnections, game.Players.PlayerRemoving:Connect(function(RemovingPlayer)
			if RemovingPlayer == Player then
				RePick()
			end
		end))
		Camera.CameraSubject = Humanoid
		pcall(function()
			script.Parent.Image.Image = game.Players:GetUserThumbnailAsync(Player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
		end)
	else
		if #Players > 0 then
			PlayerIndex = 1
			return Update()
		else
			return false
		end
	end
end
function Next()
	if not Spectating then return end
	if PlayerIndex < #Players then
		PlayerIndex += 1
	end
	Update()
end
function Previous()
	if not Spectating then return end
	if PlayerIndex >= #Players then
		PlayerIndex -= 1
	end
	Update()
end


local UserInputService = game:GetService("UserInputService")
local function onInputBegan(input)
	if not Spectating then return end
	if input.UserInputType == Enum.UserInputType.Keyboard then
		if input.KeyCode == Enum.KeyCode.Q then Previous() elseif input.KeyCode == Enum.KeyCode.E then Next() end
	end
end
UserInputService.InputBegan:Connect(onInputBegan)


script.Parent.Previous.MouseButton1Click:Connect(Previous)
script.Parent.Next.MouseButton1Click:Connect(Next)


local SpectatorClientUpdate = game.ReplicatedStorage:WaitForChild("SpectatorClientUpdate")
SpectatorClientUpdate.OnClientEvent:Connect(function(SpectateablePlayers)
	for Index, SpectateablePlayer in pairs(SpectateablePlayers) do
		if SpectateablePlayer == LocalPlayer then
			table.remove(SpectateablePlayers, Index)
		end
	end
	Players = SpectateablePlayers
end)

SpectateGui.rbxl (29.0 KB)

Why does the button not open the frame?

there must be other players for the frame to open
its at line 24 in the localscript if you want to change it
image

to let it open when there are no spectateable players:
image

This right here would mean if they die it goes up plus one. So if its just you and someone then they die then it stops speactating I belive this is whatit is but I want to make sure?

Also with this script you can spectate people on a different teams right?

Also is the Image in the GUI important?

Another problem I noticed it is big. Even though I adjusted the size to be small

If the person being spectated dies it tries to go to the player directly behind or in front of the player in the table but if it cant do that then it will stop spectating, you could remove the image but you would have to remove the lines in the script that reference it

What is big? you can change the Thumbnail type and size in the script Players:GetUserThumbnailAsync (roblox.com)

It’s a regular screen gui & elements you can re-size / style it however you want as long as you modify the script so your modifications don’t break it