Add a script to multiple parts at once

I’m trying to make a game and I need this script added to every part of a building. Is there a way to add the script to every part at once instead of having to add it to each part individually?

This is the script I need on the parts

-- Script for unanchoring a part when touched by a player

local part = script.Parent  -- Assuming this script is a child of the part

local function onTouched(other)
    local character = other.Parent
    local humanoid = character:FindFirstChildWhichIsA("Humanoid")

    -- If touched by a player's humanoid, unanchor the part
    if humanoid then
        part.Anchored = false
    end
end

part.Touched:Connect(onTouched)

Thank you!

  1. Don’t add a script for each individual part - manage it all from one script.
  2. If you really want to add a script to each part, iterate through all the descendants of the main building.
local scriptToClone = --path to your script here. Make sure it is disabled!
local building = --path to your building here

for i, v in ipairs(building:GetDescendants()) do
    if v:IsA("Part") then
        local clonedScript = scriptToClone:Clone()
        clonedScript.Parent = v
        clonedScript.Enabled = true
    end
end
local Buildings = {} --> Get the Children of a folder of buildings, or something.
local function ControlEvents()
   for _, Building in Buildings do
      for _, Part in Building:GetDescendants() do
         --> Add touched events here. This isn't very optimised, I'd suggest grouping the parts under a folder that you want to be interacted with, sometimes *every* part isn't the best.
      end
   end
end

task.spawn(function() --> Not recommended, use coroutines instead. Just a quick method.
   ControlEvents()
end)

Yes, there actually is. You can create a serverscript using the CollectionSerivce!

image

Click the plus to add the tag, then here is the following code:

local CollectionService = game:GetService("CollectionService")
local tag = "tag" -- Put your tag here

for _, part: BasePart in pairs(CollectionService:GetTagged(tag)) do
	-- Script for unanchoring a part when touched by a player
	part.Touched:Connect(function(hit)
		local character = hit.Parent
		local humanoid = character:FindFirstChildWhichIsA("Humanoid")

		-- If touched by a player's humanoid, unanchor the part
		if humanoid then
			part.Anchored = false
		end
	end)
end

To make your life much easier I would install use collection serivce

Tag Editor - Creator Store (roblox.com)

-) Once you install it go to the plugins section and press “Tag Window”

-) Next select a part(s) that you want to tag in the explorer tab and press the checkbox while its selected

Then, add a script (Server Side) for it. I’ll write one relative to your code:

local collectionService = game:GetService("CollectionService")

local function onTouched(other, part)
	local character = other.Parent
	local humanoid = character:FindFirstChildWhichIsA("Humanoid")

	-- If touched by a player's humanoid, unanchor the part
	if humanoid then
		part.Anchored = false
	end
end

while true do
	
	for i,v in pairs(collectionService:GetTagged("--Insert Tag Name--")) do
		
		if v:IsA("BasePart") then
			v.Touched:Connect(function(other)
				onTouched(other, v)
			end)
		end
		
	end
	
	wait(0.05)
end

You can have the same script apply for thousands of objects if you want while also making it organized and easy to maintain

Don’t use pairs anymore. It’s outdated and you should just reference the table/dictionary instead of wrapping it in pairs unless you want to iterate through it sequentially, where you’d have to use ipairs. pairs is now outdated and much slower in comparison.

1 Like

Ok, thank you, I will note that for future reference!

A small nitpick, but there’s an in-built Tag Editor and using a plugin is redundant. Also, when possible do not use while true loops, because it yields and also you’re creating WAY too many event connections. Do it once, not consecutively or you’re using up too much memory. What you can do is either do it once and check for DescendantAdded in workspace or another service or just use a cache of Instances with connections already established to avoid making new ones in.

e.g (with a cache):

local collectionService = game:GetService("CollectionService")
local runService = game:GetService("RunService")

local connectionCache = {  }
local function onTouched(other, part)
	local character = other.Parent
	local humanoid = character:FindFirstChildWhichIsA("Humanoid")

	-- If touched by a player's humanoid, unanchor the part
	if humanoid then
		part.Anchored = false
	end
end

runService.Heartbeat:Connect(function()
   for _, part in BUILDINGS_TABLE do
      if connectionCache[part] then continue end
      if part:IsA("BasePart") then
         part.Touched:Connect(function(hit)
            onTouched(hit, part)
         end)
         connectionCache[part]=0 --> Not the best implementation but works well.
      end
   end
end)

The easiest way would be:

local descendants = model:GetDescendants()

for i,v in descendants do
  if v:IsA("BasePart") then
    v.Touched:Connect(function(hit)
      print('touched')
    end)
  end
end

Nevermind. My friend told me how and it worked. Thank you all for trying :slight_smile:

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