Yes. Almost always it is better to do it that way.
In general, you'll have a very similar looking script. There will just be an addition of a loop to perform the action on each part (or maybe several loops in things that require wait
ing). For example, if there was a Model of parts that you wanted to change color when touched, you would just have to modify the event to use a closure:
2 | me.BrickColor = hit.BrickColor |
5 | for _, part in pairs ( workspace.Model:GetChildren() ) do |
6 | part.Touched:connect( function (h) |
The above corresponds to something like this:
2 | script.Parent.BrickColor = hit.BrickColor |
4 | script.Parent.Touched:connect( Touch ) |
A more complicated example is to make a list of parts flip between blue and red every second. The single script for each might look like this:
2 | script.Parent.BrickColor = BrickColor.Red(); |
4 | script.Parent.BrickColor = BrickColor.Blue(); |
If you don't think carefully about it, you might try translating it into the following:
2 | for _, part in pairs ( workspace.Model:GetChildren() ) do |
4 | part.BrickColor = BrickColor.Red(); |
6 | part.BrickColor = BrickColor.Blue(); |
Why? Because it starts an unending loop for just the first part, and never even gets to the second. Removing the loop will be a bit better, but it will do each part in sequence, rather than all at once.
A simple solution is to use 2 for
loops:
02 | for _, part in pairs ( workspace.Model:GetChildren() ) do |
03 | part.BrickColor = BrickColor.Red(); |
06 | for _, part in pairs ( workspace.Model:GetChildren() ) do |
07 | part.BrickColor = BrickColor.Blue(); |
This could be cleaned up with the help of a function to paint a list of parts (avoiding the repeated code)
An even more complicated example is when you want to do the above but you want them each to be flashing at random offsets, e.g.,
2 | script.Parent.BrickColor = BrickColor.Blue() |
4 | script.Parent.BrickColor = BrickColor.Red() |
A direct way to do it is to spawn a new coroutine for each part:
03 | part.BrickColor = BrickColor.Blue() |
05 | part.BrickColor = BrickColor.Red() |
12 | for _, part in pairs ( workspace.Model:GetChildren()) do |
13 | spawn( function () flash(part) end ) |
Though this isn't very elegant because spawning a large number of threads in general can cause difficulties.
Unfortunately, a direct way to do this in one thread is much more sophisticated (though possible):
02 | for _, part in pairs (workspace.Model:GetChildren()) do |
05 | time = math.random() + tick() , |
15 | for part, data in pairs ( changes ) do |
16 | soonest = math.min( soonest, data.time ) |
18 | wait( soonest - tick() ) |
24 | for part, data in pairs ( changes ) do |
25 | if data.time < tick() then |
27 | part.BrickColor = BrickColor.Red() |
29 | part.BrickColor = BrickColor.Blue() |
31 | data.red = not data.red |
32 | data.time = tick() + math.random() |