How to make Avatar Invisible to Entire Server

So here’s the thing. I have this script to make yourself invisible and it works like a charm until…
You ask another person to join you. Because even though you feel like you’re invisible, to them you aren’t.
Because well it’s a Local Script. oof
So is there a way to make you character invisible to the entire server? Like via an event or something?
Has anyone done this before?

local enabled = false
local plr = game.Players.LocalPlayer

script.Parent.Activated:Connect(function()
	if enabled == false then
		enabled = true
		for i,v in pairs(plr.Character:GetChildren()) do
			if v:IsA("Part") or v:IsA("MeshPart") or v:IsA("UnionOperation") then
				if v.Name ~= "HumanoidRootPart" then
					v.Transparency = 0.97					
				end
				
			end
			if v:IsA("Accessory") then
				v.Handle.Transparency = 0.97		
			end
			if v.Name == "Head" then				
				v.face.Transparency = 0.97				
			end
		end
     end
end)
2 Likes

From what I can tell, your script works except it won’t replicate due to it being a LocalScript (as you pointed out.)

To answer your question, yes, you would use a RemoteEvent to achieve this effect.

So I tried to invoke a server event, but didn’t the player is still visible to other players.

This is my code
LocalClient:

local enabled = false
local plr = game.Players.LocalPlayer
local char = plr.Character

script.Parent.Activated:Connect(function()	
	
	if enabled == false then
	enabled = true
	game.ReplicatedStorage.Invisible:FireServer(enabled)

		for i,v in pairs(char:GetChildren()) do
			if v:IsA("Part") or v:IsA("MeshPart") or v:IsA("UnionOperation") then
				if v.Name ~= "HumanoidRootPart" then
					v.Transparency = 0.97					
				end
				
			end
			if v:IsA("Accessory") then
				v.Handle.Transparency = 0.97		
			end
			if v.Name == "Head" then				
				v.face.Transparency = 0.97				
			end
		end
	elseif enabled == true then
		enabled = false
		for i,v in pairs(char:GetChildren()) do
			if v:IsA("Part") or v:IsA("MeshPart") or v:IsA("UnionOperation") then
				if v.Name ~= "HumanoidRootPart" then
					v.Transparency = 0
				end
			end
			if v:IsA("Accessory") then
				v.Handle.Transparency = 0
			end
			if v.Name == "Head" then				
				v.face.Transparency = 0				
			end
		end
	end
end)

And this is what I have on the server

Server:

game.ReplicatedStorage.Invisible.OnServerEvent:Connect(function(plr, enabled)	
	
	if enabled == false then
		enabled = true
		for i,v in pairs(plr.Character:GetChildren()) do
			if v:IsA("Part") or v:IsA("MeshPart") or v:IsA("UnionOperation") then
				if v.Name ~= "HumanoidRootPart" then
					v.Transparency = 0.97					
				end
				
			end
			if v:IsA("Accessory") then
				v.Handle.Transparency = 0.97		
			end
			if v.Name == "Head" then				
				v.face.Transparency = 0.97				
			end
		end
	elseif enabled == true then
		enabled = false
		for i,v in pairs(plr.Character:GetChildren()) do
			if v:IsA("Part") or v:IsA("MeshPart") or v:IsA("UnionOperation") then
				if v.Name ~= "HumanoidRootPart" then
					v.Transparency = 0
				end
			end
			if v:IsA("Accessory") then
				v.Handle.Transparency = 0
			end
			if v.Name == "Head" then				
				v.face.Transparency = 0				
			end
		end
	end
end)

Sorry these remote events are fairly new to me. Can you please give me a little more direction.

ServerScript:

local RemoteEvent = Instance.new("RemoteEvent", game.ReplicatedStorage)
RemoteEvent.Name = "ChangeVisibility"
local LastInvoke = {}
local Cooldown = 5
local CooldownForTrueOnly = true


RemoteEvent.OnServerEvent:Connect(function(player, value)
	local Found = nil
	for i,v in pairs(LastInvoke) do
		if v[1] == player.UserId then
			Found = v
		end
	end
	if Found then
		if CooldownForTrueOnly then
			if value then
				if tick() - Found[2] >= Cooldown then
					for i,v in pairs(LastInvoke) do
						if v == Found then
							v[2] = tick()
						end
					end
				else
					print("Visiblity Cooldown For: "..player.Name..", Time Left: "..math.ceil(Cooldown - (tick() - Found[2])).."s")
					return
				end
			end
		else
			if tick() - Found[2] >= Cooldown then
				for i,v in pairs(LastInvoke) do
					if v == Found then
						v[2] = tick()
					end
				end
			else
				print("Visiblity Cooldown For: "..player.Name..", Time Left: "..math.ceil(Cooldown - (tick() - Found[2])).."s")
				return
			end
		end

	else
		table.insert(LastInvoke, {player.UserId, tick()})
	end
	local Character = player.Character or player.CharacterAdded:Wait()
	if Character then
		for i,v in pairs(Character:GetChildren()) do
			
			if v:IsA("Accessory") then
				if value then v.Handle.Transparency = 1 else v.Handle.Transparency = 0 end
			else
				if v.Name ~= "HumanoidRootPart" then
					pcall(function()
						if value then v.Transparency = 1 else v.Transparency = 0 end
					end)
				end
			end
			if v.Name == "Head" then
				if value then v.face.Transparency = 1 else v.face.Transparency = 0 end
			end
		end
	end
end)

LocalScript:

game.ReplicatedStorage:WaitForChild("ChangeVisibility"):FireServer(true)
wait(5)
game.ReplicatedStorage:WaitForChild("ChangeVisibility"):FireServer(false)

Wow thank-you and clearly I was a long way from figuring this out.

In principle this worked, but this is a tool which is activated by clicking on the player once the tool is selected.

So I changed the LocalScript code to this:

local enabled = false
	
script.Parent.Activated:Connect(function()	
	
	if enabled == false then
		enabled = true
			game.ReplicatedStorage:WaitForChild("ChangeVisibility"):FireServer(true)	
	elseif enabled == true then
			game.ReplicatedStorage:WaitForChild("ChangeVisibility"):FireServer(false)
	end

end)

The result is I can manually invoke invisibility and then turn it off sometime later. But only once.
Looking at your code I was thinking it’s the cooldown but it doesn’t allow a second activation even after 5 secs.
Any ideas?

That seems really overcomplicated for a simple invisibilty script.

Assuming he’s using a Tool, the local script code should look like this.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local tool = script.Parent

tool.Activated:Connect(function() 
    ReplicatedStorage.Invisibility:FireServer()
end)

With Server Script code looking like this.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Invisibility = ReplicatedStorage.Invisibility

local invisiblePlayers = {}
local invisibilityDebounce = {}

Invisibility.OnServerEvent:Connect(function(player)
	if (invisibilityDebounce[player.Name] and os.clock() - invisibilityDebounce[player.Name] < 5) then
		return
	end
	
	local character = player.Character
	
	if invisiblePlayers[player.Name] then
		
		for _, v in pairs(character:GetDescendants()) do
			if ((v:IsA("BasePart") or v:IsA("Decal")) and v.Name ~= "HumanoidRootPart") then
				v.Transparency = 0
			end
		end
		
		invisiblePlayers[player.Name] = nil
		invisibilityDebounce[player.Name] = os.clock()
	else
		
		for _, v in pairs(character:GetDescendants()) do
			if v:IsA("BasePart") or v:IsA("Decal") then
				v.Transparency = 1
			end
		end
		
		invisiblePlayers[player.Name] = true
		invisibilityDebounce[player.Name] = os.clock()
	end
	
end)
1 Like

Looks like you forgot to change your variable back to false

Try this:

Serverscript (Switched To A Remote Function)

local RemoteFunction = Instance.new("RemoteFunction", game.ReplicatedStorage)
RemoteFunction.Name = "ChangeVisibility"
local LastInvoke = {}
local Cooldown = 5
local CooldownForTrueOnly = true


RemoteFunction.OnServerInvoke = function(player, value)
	local Found = nil
	for i,v in pairs(LastInvoke) do
		if v[1] == player.UserId then
			Found = v
		end
	end
	if Found then
		if CooldownForTrueOnly then
			if value then
				if tick() - Found[2] >= Cooldown then
					for i,v in pairs(LastInvoke) do
						if v == Found then
							v[2] = tick()
						end
					end
				else
					print("Visiblity Cooldown For: "..player.Name..", Time Left: "..math.ceil(Cooldown - (tick() - Found[2])).."s")
					return {false, Cooldown - (tick() - Found[2])}
				end
			end
		else
			if tick() - Found[2] >= Cooldown then
				for i,v in pairs(LastInvoke) do
					if v == Found then
						v[2] = tick()
					end
				end
			else
				print("Visiblity Cooldown For: "..player.Name..", Time Left: "..math.ceil(Cooldown - (tick() - Found[2])).."s")
				return {false, Cooldown - (tick() - Found[2])}
			end
		end
		
	else
		table.insert(LastInvoke, {player.UserId, tick()})
	end
	local Character = player.Character or player.CharacterAdded:Wait()
	if Character then
		for i,v in pairs(Character:GetChildren()) do
			
			if v:IsA("Accessory") then
				if value then v.Handle.Transparency = 1 else v.Handle.Transparency = 0 end
			else
				if v.Name ~= "HumanoidRootPart" then
					pcall(function()
						if value then v.Transparency = 1 else v.Transparency = 0 end
					end)
				end
			end
			if v.Name == "Head" then
				if value then v.face.Transparency = 1 else v.face.Transparency = 0 end
			end
		end
	end
	return true
end

Localscript In Tool:

local enabled = false
script.Parent.Name = "Invisibility: Off"


script.Parent.Activated:Connect(function()	
	if enabled == false then
		local result = game.ReplicatedStorage:WaitForChild("ChangeVisibility"):InvokeServer(true)
		if result == true then
			enabled = true
			script.Parent.Name = "Invisibility: On"
		elseif type(result) == "table" then
			script.Parent.Name = "Cooldown"
			wait(result[2])
			script.Parent.Name = "Invisibility: Off"
		end
	elseif enabled == true then
		local result = game.ReplicatedStorage:WaitForChild("ChangeVisibility"):InvokeServer(false)
		if result == true then
			enabled = false
			script.Parent.Name = "Invisibility: Off"
		end
	end
end)
1 Like

Yes that works perfectly. Thank-you for your help.
I’m learning new stuff everyday and updating the tool text is a nice little feature I didn’t know you could even do.

Thank-you.

Wow Interesting. This works too. And the players pets become invisible too which is kinda cool.
Putting it to the testers. That’s for adding another possible solution.

[There are so many way to code the same thing, and I wish there was more in the community on best practice (efficient) coding]

Thanks again.