How to make a typewritter effect but with details (MaxVisibleGraphemes)

By “details”, i mean, if there’s a comma, point or space, wait a certain period of time, kinda realistic, how could i implement this into a common typewritting effect with MaxVisibleGraphemes?

local TweenService = game:GetService("TweenService")

local textObject = script.Parent

local tweenInfo = TweenInfo.new(
	4, -- it takes 4 seconds for the effect to complete
	Enum.EasingStyle.Sine, -- typing starts fast and slows near the end
	Enum.EasingDirection.Out
)

local tween = TweenService:Create(textObject, tweenInfo, {
	-- Final value should be the total grapheme count
	MaxVisibleGraphemes = utf8.len(textObject.ContentText),
})

tween:Play()
tween.Completed:Wait()

-- Reset the value so it can be tweened again
textObject.MaxVisibleGraphemes = -1
2 Likes

Does this waits Punctuation signs?

I think so, try it. I hope it does.

1 Like

Sadly It doesn’t, and It’s a bit weird, thanks for the help tho

Yaah it was a code sample on the documentation, but why don’t you use string.sub? I think it’s way better. I think with it you can detect the punctuation too. Look.

local Text = "Loading, now"

for i = 1, #Text do
local String = string.sub(Text, 1, i)
if String = "," then
task.wait(1)
TextLabel.Text = String
else
TextLabel.Text = String
end
task.wait(0.05
end
2 Likes

Because if i use string.sub, it won’t support rich text, and be more buggy

1 Like

I guess but I don’t think there’s any alternative to do your certain thing.

1 Like

To do this, you’ll have to loop through each character in the string and determine if that character is one of those for which you would like there to be a delay. I developed a script to do this, accounting for rich text markup, as shown below:

local delayTimes = {
	[","] = 0.25,
	["."] = 0.5,
	[":"] = 0.25,
	[";"] = 0.25,
	[" "] = 0.0125
}

local normalWaitTime = 0.025 --The amount of time between each character being displayed; this is added to the delay time given in the "delayTimes" table for a particular character.
function typewriter(textLabel)
	textLabel.MaxVisibleGraphemes = 0
	for charPos = 1, string.len(textLabel.ContentText) do
		local currentCharacter = string.sub(textLabel.ContentText, charPos, charPos)
		textLabel.MaxVisibleGraphemes = textLabel.MaxVisibleGraphemes + 1
		if delayTimes[currentCharacter] then
			task.wait(delayTimes[currentCharacter])
		end
		task.wait(normalWaitTime)
	end
end

In order to change the delay times for individual characters or the characters for which there is an additional delay (you mentioned “comma[s], point[s], and space[s]”), edit the values in the delayTimes table or add new keys to add a delay for other characters. Also, make sure to pass the relevant TextLabel or TextButton as the argument to the typewriter function when called.

Edit: Edited the script to use the ContentText property instead of Text.

2 Likes

Perhaps this is what you want?

https://i.gyazo.com/a07bdfc25479b75ea0cb86560aeb5fef.mp4

In order to do that, I set a couple of number ranges for the delays at certain moments, such as between letters, between words, etc. I randomly get a number in that range, whenever that moment is happening.

local textLabel = script.Parent.TextLabel

local DELAY_BETWEEN_LETTERS = NumberRange.new(0.03,0.15)
local DELAY_BETWEEN_WORDS = NumberRange.new(0.1,0.4)
local DELAY_BETWEEN_HALF_SENTENCES = NumberRange.new(0.1,0.3)
local DELAY_BETWEEN_SENTENCES = NumberRange.new(0.3,1)

local function GetNumberInRange(range : NumberRange)
	return math.random(range.Min*100,range.Max*100)/100
end
function TypeWriterEffect(str : string)
	local length = string.len(str)
	textLabel.Text = str
	textLabel.MaxVisibleGraphemes = 0
	
	local lastChar = ""
	local current_delay = 0
	for i = 1,length do
		task.wait(current_delay)
		
		if lastChar == " " then
			current_delay = GetNumberInRange(DELAY_BETWEEN_WORDS)
		elseif lastChar == ',' or lastChar == ';' or lastChar == ':' then
			current_delay = GetNumberInRange(DELAY_BETWEEN_HALF_SENTENCES)
		elseif lastChar == '.' or lastChar == '?' or lastChar == '!' then
			current_delay = GetNumberInRange(DELAY_BETWEEN_SENTENCES)
		else
			current_delay = GetNumberInRange(DELAY_BETWEEN_LETTERS)
		end
		textLabel.MaxVisibleGraphemes += 1
		lastChar = string.sub(str, i, i)
	end	
end

for i = 1,10 do
	wait(3)
	TypeWriterEffect('Hello there, how are you? I am doing great.')
end
2 Likes

Both are good answers, and i appreciate that, but i am going for @usr_updated 's solution, thank you all!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.