Odd tween .Completed behavior

Hello everyone,

I’m trying to tween the transparency of a model’s descendants using this function:

function fadeOut(instance, ttime)
	local info = TweenInfo.new(
			ttime or 3,
			Enum.EasingStyle.Linear,
			Enum.EasingDirection.InOut
		)
	for _,v in ipairs(instance:GetDescendants()) do
		if not v:IsA("BasePart") then continue end
		local t = TweenService:Create(v, info, {Transparency = 1})
		t:Play()
		t.Completed:Connect(anotherFunction)
	end
end

This works fine and all the parts get properly tweened, but the Completed event for some reason returns Cancelled on about half the tweens almost immediately(yet the parts continue being tweened) and Completed on the other half. Does anyone know what causes this behavior?

It seems like you haven’t typed the function out properly, change it to this:

This is not the problem. The problem is half the tweens are “completed” as cancelled, yet continue playing and the other half complete as intended.

Besides, if I defined a function like this

function anotherFunction(...)
    print(...)
end

I can connect it by doing

thing.Event:Connect(anotherFunction)

Yeah but how could you connect a completed event to a function, what does anotherFunction do?

Why would this matter? In my case it disables an emitter, but it could also just print the state .Completed returns. I want to know why half of my tweens fire the .Completed event early yet continue playing.

Maybe try changing continue to return end, I haven’t seen or have coded a script with the word continue inside it

This would end the loop and prevent anything from being tweened. continue simply skips the current iteration.

You only want to tween Baseparts, right?

Maybe try ‘uncomplicating’ this and write a simple if statement

for ....
  if v:IsA("BasePart") then
        local t = TweenService:Create(v, info, {Transparency = 1})
		t:Play()
		t.Completed:Connect(anotherFunction)
  end
end

Im helping debug and not necessarily fixing the problem. This is usually the first step to debug something, writing the most simplified version of your code.

If so then, you should do this:

Did that, didn’t help with the problem. Personally I prefer the continue.

I think the reason why it has only tweened half of the parts is because you used ipairs instead of pairs, try changing them and see what happens.

When using ipairs its only going to run things that won’t throw an error, it won’t pass it, it will just run some of the stuff and stop where there is an error.

Never mind this, I was being an idiot and calling the function multiple times. ipairs wouldn’t matter as parts are never nil in :GetDescendants()

2 Likes

Alright, then the simplest solution I can come up with is, run your disabling function in another for loop simultaneously in another thread, and maybe put a wait(ttime) in the thread to match the disappearing info.Time.

Anyways, seems you’ve found a solution.

The use of ipairs is not the problem here. If anything OP should be using it. I know this is not relevant but

You have a memory leak. You create a tween, create a connection and the connection keeps the tween alive. Slowly this builds up.

Disconnect the connection when you are done with it

local t = TweenService:Create(v, info, {Transparency = 1})
t:Play()
local connection = t.Completed:Connect(anotherFunction)
-- later on
connection:Disconnect()

Lol I was about to say it sounded like u had tween conflicts, but I had no idea why. Glad ya got it fixed.