Can you use tweenservice.Completed twice?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    Can you use Tweenservice.Completed twice? and help with my code

  2. What is the issue? Include screenshots / videos if possible!
    The script stop after using the TweenService.Completed twice

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I try searching on devforum and i can’t find anything that’s related

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

local OpenDoorLeft = TweenService:Create(DoorPositionLeft, infoDoors, GoalsDoorLeft)
			local OpenDoorRight = TweenService:Create(DoorPositionRight, infoDoors, GoalsDoorRight)
			OpenDoorLeft:Play()
			OpenDoorRight:Play()
			OpenDoorLeft.Completed:Wait()
			OpenDoorRight.Completed:Wait()

The problem is that after the the first wait which is the OpenDoorLeft, the script did not continue on, it just stop there

this is my 2nd post so sorry if made mistake and i i’m just starting scripting so i do not know a lot yet

1 Like
OpenDoorLeft:Play()
OpenDoorRight:Play()
OpenDoorLeft.Completed:Wait()
OpenDoorRight.Completed:Wait()

You can use Tween.Completed as many times as you want (in fact it’s best practice to reuse tweens).

The problem from your code comes from the sequence.

Consider the following: You start the tweens at the same time, but what if the OpenDoorRight tween finishes before OpenDoorLeft does? This would mean that OpenDoorRight.Completed would have already fired but then the code does OpenDoorRight.Completed:Wait() … however OpenDoorRight.Completed has already gone off.

TL;DR: The code can wait for something that already happened, like waiting for a party to start that already ended.

The trick here is to check if the thing already ended. You don’t want to wait if the thing your waiting for already happened, so simply check if it happened before your start waiting:

OpenDoorLeft:Play()
OpenDoorRight:Play()
OpenDoorLeft.Completed:Wait()
-- If it's playing we need to wait for it to finish, otherwise we shouldn't
if OpenDoorRight.PlaybackState == Enum.PlaybackState.Playing then
    OpenDoorRight.Completed:Wait()
end
1 Like

Thank You for helping, my script now work perfectly fine :+1:

1 Like

Here’s another question, is there a way to check if both Tween have complete then the script continues with code rather than to check tween in sequence?

You can check if both tweens have completed with

if OpenDoorLeft.PlaybackState == Enum.PlaybackState.Playing and OpenDoorRight.PlaybackState == Enum.PlaybackState.Playing then

For the main part of the question, honestly the way you have it is probably the best. You could create a module that bundles events into a single event and wait for/connect to that, but internally it would be quite similar to what you have.

For example, here would be how you’d bundle them

-- This code bundles some events into a single event for when all the events have fired
-- (Note: make sure all the events can go off, it doesn't check if the tweens have finished so run it directly after starting the tweens)
local events = {OpenDoorLeft.Completed, OpenDoorRight.Completed}
local connections = {} 
local counter = #events -- events left to go off
local bindable = Instance.new("Bindable")
local waitForAllEvent = bindable.Event -- the singled "bundled" event
for _, event in ipairs(events) do
    local newConnection = event:Once(function() -- Creates a one time connection
        counter -= 1 -- tick down the counter of events left
        -- when the counter is 0 all the events have finishes
        if counter == 0 then
             bindable:Fire() -- trigger waitForAllEvent
             -- Clean up all the memory
             for _, connection in ipairs(connections) do
                 if connection then connection:Disconnect() end
             end
             connections = nil
             bindable:Destroy()
        end
    end)
end

-- example use:
waitForAllEvent:Connect(function()
    print("All the events have finished!")
end)

Definitely simpler to do it your way, though if you need it to be not in sequence that’s one way of doing it (though you can again use your code but in a new thread with task.spawn(func) which is also not in sequence with your main code).

1 Like

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