I’m wondering what the best practice is for TweenService in this case.
Is it worth caching and reusing tweens for the same object every time it’s shown/hidden, like I’m doing below? Or is it generally better to create a new tween whenever the UI is opened?
Right now I’m creating the tweens once, storing them in a cache, and reusing them on every Show() / Hide() call. This avoids creating new tween instances repeatedly, but I’m not sure if that’s actually the recommended approach or if there are any downsides I’m overlooking.
Here’s my current implementation:
local UIAnimator = {}
local TweenService = game:GetService("TweenService")
local Camera = workspace.CurrentCamera
-- << CONFIG >> --
local DEFAULT_FOV = 70
local ZOOM_FOV = 55
local tweenInfos = {
PopupShow = TweenInfo.new(
0.3,
Enum.EasingStyle.Back,
Enum.EasingDirection.Out
),
PopupHide = TweenInfo.new(
0.18,
Enum.EasingStyle.Quad,
Enum.EasingDirection.In
),
ZoomIn = TweenInfo.new(
0.3,
Enum.EasingStyle.Quad,
Enum.EasingDirection.Out
),
ZoomOut = TweenInfo.new(
0.18,
Enum.EasingStyle.Quad,
Enum.EasingDirection.In
),
}
local cameraTweens = {
zoomIn = TweenService:Create(
Camera,
tweenInfos.ZoomIn,
{ FieldOfView = ZOOM_FOV }
),
zoomOut = TweenService:Create(
Camera,
tweenInfos.ZoomOut,
{ FieldOfView = DEFAULT_FOV }
)
}
local cache = {}
local function getData(guiObject)
local data = cache[guiObject]
if data then
return data
end
local basePosition = guiObject.Position
local hiddenPosition = basePosition + UDim2.fromScale(0, 1)
data = {
basePos = basePosition,
hiddenPos = hiddenPosition,
}
data.TweenShow = TweenService:Create(guiObject, tweenInfos.PopupShow, {
Position = basePosition,
})
data.TweenHide = TweenService:Create(guiObject, tweenInfos.PopupHide, {
Position = hiddenPosition
})
data.TweenHide.Completed:Connect(function(playbackState)
if playbackState ~= Enum.PlaybackState.Completed then
return
end
guiObject.Visible = false
guiObject.Position = data.basePos
end)
cache[guiObject] = data
return data
end
function UIAnimator.Show(guiObject: GuiObject)
if not guiObject:IsA("GuiObject") then return end
local data = getData(guiObject)
guiObject.Position = data.hiddenPos
guiObject.Visible = true
data.TweenShow:Play()
cameraTweens.zoomIn:Play()
end
function UIAnimator.Hide(guiObject: GuiObject)
if not guiObject:IsA("GuiObject") then return end
local data = getData(guiObject)
data.TweenHide:Play()
cameraTweens.zoomOut:Play()
end
return UIAnimator
Would you cache tweens like this, or would you create them on demand instead? I’m mainly interested in what’s considered best practice in terms of performance, memory usage, and maintainability.