I have a typewriter module that, well, acts as a typewriter for dialog. I’m basically looking for any kind of improvement to the code to make it cleaner, easier to read, or just a better way of doing things.
By the way, this is my first time using metatables in a module, so please point out any mistakes I’ve made!
Here it is in action!
Here is the code:
local TweenService = game:GetService("TweenService")
TypeWriter = {}
TypeWriter.__index = TypeWriter
function TypeWriter.new(name)
local self = setmetatable({
Mouse = game.Players.LocalPlayer:GetMouse(),
Dialog = game.ReplicatedStorage.Stuff.UI.Dialog:Clone(),
}, TypeWriter)
self.Dialog.Parent = game.Players.LocalPlayer.PlayerGui
self.Dialog.Enabled = true
self.TopLine = self.Dialog.BG.Extras.Top
self.TypeSound = self.Dialog.TypeSound
self.ClickSound = self.Dialog.ClickSound
self.TextBox = self.Dialog.BG.TextBox
self.Continue = self.Dialog.BG.Continue
self.Typing = false
self.ContinueTween = nil
self.Halt = false
self.Connection = game.Players.LocalPlayer:GetMouse().Button1Down:Connect(function()
if self.Typing then
self.Halt = true
end
end)
TweenService:Create(self.TopLine, TweenInfo.new(1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {Size = UDim2.new(0.853, 0, 0, self.TopLine.Size.Y.Offset)}):Play()
for i = 0, string.len(name), 1 do
local ns = string.sub(name, 1, i)
self.Dialog.BG.ThingName.Text = ns
wait()
end
return self
end
function TypeWriter:Type(text)
if type(text) == "string" then
local connection
local Dialog = self.Dialog
local TypeSound = self.TypeSound
local ClickSound = self.ClickSound
local TextBox = self.TextBox
local TopLine = self.TopLine
self.Typing = true
for i = 0, string.len(text), 1 do
if self.ContinueTween then
self.ContinueTween:Cancel()
self.ContinueTween = nil
end
if self.Halt then TextBox.Text = text self.Halt = false self.Typing = false break end
local ns = string.sub(text, 1, i)
TypeSound:Play()
if string.sub(text, i - 1, i - 1) == "," or string.sub(text, i - 1, i - 1) == "." or string.sub(text, i - 1, i - 1) == "!" or string.sub(text, i - 1, i - 1) == "?" or string.sub(text, i - 1, i - 1) == ";" or string.sub(text, i - 1, i - 1) == ":" then
wait(.3)
end
TextBox.Text = ns
wait(.02)
end
self.Typing = false
delay(2, function()
if self.Continue.Visible == false then
if self.Typing == false then
self.Continue.Visible = true
self.ContinueTween = TweenService:Create(self.Continue, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1, true), {ImageTransparency = 0})
self.ContinueTween:Play()
end
end
end)
self.Mouse.Button1Down:Wait()
self.Continue.ImageTransparency = 1
self.Continue.Visible = false
if self.ContinueTween then
self.ContinueTween:Cancel()
end
ClickSound:Play()
TextBox.Text = ""
for i = 0, string.len(Dialog.BG.ThingName.Text), 1 do
local ns = string.sub(Dialog.BG.ThingName.Text, i, -1)
Dialog.BG.ThingName.Text = ns
wait(.02)
end
for i = 0, string.len(TextBox.Text), 1 do
local ns = string.sub(TextBox.Text, i, -1)
TextBox.Text = ns
wait(.02)
end
wait(.2)
elseif type(text) == "table" then
local connection
local Dialog = self.Dialog
local TypeSound = self.TypeSound
local ClickSound = self.ClickSound
local TextBox = self.TextBox
local TopLine = self.TopLine
for ind, v in ipairs(text) do
self.Typing = true
for i = 0, string.len(v), 1 do
if self.ContinueTween then
self.ContinueTween:Cancel()
self.ContinueTween = nil
end
if self.Halt then TextBox.Text = v self.Halt = false self.Typing = false break end
local ns = string.sub(v, 1, i)
TypeSound:Play()
if string.sub(v, i - 1, i - 1) == "," or string.sub(v, i - 1, i - 1) == "." or string.sub(v, i - 1, i - 1) == "!" or string.sub(v, i - 1, i - 1) == "?" or string.sub(v, i - 1, i - 1) == ";" or string.sub(v, i - 1, i - 1) == ":" then
wait(.3)
end
TextBox.Text = ns
wait(.02)
end
self.Typing = false
delay(2, function()
if self.Continue.Visible ~= true then
if not self.Typing then
self.Continue.Visible = true
self.ContinueTween = TweenService:Create(self.Continue, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1, true), {ImageTransparency = 0})
self.ContinueTween:Play()
end
end
end)
self.Mouse.Button1Down:Wait()
self.Continue.ImageTransparency = 1
self.Continue.Visible = false
if self.ContinueTween then
self.ContinueTween:Cancel()
end
ClickSound:Play()
TextBox.Text = ""
for i = 0, string.len(TextBox.Text), 1 do
local ns = string.sub(TextBox.Text, i, -1)
TextBox.Text = ns
wait(.02)
end
wait(.2)
end
elseif type(text) == "function" then
text()
end
end
function TypeWriter:ChangeName(name)
local Dialog = self.Dialog
for i = 0, string.len(name), 1 do
local ns = string.sub(name, 1, i)
Dialog.BG.ThingName.Text = ns
wait()
end
end
function TypeWriter:CleanUp(Callback)
local Dialog = self.Dialog
local TopLine = self.TopLine
local OGPos = Dialog.BG.Position
local OGTrans = Dialog.BG.BackgroundTransparency
local BGPos = TweenService:Create(Dialog.BG, TweenInfo.new(.8, Enum.EasingStyle.Cubic, Enum.EasingDirection.In), {Position = UDim2.new(0, 1000, 0, 1000)})
local BGTrans = TweenService:Create(Dialog.BG, TweenInfo.new(.8, Enum.EasingStyle.Cubic, Enum.EasingDirection.In), {Transparency = 1})
TweenService:Create(TopLine, TweenInfo.new(.5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {Size = UDim2.new(0, 0, 0, TopLine.Size.Y.Offset)}):Play()
BGPos:Play()
BGTrans:Play()
if Callback then Callback() end
BGPos.Completed:Wait()
BGTrans.Completed:Wait()
Dialog.Enabled = false
Dialog.BG.Position = OGPos
Dialog.BG.BackgroundTransparency = OGTrans
Dialog:Destroy()
self.Connection:Disconnect()
end
return TypeWriter
Here’s a rbxl file to test it out for yourself.
TypeWriter Module.rbxl (58.4 KB)