I am making a spectating system. I realized that if a person dies while you spectate them, the system continues to spectate the corpse. To remedy this, I made it so that whenever the Subject (AKA, player who is being spectated) dies, the CurrentCamera’s subject would switch to the respawned character.
I ran into issues when the arrows to flip through the players stopped working upon doing this. Even if I remove the old dead character and add the new, respawned character to the table of players who are allowed to be spectated, it gives me an error that says:
Attempted to perform Add (arithmetic) on nil and number
You’ll understand better if I send you the script.
IMPORTANT: An npc is part of the table of subjects by default.
local left = script.Parent.ScreenGui.Spectating.L_Arrow
local right = script.Parent.ScreenGui.Spectating.R_Arrow
local nameplate = script.Parent.ScreenGui.Spectating.SubjectName
local function spectate(sub :Model)
cam.CameraSubject = sub
left.Visible = true
right.Visible = true
nameplate.Visible = true
nameplate.Text = sub.Name
print("POV changed")
local hum = sub:FindFirstChildOfClass("Humanoid")
if hum then
print("hum found")
hum.Died:Connect(function()
table.remove(chrs, table.find(chrs, sub))
print(chrs) --first time Died fires, it works as intended, leaving only the npc in the table if the server has two players. Second time, it removes the npc from the table as well!
print("subject died")
sub = game.Players:GetPlayerFromCharacter(sub).CharacterAdded:Wait()
print("new chr added" .. sub.Name)
cam.CameraSubject = sub
print("spectating new chr")
table.insert(chrs, sub)
print(chrs) --first time Died fires, it adds one PLayer1 to the table. The second time, I see two Player1's in the table.
end)
end
return sub
end
--first player that gets spectated
local subject = chrs[1]
spectate(subject)
left.MouseButton1Click:Connect(function()
local prev = table.find(chrs, subject) - 1 --here is the error
if prev == 0 then --so that "previous" doesn't become less than 0
prev = #chrs
end
subject = chrs[prev]
spectate(subject)
--print("left")
print(chrs)
end)
right.MouseButton1Click:Connect(function()
local following = table.find(chrs, subject) + 1 --here is the error
if following > #chrs then --so that "following" doesn't exceed len(chrs)
following = 1
end
subject = chrs[following]
spectate(subject)
--print("right")
print(chrs)
end)
chrs = table of spectatable characters subject = player/npc that is being spectated left = left button to cycle through players right = similar to left, but in the opposite direction nameplate = shows username of subject on the screen prev = previous player folllowing = next player
The error occurs because .Died() happens twice for one death. Somehow, this leads to the chrs table having two instances of the player that died. Somehow this means it can’t find the subject??? I’m awfully confused, all help is greatly appreciated.
The problem is most likely because you use the last subject to find the next/previous one, but if the last subject, such as the player, dies, not only does their character, aka your subject, get destroyed, you also remove it from the chrs table as far as I understood. And then, once either button is pressed, you are attempting to find the last subject in the table, even tho you just removed it from there. You should probably separately keep track of the current index instead of directly relying on the last subject to find the next/previous one.
I changed the code to use a variable “N” insted of “previous” and "following
local function spectate(sub :Model)
cam.CameraSubject = sub
left.Visible = true
right.Visible = true
nameplate.Visible = true
nameplate.Text = sub.Name
print("POV changed")
local hum = sub:FindFirstChildOfClass("Humanoid")
if hum then
print("hum found")
hum.Died:Connect(function()
table.remove(chrs, table.find(chrs, sub))
print(chrs)
print("subject died")
sub = game.Players:GetPlayerFromCharacter(sub).CharacterAdded:Wait()
print("new chr added" .. sub.Name)
cam.CameraSubject = sub
print("spectating new chr")
table.insert(chrs, sub)
print(chrs)
end)
end
return sub
end
--first player that gets spectated
local n = 1
local subject = chrs[n]
spectate(subject)
left.MouseButton1Click:Connect(function()
n -= 1
if n == 0 then
n = #chrs
end
subject = chrs[n]
spectate(subject)
--print("left")
print(chrs)
end)
right.MouseButton1Click:Connect(function()
n += 1
if n > #chrs then
n = 1
end
subject = chrs[n]
spectate(subject)
--print("right")
print(chrs)
end)
It works perfectly… but we have a new issue now:
It still removes the NPC from the table, and it adds 7-8 copies of “player1” in Local Server testing
Well, I never would have thought I’d use dead as a variable but, here we are…
You’re seeing Humanoid.Died fire multiple times because you’re calling spectate(subject) each time a button is clicked, each call connects another hum.Died.
local dead = nil
local function spectate(sub :Model)
cam.CameraSubject = sub
left.Visible = true
right.Visible = true
nameplate.Visible = true
nameplate.Text = sub.Name
print("POV changed")
local hum = sub:FindFirstChildOfClass("Humanoid")
if hum then
if dead then
dead:Disconnect()
end
print("hum found")
dead = hum.Died:Connect(function()
table.remove(chrs, table.find(chrs, sub))
print(chrs)
print("subject died")
sub = game.Players:GetPlayerFromCharacter(sub).CharacterAdded:Wait()
print("new chr added" .. sub.Name)
cam.CameraSubject = sub
print("spectating new chr")
table.insert(chrs, sub)
print(chrs)
end)
end
return sub
end
Really don’t like the way this works or looks… but, that is most likely your problem.
It’s my first time making a spectating system, so it is probably really inefficient.
I think your solution has worked!
If I don’t experience any problems starting 2 days from now I’ll mark yours as the solution. Thank you!