Children Being Added Too Quickly Causing Problems With GUI Spacing

So I’m making a custom Backpack GUI whose code is currently in a primitive state. It basically tweens the position of mainframe’s children whenever a new child is added so that the images in the backpack are evenly spaced. However, if another child is added before the previous tweens are completed, the spacing becomes inconsistent.

example

For clarification, the tween lasts .5 seconds in the first example and a new child is added every 1 second. In the second example, the tween lasts .75 seconds and a new child is added every .5 seconds.
As you can see, in the second example, the spacing between the images grows more and more. My ideal solution is that the Frames would remain evenly spaced, no matter how quickly children are being added.

Here’s the part of code:

local gui = script.Parent
local tweenservice = game:GetService("TweenService")
local mainframe = gui:WaitForChild("Gui")
local tweeninfo = TweenInfo.new(1, Enum.EasingStyle.Back, Enum.EasingDirection.Out, 0, false, 0) --Time is 1 in Example 1 and .75 in Example 2
local items = {}
local tweens = {}

mainframe.ChildAdded:Connect(function(child)
	items[#items + 1] = child
	for i, v in pairs(items) do
		if v.Name == "Tool" then
			print(table.find(items, child))
			if v ~= child then
				local targetpos = UDim2.new(0, v.Position.X.Offset - 40, 0, 0)
				local currentpos = v.Position
				local tween = tweenservice:Create(v, tweeninfo, {Position = targetpos})
				table.insert(tweens, tween)
			elseif v == child then
				if items[#items - 1] then
					local previoustool = items[#items - 1]
					local targetpos = UDim2.new(0, previoustool.Position.X.Offset + 40, 0, 0)
					local tween = tweenservice:Create(v, tweeninfo, {Position = targetpos})
					table.insert(tweens, tween)
				end
			end
		end
	end
	for i, v in pairs(tweens) do
		v:Play()
	end
end)

How would I go about achieving my solution with this? Any advice or changes are appreciated.

Have you tried to wait for the first tween to finish before tweenInfo the second time?

What exactly do you mean by this? I can’t add wait time in the for loop because then the tweens would play one after the other, not the same time. Are you asking if I tried to detect if the part is being tweened?

Basically:
While part 1 is tweening part2 will wait, once part1 is done part tweeens

The reason why this may be happening could be because the target position for the tweens is dependent on another object’s position, which could cause the bug you are encountering, basically, what is happening is that the tween plays as intended, however, when you add another object to mainframe, while the tweens have not finished yet, the function will create other tweens and the target position of these would be based on the “still-in-progress” tweened position of the objects (which means the position will be slightly more offset), and when you play a tween when a tween is already playing, the previous tween will be canceled over the new one, which is why this happens.

I apologize if my explanation was not worded correctly, what I would do to fix this issue would be to make the target position based on the number of frames/buttons in mainframe instead of making it dependent on the latest object added to the frame:

local offsetPerObject = 40 -- You can change it if this is not correct

local gui = script.Parent
local tweenService = game:GetService("TweenService")
local mainFrame = gui:WaitForChild("Gui")
local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Back, Enum.EasingDirection.Out, 0, false, 0) --Time is 1 in Example 1 and .75 in Example 2
local items = {}

mainFrame.ChildAdded:Connect(function(Child)
	items[#items + 1] = child
	for Index, Value in ipairs(items) do -- if nothing loops then change 'ipairs' back to 'pairs'.
		local targetPos =  (offsetPerObject * (Index - 1)) - (offsetPerObject * (#Items - 1)) * 0.5 -- Basically, based on the object order, it will stay further away from the first object, then after that, to keep everything centered, it subtracts half of the total position from targetPos.
		local tween = tweenService:Create(Value, tweenInfo, {Position = UDim2.new(0, targetPos, 0, 0)})
		tween:Play() -- I would just play the tween here to keep it simple unless you have another reason as to why you're adding them to a table.
	end
end)

Please tell me if you find any errors so I can help you. :slightly_smiling_face:

1 Like

Thank you so much; this worked perfectly!

1 Like

Well, take @Conejin_Alt’s script and modify it to do the inverse effect

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.