Your module script could look something like this:
local PulseEffect = {}
local TweenService = game:GetService'TweenService'
local RunService = game:GetService'RunService'
local PulsingObjects = {}
local Info = TweenInfo.new(0.35, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local function Pulse(GuiObject)
local Clone = GuiObject:Clone()
Clone.Parent = GuiObject.Parent
local Tween = TweenService:Create(Clone, Info, {
TextTransparency = 1,
Size = UDim2.new(GuiObject.Size.X.Scale * 1.5, 0, GuiObject.Size.Y.Scale * 1.5, 0)
})
Tween:Play()
-- delete the clone after tween is done
Tween.Completed:Connect(function(PlaybackState)
Clone:Destroy()
end)
end
function PulseEffect.StartPulse(GuiObject)
table.insert(PulsingObjects, GuiObject)
end
function PulseEffect.StopPulse(GuiObject)
local Index = table.find(PulsingObjects, GuiObject)
if Index then
table.remove(PulsingObjects, Index)
end
end
-- Runs every 1.5 seconds
local LastPulse = 0
RunService.RenderStepped:Connect(function()
if os.clock() - LastPulse < 1.5 then return end
LastPulse = os.clock()
for i, GuiObject in ipairs(PulsingObjects) do
Pulse(GuiObject)
end
end)
return PulseEffect
In your main script, just require the module and do module.StartPulse(textLabel)
. You’re probably gonna have to mess around with this line
Size = UDim2.new(GuiObject.Size.X.Scale * 1.5, 0, GuiObject.Size.Y.Scale * 1.5, 0)
because text scaling and wrapping in roblox is annoying so it might move wrapped text around, etc. Just try tweaking the new scale multiplier to whatever fits.
If you want the pulse to have a shorter delay before running again, make the 1.5
in the RenderStepped
connection smaller, and if you want the tween to play faster change the 0.35
in the TweenInfo
.
Here is my gui setup for the example:

LocalScript:
local TextLabel = script.Parent.TextLabel
local Pulse = require(script.PulseEffect)
local StartPulse, StopPulse = Pulse.StartPulse, Pulse.StopPulse
-- get the 3 textlabels and apply pulse to them
for i, v in pairs(script.Parent:GetChildren()) do
if v:IsA'TextLabel' then
StartPulse(v)
end
end
The text resizing looks choppy because that’s the way roblox handles TextScaled
. You could probably use TextContainer.AutomaticSize
or something but I’ve never messed with that.
You could also maybe try turning off TextScaled
and just tween the TextSize
.