ScrollingFrame's ChildAdded Function isn't triggering

This requires some background context:

I have a ScrollingFrame in the PlayerGUI which has a script called SetupBuy, which creates the list of items in the ScrollingFrame based on a template so that no matter how many items I add, it’ll automatically update the ScrollingFrame list.

This is the script:

local buyableSeeds = game:GetService("ReplicatedStorage"):WaitForChild("buyableSeeds"):GetChildren()

for i, v in pairs(buyableSeeds) do
	local template = script:WaitForChild("SeedSelectionTemplate"):Clone()
	template.Parent = script.Parent
	template.Name = v.Name
	template.Visible = true
	
	local templateSeedDetails = template.SeedDetails
	templateSeedDetails.SeedName.Text = v.Name
	template.Price.Value = v:GetAttribute("PriceCents")
	templateSeedDetails.SeedPrice.Text = template.Price.Value.."¢"
	
	local templateSeedPayment = template.SeedPayment
		
	if v:GetAttribute("PriceCents") == 0 then
		templateSeedPayment.BuyButton_Cents.Text = "Free"
	else
		templateSeedPayment.BuyButton_Cents.Text = v:GetAttribute("PriceCents").."¢"
	end
	
	if v:GetAttribute("PriceRobux") == 0 then
		templateSeedPayment.BuyButton_Robux.Text = "Free"
	else
		templateSeedPayment.BuyButton_Robux.Text = v:GetAttribute("PriceRobux")..utf8.char(0xE002)
	end

	local seedClone = v:Clone()
	seedClone.Parent = templateSeedDetails.SeedViewportFrame

	local camera = Instance.new("Camera")
	camera.Parent = templateSeedDetails.SeedViewportFrame
	templateSeedDetails.SeedViewportFrame.CurrentCamera = camera

	if seedClone.PrimaryPart then
		local distance = seedClone:GetAttribute("CameraDistance")
		camera.CFrame = CFrame.new(seedClone.PrimaryPart.Position + Vector3.new(0, distance / 2, distance), seedClone.PrimaryPart.Position)
	end

	task.spawn(function()
		while true do
			seedClone:SetPrimaryPartCFrame(seedClone.PrimaryPart.CFrame * CFrame.Angles(0, math.rad(1), 0))
			task.wait(0.01)
		end
	end)
end

And this is the hierarchy to show exactly where the template is:

Now in the BuyScript, there is supposed to be some code to check if ChildAdded occurs on the ScrollingFrame, and then have the Buy Buttons work respectively. However, the script doesn’t work for some reason, so I’ve simplified it to just print a statement when ChildAdded occurs to try and troubleshoot the problem:

local parentInstance = script.Parent

parentInstance.ChildAdded:Connect(function(seedItem)
	print(seedItem.Name .. " added to the " .. parentInstance)
end)

No matter how I approach this, this print statement doesn’t fire in the console, so what exactly am I missing here?

Is the last code the full script or only parts of it? Also can you try to print hello or something to double check the script runs it the first place, maybe also print parentInstance.Name

The last code is the full script, and I did do a version that does print only “hello” or “printed”, but it still didn’t work.

So if you add below the connect function this code:

task.wait(1)
print(parentInstance.Name)
local c = Instance.new("Frame")
c.Parent = parentInstance
print("The connect function print should be above this^")
1 Like

so if I understand correctly, you make a childadded connection to give the buy robux and buy cents buttons their functionality.
You can just do this in the giant for loop that you have, at the end you could just give them their functionality, this way, you don’t need that extra connection and you won’t have this problem.

Ok, let’s just ignore that detail; I think your SetupBuy script is probably being loaded first and running first so your childadded connection doesn’t fire because all of the buttons were added before script made the connection. This is just a theory though, I didn’t look at the entire script (but I did see the unkillable infinite while loop, you might want to consider removing it and looking for a more performant replacement).

So either, merge the two scripts and add the connection at the top of the setupbuy script before you run your for loop, or just do it in the for loop (probably the best).

Hope this helps!

4 Likes

in the case where the SetupBuy script runs before BuyScript, all the instances will already be added to the frame as children, and so will not be detected by the ChildAdded listener in the BuyScript.

In the BuyScript, along with the ChildAdded listener, you should iterate over and detect/initialise already existing children of the frame.

1 Like

Thanks for all the suggestions guys, I ended up implementing the “merge both scripts and have the ChildAdded function above the forLoop” solution and it worked great!

I might have to change it later on to be more performative and optimized, but for now it works and happy with it.