New children don't get detected with GetChildren()

When using the GetChildren function, newly added objects will not be detected until the script is cut and pasted.

If this script is written after the object called ‘Object’ is created, it will print: ‘appeared’

StarterGui >

  • Script (new)
  • Object

(This script is placed in the PlayerGui)

function search(parent, item)
	for i,v in pairs (parent:GetChildren()) do
		if v.Name == item then
			print('appeared')
		end
	end
end

search(script.Parent, 'Object')

OUTPUT: appeared

But if we create a new object within the PlayerGui and call it ‘New’ then run the script, the script will not print: ‘appeared’

StarterGui >

  • Script (old)
  • New (new)
search(script.Parent, 'New')

OUTPUT: none

This is then fixed by cutting and pasting the script back into the PlayerGui

I have difficulty explaining it, but it tested it on studio and in-game and it had the same outputs.

All scripts, by default, are executed once.

In case 1, when everything works according to spec, the object is already there.

In case 2, the script has already completed its task (which was before the new object was created and parented), so it will not print anything.

It works correctly when you cut and paste because you are manually re-executing the script.

To remedy this, you would want to hook up an event that fires whenever an object is parented to the directory. Depending on your use case, you may not even need to use :GetChildren() to search through the objects in the directory.

Example: There are 0 frames in the path. You want to do something whenever a frame is created and parented to the path.

path.ChildAdded:connect(function(object)
  if object == a frame then
    -- do stuff
  end
end)
3 Likes

As @Chaotic_Cody has said, by the time you “create” a new object, supposedly manually and not via script before calling the function, the script has probably already finished.
The most logical solution is to use a ChildAdded listener.

Code Review
--[[
    Prints "appeared" for every child of <parent> with a name equal to <item>
    parent: The parent of an object.
    item: Object's name.
]]
function search(parent, item)
	for i,v in pairs (parent:GetChildren()) do
		if v.Name == item then
			print('appeared')
		end
	end
end

-- Let's create 10 Frames called "New" for science
local f = Instance.new('Frame')
f.Name = 'New'

for i = 1, 10 do
f = f:Clone()
f.Parent = script.Parent
end

search(script.Parent, 'New') -- Output: appeared (x10)

Oh, I forgot to say that I wasn’t replacing the script in play mode, but in edit mode. Firstly I ran the game and it detected the object called ‘Object’. Then I stopped the game, added a new object called ‘New’, ran it, and it didn’t detect that until I cut and pasted the script.

I encountered this because my mobile scale-down script didn’t scale down new UI I created in edit mode. I had to cut and paste the script for it to work.

1 Like