I have a script in my game that selects all the parts of 10 models and changes their transparency. Problem is, the script is pretty long when using 10 for loops for every model. And no, I can't combine all the parts into 1 model, because it would ruin other scripts I have for my game. Simply, I want to know if there's a way to turn this type of code:
local model1 = game.Workspace.model1:GetChildren() for i = 1, #model1 do model1[i].Transparency = 1 end local model2 = game.Workspace.model2:GetChildren() for i = 1, #model2 do model2[i].Transparency = 1 end local model3 = game.Workspace.model3:GetChildren() for i = 1, #model3 do model3[i].Transparency = 1 end --etc
into something with maybe 5 lines.
I'm quite unsure about combining "for" loops except to tell you to nest them together and put the model variables in a table like so:
model1 = game.Workspace.model1:GetChildren() model2 = game.Workspace.model2:GetChildren() model3 = game.Workspace.model3:GetChildren() MODELtable = {model1, model2, model3} for i = 1, #MODELtable do for i2 = 1, #MODELtable[i] do MODELtable[i][i2].Transparency = 1 end end
But you could also combine tables with a function instead.
totalmodel = {} -- Initialized the total children of all models, which has a length of 0. model1 = game.Workspace.model1:GetChildren() model2 = game.Workspace.model2:GetChildren() model3 = game.Workspace.model3:GetChildren() function tableinsert(TABLE) -- TABLE is the argument for efficiency. for i = 1, #TABLE do table.insert(totalmodel, (#totalmodel + 1), TABLE[i]) -- Adds the elements in the totalmodel table. end end tableinsert(model1) tableinsert(model2) tableinsert(model3) for i = 1, #totalmodel do totalmodel[i].Transparency = 1 end -- Both code tested and works.
Check back with me if you have any questions.
For your particular code, we can see that we're just repeating the same code, so it might just make more sense to make a function:
function hide(model) for _, part in pairs(model:GetChildren()) do part.Transparency = 1 end end hide(game.Workspace.model1) hide(game.Workspace.model2) hide(game.Workspace.model3)
I use a generic for
loop instead to be a bit cleaner -- you avoid having to say model[i]
, which I think makes it much easier to read / understand.
If you have a bunch of these models to do this to, it's now easy to make that into a loop:
for _, mod in pairs(workspace.Hidden:GetChildren()) do hide(mod) end
Here's a stranger way to do it, that turns out to be the same (just for fun)
m1 = workspace.model1:GetChildren() m2 = workspace.model2:GetChildren() m3 = workspace.model3:GetChildren() for i = 1, #m1 + #m2 + #m3 do local which if i <= #m1 then which = m1 else i = i - #m1 if i <= #m2 then which = m2 else i = i - #m2 which = m3 end end local part = which[i] part.Transparency = 1 end
This is for the particular case of 3 models. It basically jams the three lists next to each other, so that once one list ends, the next begins at the next index.
This is a mess to do, so let's not do that. If we make it more general, it actually cleans up:
local ms = {m1, m2, m3} local total = 0 for _, m in pairs(ms) do total = total + #m end for i = 1, total do local which = 1 while i > #ms[which] do i = i - #ms[which] which = which + 1 end ms[which][i].Transparency = 1 end
This still isn't very clean. The reason is clear in the last line; our outer loop uses i
but the first thing we care about is which
, so we should just flip them:
for which = 1, #ms do for i = 1, #ms[which] do ms[which][i].Transparency = 1 end end
which, which generic for
loops, looks much neater:
for _, m in pairs(ms) do for _, part in pairs(m) do part.Transparency = 1 end end
(Which is the straightforward top solution)