Adding Punctuation Pauses To TweenService Typewriter

so i am trying to add punctuation detection (so that i can pause the typewriter as i please) to a typewriter script that i’ve whipped up, but i have no idea where to begin. i want to detect punctuation while the tween is playing.

this is my typewriter script as of right now:

-- simple typewriter made with TweenService.
local typewriterText = "hello there! this new typewriter is created with TweenService; it can create text that has smooth, appealing visuals."

local textLabel = script.Parent:WaitForChild("TextTest1")
local tweenService = game:GetService("TweenService")

local sentencePauses = {",", ":", ";"} -- how would i detect punctuation? not sure.
local sentenceEndings = {"!", ".", "?"}

local function tweenTypewriter(text:string, label:TextLabel)
	label.MaxVisibleGraphemes = 0
	label.Text = text
	local characterNum = utf8.len(text)
	local propertyTable = {
		MaxVisibleGraphemes = characterNum
	}	

	local durationPerCharacter = 0.03
	local totalDuration = characterNum * durationPerCharacter
	local info = TweenInfo.new(totalDuration, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)

	local tween = tweenService:Create(label, info, propertyTable)
	tween:Play()
end

task.wait(5)
tweenTypewriter(typewriterText, textLabel)

1 Like

You can use a for loop to check every character of the text, and add extra time like so:

local totalDuration = 0

for i = 1, #Text, 1 do
	totalDuration = totalDuration + durationPerCharacter
	
	for _, v in ipairs(sentencePauses) do
		if Text[i] == v then
			totalDuration = totalDuration + sentencePauseDuration
		end
	end
end

You can also repeat the for _, v loop for sentence endings, or combine the two.

1 Like
-- simple typewriter made with TweenService.
local typewriterText = "hello there! this new typewriter is created with TweenService; it can create text that has smooth, appealing visuals."

local textLabel = script.Parent:WaitForChild("TextTest1")
local tweenService = game:GetService("TweenService")

local sentencePauses = {",", ":", ";"} -- punctuation characters that will cause a pause
local sentenceEndings = {"!", ".", "?"} -- punctuation characters that will cause a longer pause

local function tweenTypewriter(text:string, label:TextLabel)
	label.MaxVisibleGraphemes = 0
	label.Text = text
	local characterNum = utf8.len(text)
	local propertyTable = {
		MaxVisibleGraphemes = characterNum
	}	

	local durationPerCharacter = 0.03
	local totalDuration = characterNum * durationPerCharacter
	local info = TweenInfo.new(totalDuration, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)

	local tween = tweenService:Create(label, info, propertyTable)
	tween:Play()

	local function checkForPunctuation(character:string)
		for _, pauseChar in ipairs(sentencePauses) do
			if character == pauseChar then
				task.wait(0.5) -- pause for a short duration
				return
			end
		end

		for _, endingChar in ipairs(sentenceEndings) do
			if character == endingChar then
				task.wait(1) -- pause for a longer duration
				return
			end
		end
	end	for

 i = 1, characterNum do
		local char = utf8.sub(text, i, i)
		checkForPunctuation(char)
		task.wait(durationPerCharacter)
	end
end

task.wait(5)
tweenTypewriter(typewriterText, textLabel)

Source: Assistant | Documentation

i managed to solve it myself, but thank you for helping to point me in the right direction :+1:

i ended up doing the following:
to ensure consistent pauses at the proper punctuation, i used a coroutine that runs alongside the tween. this coroutine checks the current character being displayed and pauses the tween if necessary.

local function tweenTypewriter(text:string, label:TextLabel)
	label.MaxVisibleGraphemes = 0
	label.Text = text
	local characterNum = utf8.len(text)
	local propertyTable = {
		MaxVisibleGraphemes = characterNum
	}	

	local durationPerCharacter = 0.03
	local totalDuration = characterNum * durationPerCharacter
	local info = TweenInfo.new(totalDuration, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)

	local tween = tweenService:Create(label, info, propertyTable)
	tween:Play()

	local function checkCharacter()
		while tween.PlaybackState ~= Enum.PlaybackState.Completed do
			local graphemes = label.MaxVisibleGraphemes
			local character = string.sub(textLabel.Text, graphemes, graphemes)
			if isSentencePause(character) then
				tween:Pause()
				task.wait(pauseDuration)
				tween:Play()
			elseif isSentenceEnding(character) then
				tween:Pause()
				task.wait(pauseDuration * 1.75)
				tween:Play()
			end
			task.wait()
		end
	end

	coroutine.wrap(checkCharacter)()
end

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