Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why is my spectator script not working every EVEN time its clicked?

So, I made a spectator script. It works fine every odd time it clicked. However, when I click on it an even time, it only shows me the first person on the list, and when I click on the right and left arrow, it isn't going to the next person. Usually, when its clicked on an odd time, it works fine though. Why is it that the spectator script isn't working properly every EVEN time it is clicked?

Local Script:

camera = workspace.CurrentCamera
getPlayerInfo = game.ReplicatedStorage.Remotes.GetPlayerRole
gameLobby = script.Parent.Parent.GameLobby
components = script.Parent.Parent.SpectateComponents
getPlayers = game.ReplicatedStorage.Remotes.GetPlayers
local index

function createSpectateList()
	local players = getPlayers:InvokeServer()
	local spectateList = {}
	
	for _, plr in pairs(players) do
		if getPlayerInfo:InvokeServer(plr) ~= "" and plr.Name ~= game.Players.LocalPlayer.Name then
			table.insert(spectateList, plr.Name)
		end
	end
	
	return spectateList
end

script.Parent.MouseButton1Click:Connect(function()
	index = 1
	local players = createSpectateList()
	components.SpectateUser.Visible = true
	components.Right.Visible = true
	components.Left.Visible = true
	script.Parent.Parent.LeaveSpectate.Visible = true
	
	gameLobby.Visible = false
	script.Parent.Visible = false
	components.SpectateUser.Text = players[index]
	camera.CameraSubject = game.Players:FindFirstChild(players[index]).Character:WaitForChild("Humanoid")
	
	components.Right.MouseButton1Click:Connect(function()
		if index ~= #players then index = index + 1 else index = 1 end
		camera.CameraSubject = game.Players:FindFirstChild(players[index]).Character:WaitForChild("Humanoid")
		components.SpectateUser.Text = players[index]
	end)
	
	components.Left.MouseButton1Click:Connect(function()
		if index ~= 1 then index = index - 1 else index = #players end
		camera.CameraSubject = game.Players:FindFirstChild(players[index]).Character:WaitForChild("Humanoid")
		components.SpectateUser.Text = players[index]
	end)
	
	script.Parent.Parent.LeaveSpectate.MouseButton1Click:Connect(function()
		index = 1
		camera.CameraSubject = game.Players.LocalPlayer.Character:WaitForChild("Humanoid")
		components.SpectateUser.Visible = false
		components.Right.Visible = false
		components.Left.Visible = false
		script.Parent.Parent.LeaveSpectate.Visible = false
		script.Parent.Parent.GameLobby.Visible = true
		script.Parent.Visible = true
	end)
end)

1 answer

✓ Accepted answer

The MouseButton1Click connections are stacking. Every time the player clicks the "Spectate" button, a new connection is made, and so the same code is run multiple time for each click. I believe the code is actually "working", it's just that it cycles back to the same player when there is an even number of connections! We can change the code to clean up the connections when spectating ends:

camera = workspace.CurrentCamera
getPlayerInfo = game.ReplicatedStorage.Remotes.GetPlayerRole
gameLobby = script.Parent.Parent.GameLobby
components = script.Parent.Parent.SpectateComponents
getPlayers = game.ReplicatedStorage.Remotes.GetPlayers
local index

function createSpectateList()
    local players = getPlayers:InvokeServer()
    local spectateList = {}

    for _, plr in pairs(players) do
        if getPlayerInfo:InvokeServer(plr) ~= "" and plr.Name ~= game.Players.LocalPlayer.Name then
            table.insert(spectateList, plr.Name)
        end
    end

    return spectateList
end

script.Parent.MouseButton1Click:Connect(function()
    index = 1
    local players = createSpectateList()
    components.SpectateUser.Visible = true
    components.Right.Visible = true
    components.Left.Visible = true
    script.Parent.Parent.LeaveSpectate.Visible = true

    gameLobby.Visible = false
    script.Parent.Visible = false
    components.SpectateUser.Text = players[index]
    camera.CameraSubject = game.Players:FindFirstChild(players[index]).Character:WaitForChild("Humanoid")

    local connections = {} -- Add a table of connections

    connections.right = components.Right.MouseButton1Click:Connect(function()
        if index ~= #players then index = index + 1 else index = 1 end
        camera.CameraSubject = game.Players:FindFirstChild(players[index]).Character:WaitForChild("Humanoid")
        components.SpectateUser.Text = players[index]
    end)

    connections.left = components.Left.MouseButton1Click:Connect(function()
        if index ~= 1 then index = index - 1 else index = #players end
        camera.CameraSubject = game.Players:FindFirstChild(players[index]).Character:WaitForChild("Humanoid")
        components.SpectateUser.Text = players[index]
    end)

    connections.leave = script.Parent.Parent.LeaveSpectate.MouseButton1Click:Connect(function()
        index = 1
        camera.CameraSubject = game.Players.LocalPlayer.Character:WaitForChild("Humanoid")
        components.SpectateUser.Visible = false
        components.Right.Visible = false
        components.Left.Visible = false
        script.Parent.Parent.LeaveSpectate.Visible = false
        script.Parent.Parent.GameLobby.Visible = true
        script.Parent.Visible = true

        -- Clean up the connections
        for _, conn in pairs(connections) do
            conn:Disconnect()
        end
    end)
end)

This discussion is preserved as it was. New answers, comments, and votes are closed.