Perpetually tween manyparts | Problem with loop inside of loop

Another embarrassing question showing that I’m missing some of the basic scripting fundamentals:

I have a folder with many bubbles that I would like to have tween up and down slowly. They are all in a folder ‘CollectBubbles’.

My current script won’t work because my loop inside of a loop means that only one of the bubbles in the folder tweens because the interior while loop prevents the pairs loop from moving onto the next bubble in CollectBubble.

for i, v in pairs(CollectBubbles:GetChildren()) do 
	while true do	
		local goal = {}
		goal.Position = v.Position + Vector3.new(0,.5,0)
		local tween = TweenService:Create(v, tweenInfo, goal)
		tween:Play()
		wait (2)
		local goal = {}
		goal.Position = v.Position + Vector3.new(0,-.5,0)
		local tween = TweenService:Create(v, tweenInfo, goal)
		tween:Play()
		wait(2)
	end
end

Appreciate a nudge in the right direction. Thanks folks.

1 Like

add a task.spawn() or make it a coroutine.

for i, v in pairs(CollectBubbles:GetChildren()) do 
	task.spawn(function()
		while true do
			local goal = {}
			goal.Position = v.Position + Vector3.new(0,.5,0)
			local tween = TweenService:Create(v, tweenInfo, goal)
			tween:Play()
			wait (2)
			local goal = {}
			goal.Position = v.Position + Vector3.new(0,-.5,0)
			local tween = TweenService:Create(v, tweenInfo, goal)
			tween:Play()
			wait(2)
		end
	end)
end

or

for i, v in pairs(CollectBubbles:GetChildren()) do 
	coroutine.resume(coroutine.create(function()
		while true do
			local goal = {}
			goal.Position = v.Position + Vector3.new(0,.5,0)
			local tween = TweenService:Create(v, tweenInfo, goal)
			tween:Play()
			wait (2)
			local goal = {}
			goal.Position = v.Position + Vector3.new(0,-.5,0)
			local tween = TweenService:Create(v, tweenInfo, goal)
			tween:Play()
			wait(2)
		end
	end))
end

as an answer with words, the problem is that the while true do was continuously delaying going to the next ball and I simply added something that will make it not delay at all.

2 Likes

While you could use task.defer (example in dropdown below), there’s a much better alternative with TweenInfo.

task.defer method (don't use for this)
for i, v in pairs(CollectBubbles:GetChildren()) do 
	task.defer(function()
		while true do	
			local goal = {}
			goal.Position = v.Position + Vector3.new(0,.5,0)
			local tween = TweenService:Create(v, tweenInfo, goal)
			tween:Play()
			wait (2)
			local goal = {}
			goal.Position = v.Position + Vector3.new(0,-.5,0)
			local tween = TweenService:Create(v, tweenInfo, goal)
			tween:Play()
			wait(2)
		end
	end)
end

Now, onto the best solution for this:
TweenInfo has 2 neat little properties we can use for this. The RepeatCount and Reverses. Using them, we don’t even have to use loops at all!

(When specifying RepeatCount, using -1 makes it go forever.)
(The true is the Reverses property)

Example TweenInfo:

TweenInfo.new(2,Enum.EasingStyle.Exponential,Enum.EasingDirection.InOut,-1,true)

Using this new TweenInfo, we can now make a non-yielding, no loop repeating tween:

local NEWTweeninfo = TweenInfo.new(2,Enum.EasingStyle.Exponential,Enum.EasingDirection.InOut,-1,true)

for i, v in pairs(CollectBubbles:GetChildren()) do 
	local goal = {}
	goal.Position = v.Position + Vector3.new(0,.5,0)
	local tween = TweenService:Create(v, NEWTweeninfo, goal)
	tween:Play()
end
2 Likes

I’m always amazed at the number of folks here willing to help. @Kaid3n22 & @Inconcludable Thank you so much for the education. Both of the responses will help me in the future.

The repeat and reversing aspects of tweening worked perfectly in my case.

1 Like