Back to all posts

Advanced TweenService Techniques: Chaining, Loops, and UI Animations in Roblox

If you've read our TweenService basics guide, you already know how to animate a single part smoothly. The next challenge is knowing how to combine animations into real game feel — sequences that fire one after another, effects that loop forever, and UI transitions that make your game look finished.

This guide covers the patterns that separate a basic Roblox game from a polished one.


Chaining Tweens: Running Animations in Sequence

Many game effects need to fire in order: a chest jumps up, falls back down, then spins away. The Completed event is what makes this possible — it fires when a Tween finishes playing.

local TweenService = game:GetService("TweenService")
local part = workspace:WaitForChild("Chest")

local bounceInfo = TweenInfo.new(0.5, Enum.EasingStyle.Back, Enum.EasingDirection.Out)

-- Step 1: Jump up
local jumpUp = TweenService:Create(part, bounceInfo, {
    Position = part.Position + Vector3.new(0, 3, 0)
})

-- Step 2: Fall back down
local fallDown = TweenService:Create(part, bounceInfo, {
    Position = part.Position
})

-- Step 3: Spin out and fade
local spinInfo = TweenInfo.new(0.8, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
local spinOut = TweenService:Create(part, spinInfo, {
    Transparency = 1,
    Size         = part.Size * 1.5
})

-- Chain them
jumpUp:Play()
jumpUp.Completed:Connect(function()
    fallDown:Play()
    fallDown.Completed:Connect(function()
        spinOut:Play()
    end)
end)

Each Completed callback waits for the previous animation to fully finish before starting the next one — giving you frame-perfect control over your sequences.


Looping Tweens: Always-Moving Environmental Effects

Ambient effects like floating items, swaying lanterns, or pulsing lights need to run indefinitely. Set RepeatCount to -1 for an infinite loop, and combine it with Reverses = true so the animation automatically returns to its starting state.

local TweenService = game:GetService("TweenService")
local lantern = workspace:WaitForChild("Lantern")

local floatInfo = TweenInfo.new(
    2,                               -- 2 seconds per cycle
    Enum.EasingStyle.Sine,           -- smooth, wave-like motion
    Enum.EasingDirection.InOut,
    -1,                              -- loop forever
    true,                            -- reverse back to start
    0
)

local floatTween = TweenService:Create(lantern, floatInfo, {
    Position = lantern.Position + Vector3.new(0, 1.5, 0)
})

floatTween:Play()

Sine + InOut produces a breathing rhythm — slow at each end, smooth in the middle — that works especially well for atmospheric, ambient motion.


Animating Multiple Properties at Once

A single TweenService:Create() call can animate as many properties as you want simultaneously. Position, size, color, and transparency can all change together in one Tween.

local TweenService = game:GetService("TweenService")
local gem = workspace:WaitForChild("Gem")

local spawnInfo = TweenInfo.new(1.2, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out)

local spawnTween = TweenService:Create(gem, spawnInfo, {
    Position     = gem.Position + Vector3.new(0, 5, 0),
    Size         = gem.Size * 1.8,
    Color        = Color3.fromRGB(255, 220, 0),
    Transparency = 0
})

-- Start hidden, then reveal with the Tween
gem.Transparency = 1
spawnTween:Play()

Important: Two Tweens competing over the same property on the same object will produce unpredictable results. Always ensure only one Tween is active per property per object at a time.


UI Animations: Fade-In and Slide-In Effects

TweenService works on UI objects — Frame, TextLabel, ImageLabel — using exactly the same API as parts. Tweening BackgroundTransparency and Position on UI elements is how polished result screens, notifications, and menus are built.

Fade-In

local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local frame = Players.LocalPlayer.PlayerGui
    :WaitForChild("ResultScreen")
    :WaitForChild("Frame")

-- Start fully transparent
frame.BackgroundTransparency = 1

local fadeIn = TweenService:Create(
    frame,
    TweenInfo.new(0.6, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
    { BackgroundTransparency = 0 }
)

fadeIn:Play()

Slide-In

To slide UI in from off-screen, set an out-of-bounds Position first, then Tween it into place using UDim2.

-- Start off the right edge of the screen
frame.Position = UDim2.new(1.2, 0, 0.3, 0)

local slideIn = TweenService:Create(
    frame,
    TweenInfo.new(0.5, Enum.EasingStyle.Back, Enum.EasingDirection.Out),
    { Position = UDim2.new(0.5, 0, 0.3, 0) }
)

slideIn:Play()

Back + Out adds a slight overshoot that snaps the panel into place — giving UI a crisp, confident feel rather than just sliding to a stop.


A Note from the Author

Once I understood the basics of TweenService, the next challenge was figuring out how to chain animations and apply them to UI elements. Single tweens were easy — but building sequences and fade effects took a lot of trial and error. Knowing these patterns makes a real difference in how polished a game feels.

Before committing a style to code, I always test it in the Roblox Tween Generator first — it previews EasingStyle, Direction, and Time in real time, and copies the full TweenInfo code with one click.


Summary

Technique Best Used For
Chaining with Completed Item pickups, stage clear sequences
Infinite loop (RepeatCount = -1) Floating, swaying environmental effects
Multiple properties in one Tween Spawn / despawn effects
UI fade-in Result screens, notifications
UI slide-in Menus, panels, pop-ups

TweenService uses the same API whether you're targeting a Part in the workspace or a Frame in a ScreenGui. Once you learn the patterns, they apply everywhere — and that consistency is what makes TweenService one of the most powerful tools in Roblox development.