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)
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.
-- 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)
i managed to solve it myself, but thank you for helping to point me in the right direction
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