Type-Writer Effect Module

Hello, I got bored today and decided to make a quick Type-Writer module. It’s very straightforward to use and has great features that make it good to use!

How to use:
local script:

local Module = require(module.Path)

local TextLabel = --diction to textLabel
local Text_String = "This is a text string, I am used for tests. :D"

local module_Propertys = { --all values that can be changed at the moment.
    _typeWriter_Wait = .05, --Average wait time for any other characters
	_commaWait = .15, --Wait time when there is a comma
	_puncuationWait = .75, --Wait time when there are punctuations
	_soundId = "rbxassetid://2541098554", --Add any custom sound for typewriting
	_volume = .1 --Volume for the sound

     }

Module.TypeWrite(Text_String, TextLabel, module_Propertys)

Module Script

local debris = game:GetService("Debris")

local module = {}

function module.TypeWrite(Text: string, TextLabel: TextLabel, propertys)
	setmetatable(propertys, {
		
		__index = { --adds default properties if table left empty
			
			_typeWriter_Wait = .05,
			_commaWait = .15,
			_puncuationWait = .75,
			_soundId = "rbxassetid://2541098554",
			_volume = .1
		}
	})
	local waitTime = propertys._typeWriter_Wait
	local sound = script:WaitForChild("cache"):WaitForChild("sound")
	sound.Volume = propertys._volume
	sound.SoundId = propertys._soundId
	
	for i = 1, #Text do
		print(string.sub(Text, i, i))
		local soundClone = sound:Clone()
		if string.sub(Text, i, i) == "." or string.sub(Text, i, i) == "?" or string.sub(Text, i, i) == "!" then
			waitTime = propertys._puncuationWait
			
		elseif string.sub(Text, i, i) == "," then
			waitTime = propertys._puncuationWait
		elseif string.sub(Text, i, i) ~= "," or string.sub(Text, i, i) ~= "!" or string.sub(Text, i, i) ~= "?" or string.sub(Text, i, i) ~= "." then
			waitTime = propertys._typeWriter_Wait
		end
		soundClone.Parent = TextLabel
		soundClone:Play()
		debris:AddItem(soundClone, .25)
		TextLabel.Text = string.sub(Text, 1, i)
		print(string.sub(Text, 1, i))
		task.wait(waitTime)
	end
end

return module

TypeWriter.rbxm (2.2 KB)

Of course, I’m too tired to explain everything in detail so for right now this will have to do. Please submit feedback so I can make this better and more efficient

9 Likes

Would it not be better to include a video?

When I have the time I’ll include a video

Here is a cleaned version of this for no reason

local TypeWriter = {}

--//Services
local Debris = game:GetService("Debris")

--//Sounds
local Sound = script.SoundCache.Write

function TypeWriter.TypeWrite(Text: string, TextLabel: TextLabel, Propertys)
	
	--MetaTable
	setmetatable(Propertys, {
		
		__index = {
			
			_typeWriter_Wait = .05,
			_commaWait = .15,
			_puncuationWait = .75,
			_soundId = "rbxassetid://2541098554",
		}
	})
	
	local WaitTime = Propertys._typeWriter_Wait
	Sound.SoundId = Propertys._soundId
	
	--Loop
	for i = 1, #Text do
		
		local NewSound = Sound:Clone()
		
		if string.sub(Text, i, i) == "." or string.sub(Text, i, i) == "?" or string.sub(Text, i, i) == "!" then
			WaitTime = Propertys._puncuationWait
			
		elseif string.sub(Text, i, i) == "," then
			WaitTime = Propertys._puncuationWait
		elseif string.sub(Text, i, i) ~= "," or string.sub(Text, i, i) ~= "!" or string.sub(Text, i, i) ~= "?" or string.sub(Text, i, i) ~= "." then
			WaitTime = Propertys._typeWriter_Wait
		end
		
		NewSound.Parent = TextLabel
		NewSound:Play()
		
		Debris:AddItem(NewSound, .25)
		
		TextLabel.Text = string.sub(Text, 1, i)
		task.wait(WaitTime)
		
	end
	
end

return TypeWriter

TypeWriter.rbxm (2.4 KB)

I’ve done something similar and you’ve definitely did a great job making this using a table data structure

Do you know how you would make a reverse typewrite? As in typewriting the text out instead of in

you would have to figure out how many letters there are per line of text then you would play the array of characters backwards either by negatively iterating a number to get the key for the letter in the table. You can do that effect on a small scale if you were to use the typewriter effect on a word and punctuation instead of a letter

Im honestly too stupid to figure out what you said so im just gonan try to find a resource somewhere

  1. how many characters in a line.
  2. play it in reverse
    If you can articulate what you want AI is very good for helping you learn how to make a function like that.

"In the context of ROBLOX Luau, write a function that takes a object with a text property as an argument and do a typewriter effect in reverse. "

Ah thank you, that made it more understandable.

What Ai? Chatgpt?

ChatGPT or Bing is good for ROBLOX since it uses the dev forum as a resource.
AI are good for making pieces of what you’re trying to make unless it is a general thing. Like if you have trouble or need to do something specific asking questions can be a valuable learning experience.

Ah ok thank you, will attempt to make this and let you know how it goes

    local text = object.Text
    local length = #text

    for i = length, 1, -1 do
        object.Text = string.sub(text, 1, i)
        task.wait(0.1) -- Adjust the delay as needed
    end
end

In that example it’s wrong because it’s doing the reverse of a type writer quite literally…
This is a function that does the typewriter effect by displaying the last character then the second to last etc…

function reverseTypewriterEffect(object)
    local text = object.Text
    local length = #text

    for i = 1, length do
        object.Text = string.sub(text, length - i + 1, length)
        wait(0.1) -- Adjust the delay as needed
    end
end

It gave me this, will it work?

local function typewriterRemove(textObject, delay)
    -- Check if the provided object has a Text property
    if not textObject or not textObject:IsA("GuiObject") or not textObject.Text then
        warn("Invalid object passed. Make sure it has a Text property.")
        return
    end
    
    -- Get the initial text
    local originalText = textObject.Text
    
    -- Loop to remove each character one by one
    for i = #originalText, 1, -1 do
        -- Update the text property with the shortened version
        textObject.Text = string.sub(originalText, 1, i - 1)
        
        -- Wait for the specified delay before the next iteration
        wait(delay)
    end
end

-- Example usage
local myTextLabel = script.Parent:FindFirstChild("MyTextLabel") -- Adjust this to your actual text object
if myTextLabel then
    typewriterRemove(myTextLabel, 0.1) -- Adjust the delay as needed
end

You could just use MaxVisibleGraphemes on a textLabel and just reverse tween it.

Example:

local TweenService = game:GetService("TweenService")

local plr = game:GetService("Players").LocalPlayer
local PlayerGui = plr:WaitForChild("PlayerGui")

local EXAMPLE_TEXT = "Hello, world!"

local ScreenGUi = Instance.new("ScreenGui")
local Text = Instance.new("TextLabel")
Text.Text = EXAMPLE_TEXT
Text.Parent = ScreenGui
ScreenGui.Parent = PlayerGui

local ReverseTypeWrite = TweenService:Create(
    Text,
    TweenInfo.new(2.5)
    {MaxVisibleGraphemes = 0}
)

local TypeWrite = TweenService:Create(
    Text,
    TweenInfo.new(2.5)
    {MaxVisibleGraphemes = #Text.Text}
)

while true do
    ReverseTypeWrite:Play()
    ReverseTypeWrite.Completed:Wait()

    TypeWrite:Play()
    TypeWrite.Completed:Wait()
end

FYI I just made this in devforum so this would prob not work.

Its ok, Thank you a ton for your help though