Camera=workspace.Camera Player=game.Players.LocalPlayer SpawnNotificationFunction=game.ReplicatedStorage.ClientStorage.SpawnNotification SpectateTarget=script.Parent.SpectateTarget SpectatePrevButton=script.Parent.GuiBar.SpectatePrevButton SpectateNextButton=script.Parent.GuiBar.SpectateNextButton SpectateButton=script.Parent.GuiBar.SpectateButton LastSpectated=nil SpectateNotification=nil SpectateTargetEventConnections={}function TargetCameraOnPlayer(O)assert(typeof(O)=="\073\110\115\116\097\110\099\101"and O:IsA("\080\108\097\121\101\114"))local X=O.Character and O.Character:WaitForChild("\072\117\109\097\110\111\105\100",.5)or Player.Character and Player.Character:WaitForChild("\072\117\109\097\110\111\105\100",.5)Camera.CameraSubject=X end function UpdateSpectateGui()local O=SpectateTarget.Value local X=O~=nil SpectatePrevButton.Visible=X SpectateNextButton.Visible=X if O~=LastSpectated then for O,X in pairs(SpectateTargetEventConnections)do X:Disconnect()SpectateTargetEventConnections[O]=nil end if X then if SpectateNotification==nil or SpectateNotification.Parent==nil then SpectateNotification=SpawnNotificationFunction:Invoke("",Color3.new(1,1,1),-1)end SpectateNotification.LifetimeLeft.Value=-1 SpectateNotification.Text="\083\112\101\099\116\097\116\105\110\103 "..O.Name SpectateTargetEventConnections[1]=O.CharacterAdded:Connect(UpdateSpectateGui)else if SpectateNotification~=nil and SpectateNotification.Parent~=nil then SpectateNotification.LifetimeLeft.Value=0 end TargetCameraOnPlayer(Player)end end if X then TargetCameraOnPlayer(SpectateTarget.Value)end LastSpectated=SpectateTarget.Value end function ToggleIsSpectating()if SpectateTarget.Value==nil then SpectateTarget.Value=Player else SpectateTarget.Value=nil end end function SpectatePrevious()local O=SpectateTarget.Value if O~=nil then local X=game.Players:GetPlayers()local w=nil for X,G in ipairs(X)do if G==O then w=X break end end local G=w>1 and w-1 or#X SpectateTarget.Value=X[G]end end function SpectateNext()local O=SpectateTarget.Value if O~=nil then local X=game.Players:GetPlayers()local w=nil for X,G in ipairs(X)do if G==O then w=X break end end local G=w<#X and w+1 or 1 SpectateTarget.Value=X[G]end end UpdateSpectateGui()SpectateTarget.Changed:Connect(UpdateSpectateGui)SpectateButton.MouseButton1Click:Connect(ToggleIsSpectating)SpectatePrevButton.MouseButton1Click:Connect(SpectatePrevious)SpectateNextButton.MouseButton1Click:Connect(SpectateNext)Player.PlayState.Changed:Connect(function(O)if O=="\080\108\097\121\105\110\103"then SpectateTarget.Value=nil end end)game.Players.PlayerRemoving:Connect(function(O)if O==SpectateTarget.Value then SpectateTarget.Value=Player end end)
-- Allows players to spectate other players.
--
-- ForbiddenJ

Camera = workspace.Camera
Player = game.Players.LocalPlayer
SpawnNotificationFunction = game.ReplicatedStorage.ClientStorage.SpawnNotification

SpectateTarget = script.Parent.SpectateTarget -- ObjectValue that refers to a Player object or nil.
SpectatePrevButton = script.Parent.GuiBar.SpectatePrevButton
SpectateNextButton = script.Parent.GuiBar.SpectateNextButton
SpectateButton = script.Parent.GuiBar.SpectateButton

LastSpectated = nil
SpectateNotification = nil
SpectateTargetEventConnections = {}

function TargetCameraOnPlayer(player)
	assert(typeof(player) == "Instance" and player:IsA("Player"))

	-- Try to target the camera on the other player. Fallback to the local player's
	-- character if the other player's character is dead and is not the local player.
	local humanoid = (player.Character and player.Character:WaitForChild("Humanoid", 0.5))
		or (Player.Character and Player.Character:WaitForChild("Humanoid", 0.5))

	Camera.CameraSubject = humanoid
end
function UpdateSpectateGui()
	local targetPlayer = SpectateTarget.Value
	local isSpectating = targetPlayer ~= nil
	SpectatePrevButton.Visible = isSpectating
	SpectateNextButton.Visible = isSpectating

	if targetPlayer ~= LastSpectated then
		-- Clear the old event connections.
		for i, v in pairs(SpectateTargetEventConnections) do
			v:Disconnect()
			SpectateTargetEventConnections[i] = nil
		end

		if isSpectating then
			-- Spectate the target player.
			if SpectateNotification == nil or SpectateNotification.Parent == nil then
				SpectateNotification = SpawnNotificationFunction:Invoke("", Color3.new(1, 1, 1), -1)
			end
			SpectateNotification.LifetimeLeft.Value = -1
			SpectateNotification.Text = "Spectating " .. targetPlayer.Name
			SpectateTargetEventConnections[1] = targetPlayer.CharacterAdded:Connect(UpdateSpectateGui)
		else
			-- Reset the GUI to normal.
			if SpectateNotification ~= nil and SpectateNotification.Parent ~= nil then
				SpectateNotification.LifetimeLeft.Value = 0
			end
			TargetCameraOnPlayer(Player)
		end
	end

	-- Exempt from player changes for for CharacterAdded events.
	if isSpectating then
		TargetCameraOnPlayer(SpectateTarget.Value)
	end

	LastSpectated = SpectateTarget.Value
end
function ToggleIsSpectating()
	if SpectateTarget.Value == nil then
		SpectateTarget.Value = Player
	else
		SpectateTarget.Value = nil
	end
end
function SpectatePrevious()
	local targetPlayer = SpectateTarget.Value
	if targetPlayer ~= nil then
		local players = game.Players:GetPlayers()

		-- Find the index of the player we're currently spectating.
		local currentI = nil
		for i, player in ipairs(players) do
			if player == targetPlayer then
				currentI = i
				break
			end
		end

		-- What's the previous valid player index?
		local targetI = currentI > 1 and currentI - 1 or #players

		-- Spectate the player at targetI.
		SpectateTarget.Value = players[targetI]
	end
end
function SpectateNext()
	local targetPlayer = SpectateTarget.Value
	if targetPlayer ~= nil then
		local players = game.Players:GetPlayers()

		-- Find the index of the player we're currently spectating.
		local currentI = nil
		for i, player in ipairs(players) do
			if player == targetPlayer then
				currentI = i
				break
			end
		end

		-- What's the next valid player index?
		local targetI = currentI < #players and currentI + 1 or 1

		-- Spectate the player at targetI.
		SpectateTarget.Value = players[targetI]
	end
end

UpdateSpectateGui()

SpectateTarget.Changed:Connect(UpdateSpectateGui)
SpectateButton.MouseButton1Click:Connect(ToggleIsSpectating)
SpectatePrevButton.MouseButton1Click:Connect(SpectatePrevious)
SpectateNextButton.MouseButton1Click:Connect(SpectateNext)
Player.PlayState.Changed:Connect(function(value)
	if value == "Playing" then
		SpectateTarget.Value = nil
	end
end)
game.Players.PlayerRemoving:Connect(function(player)
	if player == SpectateTarget.Value then
		SpectateTarget.Value = Player
	end
end)
