i have this, really cool spectate script, and it’s like, really supposed to work!
buut it’s not :((
i get this error “Argument 1 is missing or nil” when trying to index an array inside the SpectateSubject
function
i am solo-testing the game, so maybe it could be that? i’m not really sure
local rStorage = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
local uInputService = game:GetService("UserInputService")
local rService = game:GetService("RunService")
-- Path to events;
local eventsFolder = rStorage:WaitForChild("Events")
local bindableEvents = eventsFolder:WaitForChild("Bindable")
local toClient = eventsFolder:WaitForChild("ToClient")
local functionalityEvents = toClient:WaitForChild("Functionality")
-- Events;
local enableHud = bindableEvents.EnableHUD
local invokeSpectate = bindableEvents.Spectate
local joinRequestResult = functionalityEvents.SendMatchRequestResult
-- Player variables;
local plr = players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local humanoid: Humanoid = char:WaitForChild("Humanoid")
local camera = workspace.CurrentCamera
-- UI;
local playerGui = plr.PlayerGui
local spectateUi = playerGui:WaitForChild("SpectateUI")
local footerFrame = spectateUi:WaitForChild("FooterFrame")
local currentPlayerSpectatedLabel = footerFrame:WaitForChild("CurrentPlayerLabel")
-- Workspace elements;
local ingameFolder = workspace:WaitForChild("InGame")
local staticSpectatePart = workspace:WaitForChild("SpectatePart")
-- Values;
local spectateIndex = 1
-- Tables;
local activePlayers = {}
-- Functions;
local function OnPlayerLoadedIntoMatch(playerChar: Model)
local playerToTamperWith = players:GetPlayerFromCharacter(playerChar)
if not playerToTamperWith then return end
-- get player's "playing" value
local playing: BoolValue = playerToTamperWith:FindFirstChild("Playing")
if not playing then return end
-- listen to changes to its value
playing:GetPropertyChangedSignal("Value"):Once(function()
-- if it's true, just don't do anything
if playing.Value then return end
-- get the player position in the activePlayers table
local playerIndex = table.find(activePlayers, playerToTamperWith.UserId)
-- if it doesn't exist, also don't do anything
if not playerIndex then return end
-- remove the player from the table
table.remove(activePlayers, playerIndex)
end)
-- add the player to active players
table.insert(activePlayers, playerToTamperWith.UserId)
end
local function OnPlayerLeavingGame(playerLeaving: Player)
-- get the player position in the activePlayers table
local playerIndex = table.find(activePlayers, playerLeaving.UserId)
if not playerIndex then return end
-- remove the player from that table
table.remove(activePlayers, playerIndex)
end
local function SpectateSubject()
-- get player to spectate (LINE THAT ERRORS LINE THAT ERRORS LINE THAT ERRORS)
-- BIG WARNING BIG WARNING BIG WARNING BIG WARNING BIG WARNING
local playerToSpectate = players:GetPlayerByUserId(activePlayers[spectateIndex])
-- get player's elements
local playerCharacter = playerToSpectate.Character
local playerRootPart: BasePart = playerCharacter:FindFirstChild("HumanoidRootPart")
if not playerCharacter or not playerRootPart then return end
-- change camera subject and update the player name label
camera.CameraSubject = playerRootPart
currentPlayerSpectatedLabel.Text = playerToSpectate.DisplayName or playerToSpectate.Name
end
local function GetSpectateSubject()
-- get player playing value
local playing: BoolValue = plr:FindFirstChild("Playing")
if not playing then return end
-- see if the player can even spectate at the moment
if playing.Value or char.Parent ~= ingameFolder then return end
-- get active players
local amountOfPlayersPlaying = #activePlayers
-- see if there's any players to spectate
if amountOfPlayersPlaying == 0 then return end
-- change spectate index to 1 or to whatever
-- the amount of players there are if the player tries
-- to spectate too high or too low (bad explanation)
if spectateIndex > amountOfPlayersPlaying then
spectateIndex = 1
elseif spectateIndex < amountOfPlayersPlaying then
spectateIndex = amountOfPlayersPlaying
end
end
local function OnInput(inputObject: InputObject)
local key = inputObject.KeyCode
-- change spectate index based on key pressed
if key == Enum.KeyCode.Q then
spectateIndex -= 1
elseif key == Enum.KeyCode.E then
spectateIndex += 1
end
end
local function InvokeSpectate()
spectateUi.Enabled = true
if #activePlayers == 0 then
SpectateSubject()
else
camera.CameraSubject = staticSpectatePart
end
-- listen for playing changes
local playing: BoolValue = plr:FindFirstChild("Playing")
if not playing then return end
playing:GetPropertyChangedSignal("Value"):Once(function()
if not playing.Value then return end
camera.CameraSubject = humanoid
enableHud:Fire()
end)
end
local function OnRequestToJoin(success: boolean)
if success then
camera.CameraSubject = humanoid
enableHud:Fire()
else
InvokeSpectate()
end
end
-- Runtime;
joinRequestResult.OnClientEvent:Connect(OnRequestToJoin)
players.PlayerRemoving:Connect(OnPlayerLeavingGame)
ingameFolder.ChildAdded:Connect(OnPlayerLoadedIntoMatch)
uInputService.InputBegan:Connect(OnInput)
invokeSpectate.Event:Connect(InvokeSpectate)