How to hide parts (which are on Workspace) locally? Is it possible?

Hello! It’s my first post here. :sweat_smile:

I want to know whether if it’s possible / how to hide hide parts (which are on game.Workspace) locally? Here’s an example video (while not exactly what I want, just to demonstrate the mechanic I’m looking for):

As you can see, in POV 1 the second player is hidden, while in POV 2 the first player is still visible.

So is it possible to do such “magic”? How do you do it?
I couldn’t find any (useful) resources , so let me know if there are or if I missed some.

It is absolutely possible. All that developer did was turn the characters of other players invisible. Characters are ultimately made up of parts and decals whose transparencies can be altered. You’ll need to handle players who join after this setting has been set, as well as respawning players

I do know that you can make them invisible the setting the part transparencies, but the thing is that I want this setting to apply locally, in a sense that one player might not see all players, but another player could.

Also, problem is, I also need to handle multiple settings of players which contrast between each other, so I need to also handle players who haven’t respawned nor joined this moment.

(Correct me if I’m wrong or If I didn’t fully understand you)

You can do this by handling it in a local script. When something runs in a local script it only applies for that player

1 Like

As @Fune155 said, this would be handled in a LocalScript. Doing so would not replicate the transparency changes. If you were not already aware of this, take a moment to read up on Roblox’s client-server runtime model. I’ve written a script for you that implements the feature. You need only call setOthersInvisible with the setting’s current boolean state when loading the player’s settings and when the setting is changed:

--!strict
local Players = game:GetService("Players")


local invisibilityConnections = {}



local function setCharacterInvisible(character: Model, invisible: boolean)
	local transparency = if invisible then 1 else 0
	
	for _, descendant in character:GetDescendants() do
		if not (descendant:IsA("BasePart") or descendant.ClassName == "Decal") then
			continue
		end
		
		if descendant.Name == "HumanoidRootPart" then
			continue
		end
			
		(descendant :: BasePart).Transparency = transparency
	end
end

local function onCharacterAdded(character: Model)
	setCharacterInvisible(character, true)
end

local function onPlayerAdded(player: Player)
	local character = player.Character
	
	if character then
		onCharacterAdded(character)
	end
	
	invisibilityConnections[player] = player.CharacterAdded:Connect(onCharacterAdded)
end

local function onPlayerRemoving(player: Player)
	invisibilityConnections[player]:Disconnect()
	invisibilityConnections[player] = nil
end

local function setOthersInvisible(invisible: boolean)
	for _, connection in invisibilityConnections do
		connection:Disconnect()
	end
	
	invisibilityConnections = {}
	
	for _, player in Players:GetPlayers() do
		if player == Players.LocalPlayer then
			continue
		end
		
		if invisible then
			invisibilityConnections[player] = player.CharacterAdded:Connect(onCharacterAdded)
			
			invisibilityConnections.PlayerAdded = Players.PlayerAdded:Connect(onPlayerAdded)
			invisibilityConnections.PlayerRemoving = Players.PlayerRemoving:Connect(onPlayerRemoving)
		end
		
		if player.Character then
			setCharacterInvisible(player.Character, invisible)
		end
	end
end
1 Like

Ahhaaa, one question. Where do I put this script in (I know it’s in a LocalScript, but where should I put it in)?

I haven’t really read anything that was said and just breezed through but you probably should place it into StarterPlayerScripts.

If I were you, I would develop settings using modules, but the design conversation is too taxing for the DevForum. For now, you can use StarterPlayerScripts, or put it under your GUI in StarterGui

Thank you! It works very well!

Now here’s what I’ve done on my side:

SarterGUI, LocalScript (The button to hide players):

local Button = script.Parent.ScreenGui.TextButton
local Event = game:WaitForChild("ReplicatedStorage"):WaitForChild("HidePlayersEvent")

Button.MouseButton1Click:Connect(function()
	if Button.BackgroundColor3 == Color3.fromRGB(255, 255, 255) then
		Event:FireServer("Hide")
		Button.BackgroundColor3 = Color3.fromRGB(63, 63, 63)
	elseif Button.BackgroundColor3 == Color3.fromRGB(63, 63, 63) then
		Event:FireServer("Show")
		Button.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
	else
		warn("Error :( (Client)")
	end
end)

ServerScriptService, Script (Gets the Event from the Client and fires it back to activate the setting locally):

game:WaitForChild("ReplicatedStorage"):WaitForChild("HidePlayersEvent").OnServerEvent:Connect(function(player, Status)
	if Status == "Hide" and player then
		game:WaitForChild("ReplicatedStorage"):WaitForChild("HidePlayersEvent"):FireClient(player, "HideFromServer")
		print("Hidden all players, Server")
	elseif Status == "Show" and player  then
		game:WaitForChild("ReplicatedStorage"):WaitForChild("HidePlayersEvent"):FireClient(player, "ShowFromServer")
		print("Showen all players, Server")
	else
		warn("Error :( (Server)")
	end
end)

StarterPlayerScripts, LocalScript (Hides players locally after getting the Event from the Server):

--!strict
local Players = game:GetService("Players")


local invisibilityConnections = {}



local function setCharacterInvisible(character: Model, invisible: boolean)
	local transparency = if invisible then 1 else 0

	for _, descendant in character:GetDescendants() do
		if not (descendant:IsA("BasePart") or descendant.ClassName == "Decal") then
			continue
		end

		if descendant.Name == "HumanoidRootPart" then
			continue
		end

		(descendant :: BasePart).Transparency = transparency
	end
end

local function onCharacterAdded(character: Model)
	setCharacterInvisible(character, true)
end

local function onPlayerAdded(player: Player)
	local character = player.Character

	if character then
		onCharacterAdded(character)
	end

	invisibilityConnections[player] = player.CharacterAdded:Connect(onCharacterAdded)
end

local function onPlayerRemoving(player: Player)
	invisibilityConnections[player]:Disconnect()
	invisibilityConnections[player] = nil
end

local function setOthersInvisible(invisible: boolean)
	for _, connection in invisibilityConnections do
		connection:Disconnect()
	end

	invisibilityConnections = {}

	for _, player in Players:GetPlayers() do
		if player == Players.LocalPlayer then
			continue
		end

		if invisible then
			invisibilityConnections[player] = player.CharacterAdded:Connect(onCharacterAdded)

			invisibilityConnections.PlayerAdded = Players.PlayerAdded:Connect(onPlayerAdded)
			invisibilityConnections.PlayerRemoving = Players.PlayerRemoving:Connect(onPlayerRemoving)
		end

		if player.Character then
			setCharacterInvisible(player.Character, invisible)
		end
	end
end

---------------------------------------------------------

game:WaitForChild("ReplicatedStorage"):WaitForChild("HidePlayersEvent").OnClientEvent:Connect(function(Status)
	if Status == "HideFromServer"  then
		setOthersInvisible(true)
		print("Client side hiding complete!")
	elseif Status == "ShowFromServer"   then
		setOthersInvisible(false)
		print("Client side showing complete!")
	else
		warn("Error :( (Client, PlayerScripts)")
	end
end)

Also, the same principle should apply to parts in game.Workspace, right?

Why was a remote event was used? You can use a bindable event to trigger custom events in the same network, or simply combine my code with your GUI code. I’m not sure what you mean by “same principle” as well

By “same principle”, I mean if I can modify your script to make it hide parts (Transparency = 1), would it work? Or I need to make newer lines of code for that to work?

Hiding parts would require substantially less code, but the same idea of iterating over an array of parts and toggling their transparency applies

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.