I’ve been trying to figure out a way to slow down tweens smoothly while a tween is playing but that wasn’t a feature (that I know of) and I was wondering why there wasn’t a setting for like timescale or speed on tweens that can be smoothly changed like how particles have?
I’ve tried looking around on the devforum but only found workarounds where you stop a tween while its playing and play another one with a different speed but it doesn’t work as smoothly as I’d like
Some use cases I could think of could be for some time related abilities in a game or hit-stops where VFX or other stuff that’s tweened gets frozen or slowed drastically, unless I’m missing something in the engine that allows me to do this?
Well technically there already is a thing for this.
When creating a tween, one of the options for tween info is the EasingStyle, of which depending on which one you pick the tween will act in different ways.
linear will tween at a constant speed, Quint stalls for a bit before speeding up real fast, and I cannot explain the others at all
Tweens aren’t objects, so they aren’t really designed to be manageable in real time. In your case, you’d have to keep track of all the active tweens to adjust their timescales. In a sense, that’s not much different than the work around of keeping track of them, and overriding them with a new tween that accounts for the new scale. The only tricky bit is having consistent easing styles. There might not be a good way to do this without custom easing or only using linear for everything.
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local TweenController = {}
TweenController.__index = TweenController
function TweenController.new(duration, easingStyle, easingDirection)
local self = setmetatable({}, TweenController)
self.duration = duration or 1
self.easingStyle = easingStyle or Enum.EasingStyle.Quad
self.easingDirection = easingDirection or Enum.EasingDirection.InOut
self.progress = 0
self.speed = 1
self.isPlaying = false
self.loop = false
self.connection = nil
self.onUpdate = nil
return self
end
function TweenController:play()
if self.connection then return end
self.isPlaying = true
self.connection = RunService.Heartbeat:Connect(function(dt)
if self.isPlaying then
self.progress = self.progress + (dt * self.speed / self.duration)
self.progress = math.clamp(self.progress, 0, 1)
local alpha = TweenService:GetValue(self.progress, self.easingStyle, self.easingDirection)
if self.onUpdate then
self.onUpdate(alpha, self.progress)
end
if self.progress >= 1 then
if self.loop then
self.progress = 0
else
self:pause()
end
end
end
end)
end
function TweenController:pause()
self.isPlaying = false
end
function TweenController:resume()
self.isPlaying = true
end
function TweenController:stop()
self.isPlaying = false
self.progress = 0
end
function TweenController:setSpeed(speed)
self.speed = speed
end
function TweenController:setProgress(progress)
self.progress = math.clamp(progress, 0, 1)
end
function TweenController:destroy()
if self.connection then
self.connection:Disconnect()
self.connection = nil
end
end
return TweenController
Sample use-case (AI):
local TweenController = require(script.Parent.TweenController)
local part = Instance.new("Part")
part.Size = Vector3.new(4, 4, 4)
part.Position = Vector3.new(0, 10, 0)
part.Anchored = true
part.Parent = workspace
local startPos = Vector3.new(0, 10, 0)
local endPos = Vector3.new(50, 10, 0)
local startColor = Color3.fromRGB(0, 100, 255)
local endColor = Color3.fromRGB(255, 100, 0)
local tween = TweenController.new(5, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)
tween.loop = true
tween.onUpdate = function(alpha, progress)
part.Position = startPos:Lerp(endPos, alpha)
part.Color = startColor:Lerp(endColor, alpha)
end
tween:play()
task.wait(2)
print("Speeding up to 2x")
tween:setSpeed(2)
task.wait(2)
print("Slowing down to 0.5x")
tween:setSpeed(0.5)
task.wait(3)
print("Pausing")
tween:pause()
task.wait(2)
print("Resuming")
tween:resume()
task.wait(3)
print("Back to normal speed")
tween:setSpeed(1)
OH NO THATS NOT WHAT I MEANT
so i wasnt asking for easing styles but instead the ability to change it’s speed like how you would for particles, so it could still be, for example, Exponential Out, but i want the ability to slow it down WHILE it’s playing like making it 0.2x speed but still keeping every other property the same
I know there are workarounds to have this work but I was just wondering if it could be a feature roblox actually implemented as like a setting for tweens
For these types of systems it’s usually better to code your own “time stop” system. Instead of using tweens, you can build your own “tween-like” class that supports slowdowns. You also have the advantage of control over all playing tweens and slow them down all at once.
Personally, I don’t use tweens unless it’s some repetitive or predictable adjustment. For things like player abilities or dynamic status effects, I tend to just code that in without tweens. It’s easier than you think, and shouldn’t be a big hassle.
Real, many of the replies I’ve seen on here are workarounds but why must we have a workaround when it could be a feature? we already have like :AdjustSpeed for animationtracks and timescale for particles, same thing for tweens would be awesome