Now is 3 am, and i wan’t to make something funny, i made a slingshot, and more.
Back to the problem, i made a module that animate the text, like, here’s the function from my module - animationText:TypeText("There's <RAGE>animation</RAGE>! And it's Very <MAGIC>magical</MAGIC>!")
and i have an error - Connection is not a supported attribute type, i wan’t to fix that to make my module better, but this error don’t make a bug, just to make a completed my first working module, here’s the module -
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local TextAnimation = {}
TextAnimation.__index = TextAnimation
local LETTER_WIDTH = 15
local LETTER_HEIGHT = 50
local TEXT_SIZE = 20
local FONT = Font.new("rbxasset://fonts/families/Montserrat.json", Enum.FontWeight.ExtraBold, Enum.FontStyle.Normal)
function TextAnimation.new(options)
local self = setmetatable({}, TextAnimation)
self.adornee = options.adornee
self.Pack = script:FindFirstChild("Pack")
if not self.Pack then
warn('Folder "Pack", is not valid member of this model!!!')
end
return self
end
local function parseText(text)
local segments = {}
local currentIndex = 1
while true do
local rageStart, rageEnd = string.find(text, "<RAGE>", currentIndex)
local magicStart, magicEnd = string.find(text, "<MAGIC>", currentIndex)
local startIdx, endIdx, tagType
if rageStart and (not magicStart or rageStart < magicStart) then
startIdx, endIdx, tagType = rageStart, rageEnd, "RAGE"
elseif magicStart then
startIdx, endIdx, tagType = magicStart, magicEnd, "MAGIC"
end
if startIdx then
if startIdx > currentIndex then
table.insert(segments, {text = string.sub(text, currentIndex, startIdx - 1), effect = "Normal"})
end
local closeTag = "</" .. tagType .. ">"
local closeStart, closeEnd = string.find(text, closeTag, endIdx + 1)
if closeStart then
local tagText = string.sub(text, endIdx + 1, closeStart - 1)
table.insert(segments, {text = tagText, effect = tagType})
currentIndex = closeEnd + 1
else
local tagText = string.sub(text, endIdx + 1)
table.insert(segments, {text = tagText, effect = tagType})
break
end
else
local remaining = string.sub(text, currentIndex)
if remaining ~= "" then
table.insert(segments, {text = remaining, effect = "Normal"})
end
break
end
end
return segments
end
local function applyEffects(effectTemplate, parentGui)
if effectTemplate then
for _, effect in ipairs(effectTemplate:GetChildren()) do
local clone = effect:Clone()
clone.Parent = parentGui
end
end
end
local function vanishLetter(letterGui)
local vanishDelay = 1.5
local vanishDuration = 0.3
delay(vanishDelay, function()
local tweenInfo = TweenInfo.new(vanishDuration, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
local tweenLetter = TweenService:Create(letterGui, tweenInfo, {TextTransparency = 1})
tweenLetter:Play()
tweenLetter.Completed:Connect(function()
letterGui:Destroy()
end)
for _, child in ipairs(letterGui:GetDescendants()) do
if child:IsA("UIStroke") then
local tweenChild = TweenService:Create(child, tweenInfo, {Transparency = 1})
tweenChild:Play()
end
end
end)
end
local function animateNormalLetter(letterGui, targetPos)
local tweenInfo = TweenInfo.new(0.15, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
local properties = {Position = targetPos, TextTransparency = 0}
local tween = TweenService:Create(letterGui, tweenInfo, properties)
tween:Play()
tween.Completed:Connect(function()
vanishLetter(letterGui)
end)
end
local function animateRageLetter(letterGui, startPos, targetPos)
local totalDuration = 0.45
local elapsed = 0
local amplitude = 10
local connection
connection = RunService.Heartbeat:Connect(function(delta)
elapsed = elapsed + delta
local progress = math.min(elapsed / totalDuration, 1)
local newX = startPos.X.Offset + (targetPos.X.Offset - startPos.X.Offset) * progress
local newY = startPos.Y.Offset + (targetPos.Y.Offset - startPos.Y.Offset) * progress
local currentAmplitude = amplitude * (1 - progress)
local offsetX = math.random(-currentAmplitude, currentAmplitude)
local offsetY = math.random(-currentAmplitude, currentAmplitude)
letterGui.Position = UDim2.new(0, newX + offsetX, 0, newY + offsetY)
letterGui.TextTransparency = 1 - progress
if progress >= 1 then
connection:Disconnect()
letterGui.Position = targetPos
letterGui.TextTransparency = 0
vanishLetter(letterGui)
end
end)
end
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local function animateMagicLetter(letterGui, startPos, targetPos)
local tweenInfo = TweenInfo.new(0.15, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
local tween = TweenService:Create(letterGui, tweenInfo, {Position = targetPos, TextTransparency = 0})
tween:Play()
tween.Completed:Connect(function()
local basePos = targetPos
local speed = 6
local radius = 3
local startTime = tick()
local connection
connection = RunService.Heartbeat:Connect(function()
local t = tick() - startTime
local offsetX = math.cos(t * speed) * radius
local offsetY = math.sin(t * speed) * radius
letterGui.Position = UDim2.new(0, basePos.X.Offset + offsetX, 0, basePos.Y.Offset + offsetY)
end)
letterGui:SetAttribute("MagicConn", connection)
end)
vanishLetter(letterGui)
end
function TextAnimation:TypeText(fullText)
self.adornee:ClearAllChildren()
local segments = parseText(fullText)
local letterDelay = 0.05
local currentX = 0
local yPosition = 0
local globalIndex = 0
for _, segment in ipairs(segments) do
local effectFolderName = segment.effect
local effectTemplate = self.Pack and self.Pack:FindFirstChild(effectFolderName)
if not effectTemplate then
warn("The effect " .. effectFolderName .. " cannot find in the Pack!")
end
for i = 1, #segment.text do
globalIndex = globalIndex + 1
local char = string.sub(segment.text, i, i)
if segment.effect == "RAGE" then
char = string.upper(char)
end
local letterGui = Instance.new("TextLabel")
letterGui.Size = UDim2.new(0, LETTER_WIDTH, 0, LETTER_HEIGHT)
letterGui.TextColor3 = Color3.fromRGB(255, 255, 255)
letterGui.FontFace = FONT
letterGui.BackgroundTransparency = 1
letterGui.TextSize = TEXT_SIZE
letterGui.Text = char
letterGui.TextTransparency = 1
letterGui.Parent = self.adornee
applyEffects(effectTemplate, letterGui)
local startPos = UDim2.new(0, currentX, 0, yPosition - 16)
letterGui.Position = startPos
local targetPos = UDim2.new(0, currentX, 0, yPosition)
task.spawn(function()
if segment.effect == "RAGE" then
animateRageLetter(letterGui, startPos, targetPos)
elseif segment.effect == "MAGIC" then
animateMagicLetter(letterGui, startPos, targetPos)
else
animateNormalLetter(letterGui, targetPos)
end
end)
currentX = currentX + LETTER_WIDTH
wait(letterDelay)
end
end
end
return TextAnimation
Anyway’s y’all can take it, i just wanna to try to make a some like unity text animations.