Making all parts within a model transparent when a part is touched

The goal is to make all models named “roof”'s parts in game.Workspace.roof transparent when a player touches a part. Essentially just a hit box that I fill a building with that removes roofs. I’m making an isometric game, and for aesthetic purposes I have buildings with roofs and the invisicam really suffers visually doing this. I could just delete the roofs and save me time, but I want to make things look good here! The script I have below works perfectly well, however, only works for 1 model named roof, not all of them and it seems to select a random roof each time, not the same one when testing.

local roof = game.Workspace.roof
local myPart = game.Workspace.Touchy
local Players = game.Players

-- Function to handle when the part is touched.
local function onTouch(hit)
	--Disable roof.
	if not hit or not hit.Parent then return end
	if Players:GetPlayerFromCharacter(hit.Parent) ~= Players.LocalPlayer then return end
	for i, myPart in pairs (workspace:GetChildren(roof)) do
		for i, myPart in pairs (roof:GetChildren()) do
			myPart.Transparency = 1
		end
	end
end

-- Function to handle when the part is no longer touched.
local function onUnTouch(hit)
	--Return roof.
	if not hit or not hit.Parent then return end
	if Players:GetPlayerFromCharacter(hit.Parent) ~= Players.LocalPlayer then return end
	for i, myPart in pairs (workspace:GetChildren(roof)) do
		for i, myPart in pairs (roof:GetChildren()) do
			myPart.Transparency = 0
		end
	end
end

-- Connect the onTouch function to the Touched event of the part.
myPart.Touched:Connect(onTouch)


-- Connect the onUnTouch function to the TouchEnded event of the part.
myPart.TouchEnded:Connect(onUnTouch)

Thank you if you can help me resolve this basic scripting error!

2 Likes

You can try this

local roofs = {}
local myPart = game.Workspace.Touchy
local Players = game.Players

for _, v in pairs(workspace:GetDescendants()) do
	if v.Name:lower() == "roof" and v:IsA("Model") then --> Assuming They Are a Model and named "Roof"
		table.insert(roofs, v)
	end
end

-- Function to handle when the part is touched.
local function onTouch(hit)
	--Disable roof.
	if not hit or not hit.Parent then return end
	if Players:GetPlayerFromCharacter(hit.Parent) ~= Players.LocalPlayer then return end
	for _, roof in pairs(roofs) do
		for _, part in pairs(roof:GetDescendants()) do
			if part:IsA("BasePart") or part:IsA("MeshPart") or part:IsA("UnionOperation") then
				part.Transparency = 1
			end
		end
	end
end

-- Function to handle when the part is no longer touched.
local function onUnTouch(hit)
	--Return roof.
	if not hit or not hit.Parent then return end
	if Players:GetPlayerFromCharacter(hit.Parent) ~= Players.LocalPlayer then return end
	for _, roof in pairs(roofs) do
		for _, part in pairs(roof:GetDescendants()) do
			if part:IsA("BasePart") or part:IsA("MeshPart") or part:IsA("UnionOperation") then
				part.Transparency = 0
			end
		end
	end
end

-- Connect the onTouch function to the Touched event of the part.
myPart.Touched:Connect(onTouch)


-- Connect the onUnTouch function to the TouchEnded event of the part.
myPart.TouchEnded:Connect(onUnTouch)
1 Like

That worked perfectly! Thank you for going above and beyond here!

2 Likes

You can also avoid using GetDescendants on the workspace by making a folder in workspace called “Roofs” and put all the roof models in there

Then change

local roofs = {}

To

local roofs = workspace:WaitForChild("Roofs", 1):GetChildren()

and Remove this part

for _, v in pairs(workspace:GetDescendants()) do
	if v.Name:lower() == "roof" and v:IsA("Model") then --> Assuming They Are a Model and named "Roof"
		table.insert(roofs, v)
	end
end
1 Like

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