Camera making enemies and players (anything with humanoid) just disappear when spectating

The issue is that enemies randomly disappear when using this spectate as well as players.

I’ve looked everywhere and no one’s seemed to come across this same problem. I looked through in studio and did some testing and apparently the enemies humanoids just don’t appear for the local player sometimes?? It’s very weird and I have no clue why it happens.
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

Script 1 - for opening spectate

local button = script.Parent
local frame = button.Parent
local gui = frame.Parent
local part = gui.SpectatePart

local pressed = false

button.MouseButton1Click:Connect(function()
	if pressed == false then
		pressed = true
		frame.BackgroundColor3 = Color3.new(0.992157, 1, 0.419608)
		frame.BorderColor3 = Color3.new(0.737255, 0.690196, 0.337255)
		button.Text = "CLOSE"
		part.Visible = true
	elseif pressed == true then
		pressed = false
		frame.BackgroundColor3 = Color3.new(1, 1, 1)
		frame.BorderColor3 = Color3.new(159/255, 159/255, 159/255)
		button.Text = "SPECTATE"
		part.Visible = false
		for i,v in pairs(game.Players:GetChildren()) do
			if v == game.Players.LocalPlayer then
				gui.Num.Value = i
			end
		end
		part.EnemySpectate.Value = false
		gui.IsSpectating.Value = false
		workspace.CurrentCamera.CameraSubject = game.Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
	end
end)

gui.IsSpectating.Changed:Connect(function(val)
	if not val then
		part.EnemySpectate.Value = false
		gui.IsSpectating.Value = false
		workspace.CurrentCamera.CameraSubject = game.Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
		gui.SpectatePart.Frame.TextLabel.Text = game.Players.LocalPlayer.Name
	end
end)

Script 2 - for the spectate

local part = script.Parent
local gui = part.Parent
local frame = part.Frame
local back = part.Back
local next = part.Next
local enemy = part.TextButton
local enemyNum = #game.Workspace.enemies:GetChildren()
local camera = workspace.CurrentCamera
local plr = game.Players.LocalPlayer

local enemySpectate = part.EnemySpectate
local currentSpectate = nil

local topnum = #game.Players:GetChildren()
local currentnum = part.Parent:FindFirstChild("Num") or task.wait()
local currentEnemy = part.Parent:FindFirstChild("Enemies") or task.wait()
for i,v in pairs(game.Players:GetChildren()) do
	if v == game.Players.LocalPlayer then
		currentnum.Value = i
	end
end

frame.TextLabel.Text = game.Players.LocalPlayer.Name

game.Players.PlayerAdded:Connect(function()
	topnum += 1
end)
game.Players.PlayerRemoving:Connect(function()
	topnum -=1
end)
game.Workspace.enemies.ChildAdded:Connect(function()
	enemyNum += 1
end)
game.Workspace.enemies.ChildRemoved:Connect(function()
	enemyNum -= 1
end)

next.MouseButton1Click:Connect(function()
	if not enemySpectate.Value then
		currentnum.Value += 1
		if currentnum.Value > topnum then
			currentnum.Value = 1
		end
	elseif enemySpectate.Value then
		currentEnemy.Value +=1
		if currentEnemy.Value > enemyNum then
			currentEnemy.Value = 1
		end
	end
end)
back.MouseButton1Click:Connect(function()
	if not enemySpectate.Value then
		currentnum.Value -= 1
		if currentnum.Value < 1 then
			currentnum.Value = topnum
		end
	else if enemySpectate.Value then
			currentEnemy.Value -= 1
			if currentEnemy.Value < 1 then
				currentEnemy.Value = enemyNum
			end
		end
	end
end)


enemy.MouseButton1Click:Connect(function()
	if not enemySpectate.Value then
		if enemyNum == 0 then
			coroutine.wrap(function()
				enemy.Text = "NO ENEMIES!"
				task.wait(.5)
				enemy.Text = "Enemy Spectate"
			end)()
		elseif enemyNum > 0 then
			for i,v in pairs(game.Players:GetChildren()) do
				if v == game.Players.LocalPlayer then
					currentnum.Value = i
				end
			end
			currentEnemy.Value = 1
			enemy.Text = "CLOSE"
			script.Parent.EnemySpectate.Value = true
		end
	else
		camera.CameraSubject = game.Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
		currentEnemy.Value = 0
		
		enemy.Text = "ENEMY SPECTATE"
		script.Parent.EnemySpectate.Value = false
	end
end)
currentnum.Changed:Connect(function()
	if not enemySpectate.Value then
		for i,v in pairs(game.Players:GetChildren()) do
			if i == currentnum.Value and v ~= plr then
				currentSpectate = v
				gui.IsSpectating.Value = true
				workspace.Camera.CameraSubject = v.Character.Humanoid
				frame.TextLabel.Text = v.Name
				
				v.Character.AncestryChanged:Connect(function()
					if gui.IsSpectating.Value and currentSpectate == v then
						workspace.Camera.CameraSubject = v.Character.Humanoid
					end
				end)
				break
			elseif i == currentnum.Value and v== plr then
				gui.IsSpectating.Value = false
			end
		end
	end
end)

currentEnemy.Changed:Connect(function()
	if enemySpectate.Value then
		local enemies = game.Workspace.enemies:GetChildren()
		for i, v in ipairs(enemies) do
			if i == currentEnemy.Value then
				currentSpectate = v
				local humanoid = v:FindFirstChild("Humanoid")
				if humanoid then
					camera.CameraSubject = humanoid
					enemy.Text = v.Name
				end
				break
			end
		end
	end
end)

Both scripts are local scripts.
image

2 Likes


This is everything insside the one global sscript btw. It does nothing that could affect this.

I’ve also tried seeing if it was anything with the humanoids causing this by copying player humanoids and seeing what would happen and there wasn’t.

This problem is still ongoing so if there was anyone who could help I would be grateful.

Is your character far away from what you are spectating? My assumption is yes, and then my first hunch is that the objects are being streamed out by Roblox.

Roblox reserves streaming region around your character unless specified otherwise, so that would be a place to start. I think streaming is determined by what the Camera focus is, so you can try updating it regularly workspace.Camera.Focus = v.Character.PrimaryPart.CFrame.

You can also check out Player:RequestStreamArouncAsync() for a more advanced solution, but I think setting Focus should do the trick.

I had found the solution out a while back after asking a friend with a lot of developing experience about it and it was that the streamingenabled workspace property was streaming them out by Roblox. All I had to do was turn it off to fix this entirely, although that might not be the most optimized decision seeing that there might be other ways to go around this.

1 Like

The implications of turning streaming off is just that Roblox stops doing any heavy lifting for optimizing memory usage. Depending on your game, that may or may not be an issue. It may be an issue for weaker specs like older phones/tablets.