Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Is it possible to GetChildren() and change their properties?

game.Workspace.InvisibleWalls:GetChildren().CanCollide = false
game.Workspace.Doors:GetChildren().CanCollide = false
game.Workspace.Doors:GetChildren().Transparency = 1

for _, v in ipairs(Workspace.InvisibleWalls:GetChildren()) do
    if v:IsA("BasePart") then
        v.CanCollide = false
    end
end

How can I get those top 3 into justone loop?

3 answers

✓ Accepted answer

The other answers haven't addressed putting this into one (property changing) loop, and though in this situation it's perhaps not the best solution, it can be done.

Joining Two Lists

We have two lists:

local walls = game.Workspace.InvisibleWalls:GetChildren()
local doors = game.Workspace.Doors:GetChildren()

We can join them together to make a single list (though this requires a loop since Lua does not have this as a built in function)

local parts = walls
for _, door in pairs(doors) do
	table.insert(parts, door)
end

We can now have a single loop that will change the properties of objects in both lists (because we've turned it into just one)

We want all parts to have their CanCollide property set to false, and just those children of Doors to become invisible. It could look like this:

for _, part in pairs(parts) do
	if part:IsA("BasePart") then
		-- If `part` is actually a Part as opposed to some other
		-- object like a Script or Model
		part.CanCollide = false
		if part.Parent == workspace.Doors then
			-- Is a door
			part.Transparency = 1
		end
	end
end



Or, Using a New Iterator

We can define our own ipairs like iterator for a for loop which will take two lists in and just iterate over both of them. This means we no longer need the initial joining loop, though we do need a more complicated construct..

function joinobjs(one, two)
	local i = 0
	return function()
		i = i + 1
		if i <= #one then
			return one[i]
		elseif i <= #one + #two then
			return two[i - #one]
		end
	end
end

Now we just use the loop from the previous one with a different line for the for:

for part in joinobjs(parts) do
	if part:IsA("BasePart") then
		-- If `part` is actually a Part as opposed to some other
		-- object like a Script or Model
		part.CanCollide = false
		if part.Parent == workspace.Doors then
			-- Is a door
			part.Transparency = 1
		end
	end
end

As you may know, GetChildren returns a table of every child of the parent. In order to set all of the children individually you must iterate through the table.

Two Options

Option 1

local children=Workspace.InvisibleWalls:GetChildren()
for i=1, #children do
if children[i]:IsA("BasePart") then --make sure we are editing a part!
children[i].CanCollide=false
end
end

Option 2

local children=Workspace.InvisibleWalls:GetChildren()
for index, value in pairs(children) do
if value:IsA("BasePart") then --make sure we are editing a part!
value.CanCollide=false
end
end

2 comments

0

do I have to use a for loop. I am sure they dont have to be so long and complicated

0

You have to use some kind of loop to iterate over the contents of a Table, as you want to do. I'll write an answer that contains more typically used code for this.

As promised:

for _, v in ipairs(Workspace.InvisibleWalls:GetChildren()) do
	if v:IsA("BasePart") then
		v.CanCollide = false
	end
end

This, I should mention, is functionally identical to l0cky's "Option 2", just using current practices.

2 comments

1

whats the IsA("BasePart") ????

1

IsA is a method of all Instances that checks whether the Instance is of a certain class or inherits from it. For example, a Part is a Part because it is, but it is also a BasePart because the WedgePart class inherits from the BasePart class. Checking for IsA("BasePart") check if the Object in question is a Part, WedgePart, or Truss in one method call.

This discussion is preserved as it was. New answers, comments, and votes are closed.