Is there a better way to check when a player touches any of the children of a model?

Hello, I was wondering if there was a better way to going about what the script below does. I am more concerned about the script causing lag in this matter rather than much of anything else.

What the script does is simply get the children of a model and detect when a player touches any of the children. If a player touches the child, the childs transparency goes to 0. all of the other touching parts in the model that are touching the current child also get a transparency of 0. After that, a loop makes the transparency slowly get back to 1 for each part.

wait(math.random(1,2))

local model = {
	
	game.Workspace.Part1;
	game.Workspace.Part2;
	game.Workspace.Part3;
	game.Workspace.Part4;
	game.Workspace.Part5;
	game.Workspace.Part6;
}

-----	-----------	----	--------------
--Start:

for nam, obj in pairs(model) do
	if obj.ClassName == "Part" then
		--Get the object ready:----------
		if obj.Tranparency ~= 1 then
			obj.Transparency = 1
		end
		
		if obj:FindFirstChild("SoundFX") == nil then
			local newsom = Instance.new("Sound")
			newsom.SoundId = "rbxassetid://1324318825"
			newsom.Name = "SoundFX"
			newsom.Looped = false
			newsom.Parent = game.ReplicatedStorage
			newsom.Parent = obj
			newsom:Stop()
		end
		
		if obj:FindFirstChild("Activator") == nil then
			local newActivator = Instance.new("BoolValue")
			newActivator.Name = "Activator"
			newActivator.Parent = obj
		end
		------:Start:---------
		local function GetTouchingParts(part)
			local connection = part.Touched:Connect(function() end)
			local results = part:GetTouchingParts()
			for _, p in next, results do
				if p.ClassName == "Part" and p:FindFirstChild("Activator") then
					if p.Activator.Value == false then
						wait(0.05)
						p.Activator.Value = true
					end
				end
			end;

			connection:Disconnect()
			return results
		end
		
		local activator = obj:FindFirstChild("Activator")
		local actviator_ACTIVE = false
		
		activator.Changed:Connect(function()
			if activator.Value == true then
				if actviator_ACTIVE == false then
					actviator_ACTIVE = true
					
					obj.Transparency = 0
					local results = GetTouchingParts(obj)
					
					while obj.Transparency < 1 do
						wait(0.02)
						obj.Transparency = obj.Transparency + 0.1
						if obj.Transparency >= 1 then
							obj.Transparency = 1 
							break;
						end
					end
					
					
					wait(0.2)
					activator.Value = false
					actviator_ACTIVE = false
				end
			end
		end)
		
		local Plr_Touched = false
		obj.Touched:Connect(function(hit)
			if hit and hit.Parent then
				if hit.Parent:FindFirstChild("Humanoid") then
					local humanoid = hit.Parent:FindFirstChild("Humanoid") 
					
					if Plr_Touched == false then
						Plr_Touched = true
						
						if activator.Value == false then
							activator.Value = true
						end
						
						wait(0.5)
						Plr_Touched = false
					end
				end
			end
		end)
	end
end

Put each of your parts in a folder and call GetChildren on that folder, it makes your code easier to maintain if you were to put more parts in the folder. It also means you dont have to structure your parts like Part1, Part2 Part3 and so on…

local parts = workspace.Parts:GetChildren()

You also dont need to wait at the beginning of a script.

Can you elaborate a little bit or perhaps show me some more code ? Is the script already fine as it is? and all I need to do is put them in a folder?

To be clear, I have no errors. My script works completely fine as it is. I simply want change code a little bit because I know there is probably a less laggier and more efficient way to do what I am trying to do. That is what I am asking for.

So I am already doing it efficiently I guess…?

here’s some untested code

local Players = game.Players
local Model = workspace.TouchPartsModel
local Parts = Model:GetChildren()

function MakeTransparent(Part: BasePart)
      if Part.Transparency ~= 1 then
        Part.Transparency = 1
        spawn(function()
            wait(3)
            Part.Transparency = 0 
        end)
        for index,TouchingPart in ipairs(Part:GetTouchingParts()) do
              MakeTransparent(TouchingPart)
          end
    end
end


for index,Part in ipairs(Parts) do
  if Part:IsA("BasePart") then
    
    Part.Touched:Connect(function(HitPart)
        if HitPart.Parent:FindFirstChildOfClass("Humanoid") then
              MakeTransparent(HitPart)
        end
    end)
    
  end
end

This assumes there’s a Model named “TouchPartsModel” under workspace with all the parts that can be touched.

1 Like