Yes, I do. I found this clip of someone fighting Toriel on the genocide route in Undertale.
Skip to 0:18 and you’ll see the kind of shaky text I’m talking about
Yes, I do. I found this clip of someone fighting Toriel on the genocide route in Undertale.
Skip to 0:18 and you’ll see the kind of shaky text I’m talking about
Like in second 0:28 of the video you sent?
Unfortunately, with the current limitations of TextLabels, you would have to give each character it’s own TextLabel, as mentioned in this preexisting post.
To create the shake effect, you could use Random( specifically Random:NextNumber() ), or math.random to offset the positions of each of the character TextLabels at a very fast speed.
Example of how this can be done:
local text = "scary undertale text"
TextFont = Enum.Font.Arcade
TextFontSize = 30
TextSize = game.TextService:GetTextSize(text, TextFontSize, TextFont, Vector2.new(10000,10000))
SpaceAmount = 1.3 -- 1 is the base, with no spacing
TextHolderFrame = Instance.new("Frame")
TextHolderFrame.Parent = script.Parent
TextHolderFrame.Position = UDim2.new(0.5,0,0.5,0)
TextHolderFrame.AnchorPoint = Vector2.new(0.5,0.5)
TextHolderFrame.BackgroundTransparency = 0
TextHolderFrame.BackgroundColor3 = Color3.fromRGB(255,255,255)
TextHolderFrame.BorderSizePixel = 0
TextHolderFrame.Name = "TextHolderFrame"
TextHolderFrame.Size = UDim2.new(0,TextSize.X * SpaceAmount,0,TextSize.Y)
for i = 1, #text do --loop through every character in the text string
CharacterLabel = Instance.new("TextLabel")
CharacterLabel.ZIndex = 2
CharacterLabel.BackgroundTransparency = 1
CharacterLabel.Font = TextFont
CharacterLabel.TextSize = TextFontSize
CharacterLabel.Size = UDim2.new(0,TextSize.X/#text, 0, TextSize.Y) --set the size, based on what GetTextSize returns
CharacterLabel.Position = UDim2.new(0, ((TextSize.X/#text) * i * SpaceAmount) - TextSize.X/#text/2, 0.5, 0) --calculate the position, by multiplying the size of one character, by the current character index we are on. The Scale values are just to position the text in this middle of the TextHolderFrame, which we will be parenting this label to shortly.
CharacterLabel.AnchorPoint = Vector2.new(0.5,0.5)
CharacterLabel.Text = string.sub(text, i, i) --grab just the character we need from the string
CharacterLabel.Parent = TextHolderFrame
end
--To make the individual TextLabels shake, you can do something like this:
CharacterLabels = script.Parent.TextHolderFrame:GetChildren()
Shake = true
while Shake == true do
for _, Label in pairs(CharacterLabels) do -- loop through the CharacterLabels one by one
Label.AnchorPoint = Vector2.new(math.random(4.5, 5.5)/10, math.random(4.5, 5.5)/10) --I'm using AnchorPoint instead of Position so we can maintain the original Position
end
wait(0.05)
end
I just gave this code a test, by putting it inside of a ScreenGui inside of StarterGui, and it results in this:
I still don’t really get what what you’re saying, but I’m assuming this is the correct answer.
What don’t you get I could explain the thing’s you don’t undertstand excessEnergy has given you all the information to make something like you reqested.
I made some updates to my original post, as well as provided some basic examples to further demonstrate what I mean.
Tell me if you still don’t understand something.
EDIT: I gave the code a test after a few modifications, and it works great @LazokkYT. I updated the post once more, but with run-able code.
Ohhhhh now I get what you were saying.
I get it now. Just needed like an example script.
Hello! Does this still work? I have tried the code example you provided, but it only generates a frame with the text. The text isn’t moving at all…
I just tried this code again myself, and it didn’t work for me either. There was a simple error, but I updated the code in the original post. It should work for you now.
Ohhh alright, thank you so much! I’ll try it out.
It worked, thanks! By the way, is there a way I could add some kind of typewriter effect to the shaking text? The reason I’m asking is because the Text frames in my game will use a typewriter effect to make it look, uh, better, like almost every other game does.
It might not be the simplest way, but I would do this by simply adding a wait() within the
for i = 1, #text do
for loop, and then using a table to store all of the characters that have been loaded, and shake those.
Something like this:
CharacterLabels = {}
spawn(function() --don't judge me for using spawn
Shake = true
while Shake == true do
for _, Label in pairs(CharacterLabels) do -- loop through the CharacterLabels one by one
Label.AnchorPoint = Vector2.new(math.random(4.5, 5.5)/10, math.random(4.5, 5.5)/10) --I'm using AnchorPoint instead of Position so we can maintain the original Position
end
wait(0.05)
end
end)
for i = 1, #text do --loop through every character in the text string
wait( "time to wait" )
CharacterLabel = Instance.new("TextLabel")
CharacterLabel.ZIndex = 2
CharacterLabel.BackgroundTransparency = 1
CharacterLabel.Font = TextFont
CharacterLabel.TextSize = TextFontSize
CharacterLabel.Size = UDim2.new(0,TextSize.X/#text, 0, TextSize.Y) --set the size, based on what GetTextSize returns
CharacterLabel.Position = UDim2.new(0, ((TextSize.X/#text) * i * SpaceAmount) - TextSize.X/#text/2, 0.5, 0) --calculate the position, by multiplying the size of one character, by the current character index we are on. The Scale values are just to position the text in this middle of the TextHolderFrame, which we will be parenting this label to shortly.
CharacterLabel.AnchorPoint = Vector2.new(0.5,0.5)
CharacterLabel.Text = string.sub(text, i, i) --grab just the character we need from the string
CharacterLabel.Parent = TextHolderFrame
CharacterLabels.insert(CharacterLabel)
end
I haven’t tested this, but its just an example of what I would try first.
Alright thanks, I’ll try it out!
I would not use math.random for this if i were you, i would use Random:NextNumber as it has more verity
i added tweens to this script since it wasnt feeling that good so here’s the new script:
local text = "damn bruh"
TextFont = Enum.Font.Arcade
TextFontSize = 30
TextSize = game.TextService:GetTextSize(text, TextFontSize, TextFont, Vector2.new(10000,10000))
SpaceAmount = 1.3 -- 1 is the base, with no spacing
TextHolderFrame = Instance.new("Frame")
TextHolderFrame.Parent = script.Parent
TextHolderFrame.Position = UDim2.new(0.5,0,0.5,0)
TextHolderFrame.AnchorPoint = Vector2.new(0.5,0.5)
TextHolderFrame.BackgroundTransparency = 0
TextHolderFrame.BackgroundColor3 = Color3.fromRGB(255,255,255)
TextHolderFrame.BorderSizePixel = 0
TextHolderFrame.Name = "TextHolderFrame"
local TweenService = game:GetService("TweenService")
TextHolderFrame.Size = UDim2.new(0,TextSize.X * SpaceAmount,0,TextSize.Y)
for i = 1, #text do --loop through every character in the text string
CharacterLabel = Instance.new("TextLabel")
CharacterLabel.ZIndex = 2
CharacterLabel.BackgroundTransparency = 1
CharacterLabel.Font = TextFont
CharacterLabel.TextSize = TextFontSize
CharacterLabel.Size = UDim2.new(0,TextSize.X/#text, 0, TextSize.Y) --set the size, based on what GetTextSize returns
CharacterLabel.Position = UDim2.new(0, ((TextSize.X/#text) * i * SpaceAmount) - TextSize.X/#text/2, 0.5, 0) --calculate the position, by multiplying the size of one character, by the current character index we are on. The Scale values are just to position the text in this middle of the TextHolderFrame, which we will be parenting this label to shortly.
CharacterLabel.AnchorPoint = Vector2.new(0.5,0.5)
CharacterLabel.Text = string.sub(text, i, i) --grab just the character we need from the string
CharacterLabel.Parent = TextHolderFrame
end
--To make the individual TextLabels shake, you can do something like this:
CharacterLabels = script.Parent.TextHolderFrame:GetChildren()
Shake = true
while Shake == true do
for _, Label in pairs(CharacterLabels) do -- loop through the CharacterLabels one by one
local tween = TweenService:Create(Label,TweenInfo.new(0.05,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false,0),{AnchorPoint = Vector2.new(math.random(4.5, 5.5)/10, math.random(4.5, 5.5)/10)})
tween:Play()
end
wait(0.05)
end
ey bud, use table.insert(CharacterLabels, CharacterLabel), not CharacterLabels.insert(CharacterLabel)
Oh so that’s why my script was getting errors
Is there any way that I can have the word be nore accuratly placed in the right spot? Sometimes when i use a different font or make it a little bold with a stroke, it places diffrent than a regular textlabel would.
This game show my problem.
(P.s., i know that i need to add the text to move down to thr next column but I haven’t added it yet.
Try checking out TextService:GetTextboundsAsync(). I worked on a bit more of a complex system but here is the relevant function I use to draw the text if you are interested:
function TextBoxHandler:AddText(text: string, effects: {TextEffect}?, ...: TextArguments)
local textArguments = {...}
local params = Instance.new("GetTextBoundsParams")
-- params.Text = text
params.Font = self.Speaker.Font
params.Size = self.Speaker.FontSize
params.Width = self.Root.AbsoluteSize.X
local startPoint = self._currentTextPos
local labelList = {}
for word in text:gmatch("%S+") do
word = word .. " "
params.Text = word
local textSize = TextService:GetTextBoundsAsync(params)
if self._currentPos.X + textSize.X > self.Root.AbsoluteSize.X then
self._currentPos = Vector2.new(self._defaultPos.X, self._currentPos.Y + self.Speaker.FontSize)
end
for i = 1, #word do
self._currentTextPos += 1
local c = word:sub(i, i)
params.Text = c
local textSize = TextService:GetTextBoundsAsync(params)
local charLabel = Instance.new("TextLabel")
charLabel.Size = UDim2.fromOffset(textSize.X, textSize.Y)
charLabel.Position = UDim2.fromOffset(self._currentPos.X, self._currentPos.Y)
charLabel.Text = c
charLabel.Transparency = 1
charLabel.FontFace = self.Speaker.Font
charLabel.TextSize = self.Speaker.FontSize
charLabel.TextColor3 = self.Speaker.TextColor
charLabel.RichText = true
charLabel.Name = tostring(self._currentTextPos)
charLabel.Parent = (self.Root :: Frame) :: Instance
table.insert(labelList, charLabel)
self._textLabels[self._currentTextPos] = charLabel
self._currentPos += Vector2.new(textSize.X, 0)
end
end
self._textLabels[#self._textLabels]:Destroy()
if effects then
for i, effect in effects do
effect(labelList, startPoint, table.unpack(textArguments[i] or {}))
end
end
local charDelays = self.Speaker.CharDelays or {} :: {[string]: number}
for _, label in labelList do
label.Transparency = 0
label.BackgroundTransparency = 1
local charDelay = charDelays[label.Text]
if charDelay then
task.wait(charDelay)
else
task.wait(self.Speaker.SpeakingDelay)
end
end
-- effect(labelList, startPoint, ...)
end