How to avoid a Tween to be interrupted by another Tween?

In my script, when the user presses the key “R”, I rotate a part.
I use TweenService to change the Orientation for that, with a time of 0.15 seconds.
And UserInputService.InputBegan to detect the keyboard.
It’s a nice rotation effect.

The problem is if the user presses “R” quickly (with a shorter interval of 0.15 seconds), UserInputService.InputBegan will run a new TweenService BEFORE the previous tween has been completed.
As a result, the rotation is interrupted.
Apparently a second tween cancels the first tween, if it is executed before the completion of the first, right?

I’d like to know if is there an option to avoid this tween cancelation and put them in a kind of “queue”?

UserInputService.InputBegan:Connect(function(input,GPE)
        if input.KeyCode == Enum.KeyCode.R then 
            TweenService:Create(
                ObjSobMouse, 
                TweenInfo.new(tempoTween, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), 
                {Orientation = Vector3.new(ObjSobMouse.Orientation.X, ObjSobMouse.Orientation.Y + 90, ObjSobMouse.Orientation.Z)} 
            ):Play()
        end
    end
end)
1 Like

Have a global tween that you reuse every rotation.

I believe tweens will automatically be destroyed upon completion, so you can do something like

if tweenRotation then
     tweenRotation.Completed:Wait() -- wait for previous tween to end
end
tweenRotation = -- your tween
tweenRotation:Play()
1 Like

If you just wanted to stop someone from spamming it and making it look weird, and for the player to wait for the one to finish before pressing it again, you could use a “debounce”. This would prevent your Tween from :Play()ing again before it finishes.

debounce = true
UserInputService.InputBegan:Connect(function(input,GPE)
        if input.KeyCode == Enum.KeyCode.R and debounce then  
            debounce = false
            local Tween = TweenService:Create(
                ObjSobMouse, 
                TweenInfo.new(tempoTween, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), 
                {Orientation = Vector3.new(ObjSobMouse.Orientation.X, ObjSobMouse.Orientation.Y + 90, ObjSobMouse.Orientation.Z)} 
            ):Play()
           Tween.Completed:Wait()
           debounce = true

        end
    end
end) 

Making a actual queue system would be a bit more complicated. You could create a NumInQueue variable that stores the number of Tweens pending, and then :Play() them one by one whenever one finishes. You would lower the NumInQueue by 1 every time a Tween is completed, until NumInQueue == 0.

Hope this helps!

3 Likes