Simple text animation skips letter

Hello, developers! I am making a text animation for my scoreboard like Hypixel’s.
It basically goes through all the letters one by one and changes them to a darker shade of yellow.

My problem is that the text is skipping the last letter because it searches for the letter from the start of the string. (I am using string.gsub) It looks like this.

string.gsub(String, Letter, NewLetter, 1)

“THE PIT”
THE PIT”

Whenever I remove the third argument, it just makes both letters a dark shade of yellow.

string.gsub(String, Letter, NewLetter)

THE PIT

Code:

Code
local TextLabel = script.Parent
local String = TextLabel.Text

local ColorCode = "<font color='rgb(195, 207, 17)'>letter</font>"

while true do
	for i = 1, #String do
		local Letter = string.sub(String, i, i)
		local NewLetter = string.gsub(ColorCode, "letter", Letter, 1)
		local NewString = string.gsub(String, Letter, NewLetter, 1)
		
		TextLabel.Text = NewString
		task.wait(0.2)
	end
end

I understand why its skipping, I am just asking for a possible solution to this problem.
Thank you!

  • DeveloperBLk
1 Like

Couldn’t you just append a random character to the end of the string so that it becomes the ignored last letter?

local String = TextLabel.Text..' ' --append a whitespace

--or

local String = TextLabel.Text
String ..= ' '

string.gsub looks to see if there is a third argument. If there is, it will only try and match that many of the same letters.

Basically it matches with the letter ‘t’ in ‘the’ instead of ‘pit’.

Instead of using gsub, how about you organize the characters into a table and iterate through that instead, concatenating the indices?

The following example is most likely really inefficient but it works i guess

local tl: TextLabel = script.Parent

local textTable: {string} = {}
tl.Text:gsub('.', function(ch)
	table.insert(textTable, ch)
end)

local counter: number = 0
while task.wait(.2) do
	counter += 1
	local prevChar: string = textTable[counter]
	textTable[counter] = string.format("<font color='rgb(195, 207, 17)'>%s</font>", prevChar)
	tl.Text = table.concat(textTable)
	textTable[counter] = prevChar
	counter = if counter == #textTable then 0 else counter
end
1 Like

Thank you!

Could you give more information on how this works? Because it’s kind of confusing for me.

So I turned the text into a table. Each character of the string is placed in order.

local textTable: {string} = {}
tl.Text:gsub('.', function(ch)
	table.insert(textTable, ch)
end)

As an example, the string "hello" would get turned into the table {"h", "e", "l", "l", "o"}

Next, there’s a loop that increments the number counter

counter += 1

If the counter reaches the limit (which is the length of the string), it gets resetted

counter = if counter == #textTable then 0 else counter

Inside the loop, the script appends the richtext color code to the designated character which is determined by the counter

textTable[counter] = string.format("<font color='rgb(195, 207, 17)'>%s</font>", prevChar)

Then it concats the table into a string which is then used on the TextLabel

tl.Text = table.concat(textTable)

When everything’s done, the character returns to its original state which is stored before the change

textTable[counter] = prevChar
1 Like

Thank you so much! :smiley:
This really helps.

So I have a little problem. It removes my text shadow. However, I created a flashing animation to go with the other animation, and the text shadow reappears. I’m guessing its because the first animation covered the text shadow. I can even see the text moving a bit when it changes. Do you know why?

What are the “text shadows”? Are they a separate TextLabel? You will have to synchronize the changes if they are

I’m 99% sure the text movement is caused by richtext itself. There are numerous issues with them, such as unintentional indents when using <br />.

1 Like

Ill try that soon. Thanks for the help!