How do you make shaky text?

I couldn’t find any tutorials on this, so is there’s any way I can make shaky text in a TextLabel? I think this would require a lot of math, and I’m not the best at math lol.

3 Likes

What do you mean by shaky text? Do you have any example of what you want to achieve?

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

1 Like

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:
image

34 Likes

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.

1 Like

Ohhhhh now I get what you were saying.

I get it now. Just needed like an example script.

2 Likes

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.

2 Likes

Alright thanks, I’ll try it out! :ok_hand:

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
1 Like

ey bud, use table.insert(CharacterLabels, CharacterLabel), not CharacterLabels.insert(CharacterLabel)

Oh so that’s why my script was getting errors

1 Like