Skip to content

Instantly share code, notes, and snippets.

@mvyasu
Last active February 27, 2025 22:22
Show Gist options
  • Select an option

  • Save mvyasu/9f35377e79dc2b09dfe61812ffeb5460 to your computer and use it in GitHub Desktop.

Select an option

Save mvyasu/9f35377e79dc2b09dfe61812ffeb5460 to your computer and use it in GitHub Desktop.
A quick and easy way to hide characters by setting attributes. If you want this to work with StreamingEnabled, you should handle the tagging of characters with a server script instead of with the provided snippet at the bottom.
--by @mvyasu
--4 May 2023
--A quick and easy way to hide characters by setting attributes
--To change whether characters are hidden do: game.Players:SetAttribute("HideCharacters", true)
--To exclude a player's character from being hidden do: game.Players.LocalPlayer:SetAttribute("NeverHideCharacter", true)
local CHARACTER_TAG = game:GetService("HttpService"):GenerateGUID()
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
do --handles the transparency of the characters
local function cleanupObject(object: any)
local t = typeof(object)
if t == "function" then
object()
elseif t == "RBXScriptConnection" then
object:Disconnect()
elseif t == "table" or t =="Instance" then
if object.Destroy then
object:Destroy()
else
for _,child in pairs(object) do
cleanupObject(child)
end
table.clear(object)
end
elseif t == "thread" then
coroutine.close(object)
end
end
local characterCleanupObjects = {}
local function onCharacterAdded(character)
if characterCleanupObjects[character] then
return
end
--the or statement is needed because apparently :GetPlayerFromCharacter() has a race condition
local player = Players:GetPlayerFromCharacter(character) or Players:FindFirstChild(character.Name)
if player==nil then
return
end
local objectsToCleanup: {[any]: any} = {}
characterCleanupObjects[character] = objectsToCleanup
do --handles when and what to set the transparency to
local wasHiddenLastUpdate = nil
local function shouldBeHidden(): boolean
return Players:GetAttribute("HideCharacters") and not player:GetAttribute("NeverHideCharacter")
end
local function setDescendantTransparency(object: any, forcedTransparency: number?)
if object:IsA("BasePart") or object:IsA("Decal") then
object.LocalTransparencyModifier = forcedTransparency or (if wasHiddenLastUpdate then 1 else 0)
end
end
local function setCharacterTransparency()
for _,descendant in character:GetDescendants() do
setDescendantTransparency(descendant)
end
end
local lastForceTransparencyConnection = nil
local function onHiddenStatusChanged(isCharacterHidden)
if player~=Players.LocalPlayer then
return
end
if lastForceTransparencyConnection then
lastForceTransparencyConnection:Disconnect()
table.remove(objectsToCleanup, table.find(objectsToCleanup, lastForceTransparencyConnection))
end
if isCharacterHidden then
local newForceTransparencyConnection = game:GetService("RunService").RenderStepped:Connect(setCharacterTransparency)
lastForceTransparencyConnection = newForceTransparencyConnection
table.insert(objectsToCleanup, newForceTransparencyConnection)
end
end
local function updateCharacterTransparency(forceUpdate: boolean?)
local shouldHideCharacter = shouldBeHidden()
if shouldHideCharacter==wasHiddenLastUpdate and not forceUpdate then
return
end
if wasHiddenLastUpdate~=shouldHideCharacter then
onHiddenStatusChanged(shouldHideCharacter)
end
wasHiddenLastUpdate = shouldHideCharacter
setCharacterTransparency()
end
updateCharacterTransparency()
table.insert(objectsToCleanup, {
character.DescendantAdded:Connect(setDescendantTransparency),
character.DescendantRemoving:Connect(function(descendant)
setDescendantTransparency(descendant, 0)
end),
player:GetAttributeChangedSignal("NeverHideCharacter"):Connect(updateCharacterTransparency),
Players:GetAttributeChangedSignal("HideCharacters"):Connect(updateCharacterTransparency),
})
end
end
CollectionService:GetInstanceAddedSignal(CHARACTER_TAG):Connect(onCharacterAdded)
for _,character in CollectionService:GetTagged(CHARACTER_TAG) do
task.spawn(onCharacterAdded, character)
end
CollectionService:GetInstanceRemovedSignal(CHARACTER_TAG):Connect(function(character)
local objectsToCleanup = characterCleanupObjects[character]
if objectsToCleanup then
cleanupObject(objectsToCleanup)
characterCleanupObjects[character] = nil
end
end)
end
do --handles tagging the player with a tag defined by CHARACTER_TAG
local function onCharacterAdded(character)
CollectionService:AddTag(character, CHARACTER_TAG)
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(onCharacterAdded)
if player.Character then
task.spawn(onCharacterAdded, player.Character)
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
for _,player in Players:GetPlayers() do
task.spawn(onPlayerAdded, player)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment