Loading dot animations are "synchronized"

I’m trying to create a loading animation of three dots. The problem is that the dots tween are “syncronized” , even though all three tween animations occur with a clear 0.1 second delay.

Code:

local TweenService = game:GetService(`TweenService`)
local Replicated = game:GetService(`ReplicatedStorage`)
local ContentProvider = game:GetService(`ContentProvider`)

local LocalPlr = game.Players.LocalPlayer

local LoadingUI = script.LoadingUI
local CurrentLoadingText = LoadingUI.ObjectsFrame.CurrentLoading

local DotInfo = TweenInfo.new(.6, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true)

local LoadingThread:thread?

local function LoadInstance(WhatLoad:Instance, Name:string)
	game:GetService(`SoundService`).UI.NextLoading:Play()
	CurrentLoadingText.Text = Name

	ContentProvider:PreloadAsync(WhatLoad:GetDescendants())
end


LoadingUI.Parent = LocalPlr.PlayerGui

CurrentLoadingText.Text = `Ждём когда Roblox полностью загрузит игру`

repeat task.wait(5) until game:IsLoaded()

LoadingThread = coroutine.create(function()
	LoadInstance(Replicated.Skins, `Загрузка скинов`)
	LoadInstance(LocalPlr.PlayerGui, `Загрузка UI`)
	LoadInstance(workspace.Lobby, `Загрузка Лобби`)
end)

coroutine.resume(LoadingThread)

task.defer(function()
	TweenService:Create(LoadingUI.ObjectsFrame.Dots.Left, DotInfo, {Position = UDim2.fromScale(0,1)}):Play()
	task.wait(.1)
	TweenService:Create(LoadingUI.ObjectsFrame.Dots.Center, DotInfo, {Position = UDim2.fromScale(.5,1)}):Play()
	task.wait(.1)
	TweenService:Create(LoadingUI.ObjectsFrame.Dots.Right, DotInfo, {Position = UDim2.fromScale(1,1)}):Play()
end)

Team Test:

I don’t understand what I’m doing wrong. Any help would be appreciated.

not too sure about this to be honest, u dont need to use task.defer for this since youre already loading everything inside of its own thread, try removing the thraed for the tweens & it may also just be an issue with how roblox handles tweeninfos but im not entirely sure

Instead of wrapping it in a task.defer and using task.wait before playing each one, play them all at once and control the delay using the last field in the TweenInfo constructor (add a delay time of .1 for the second one and .2 for the third one).

1 Like

This doesn’t work the way I wanted. Tween waits for the specified number of seconds after each playback, instead of the delay occurring only at the beginning.

Unfortunately, this doesn’t help.

What you probably will want instead then is to abandon trying to achieve this with a single infinitely looping Tween. Something like this sounds like it’d give you the desired effect:

task.spawn(function()
    while true do
        TweenService:Create(LoadingUI.ObjectsFrame.Dots.Left, TweenInfo.new(.6, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, true), {Position = UDim2.fromScale(0,1)}):Play()
	    TweenService:Create(LoadingUI.ObjectsFrame.Dots.Center, TweenInfo.new(.6, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, true, .1), {Position = UDim2.fromScale(.5,1)}):Play()
	    TweenService:Create(LoadingUI.ObjectsFrame.Dots.Right, TweenInfo.new(.6, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, true, .2), {Position = UDim2.fromScale(1,1)}):Play()
        task.wait(1)
    end
end)

It’s bad practice to create a tween every time you need play it, it can lead to a memory leak very quickly. I’d recommend creating them beforehand. What you did with the TweenInfo.DelayTime is good, though; you just need to set RepeatCount to -1 to loop infinitely.

Example:

local dots = LoadingUI.ObjectsFrame.Dots

local delay = 1 -- delay between each loop
local time = 0.6
local style = Enum.EasingStyle.Sine
local direction = Enum.EasingDirection.InOut
local delayTime = 0.1

local leftTween = TweenService:Create(
    dots.Left,
    TweenInfo.new(time, style, direction, -1, true, 0 + delay),
    {Position = UDim2.fromScale(0, 1)}
)
local centerTween = TweenService:Create(
    dots.Center,
    TweenInfo.new(time, style, direction, -1, true, time + delay),
    {Position = UDim2.fromScale(0.5, 1)}
)
local rightTween = TweenService:Create(
    dots.Right,
    TweenInfo.new(time, style, direction, -1, true, time*2 + delay),
    {Position = UDim2.fromScale(1, 1)}
)

leftTween:Play()
centerTween:Play()
rightTween:Play()

Then stop them whenever it stops loading.

Or, even better, assign a delay to each dot and use RunService and math.sin() to set their position smoothly every frame (which is way more customizable than using Tweens).

@EenatAlt

1 Like