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.