More efficient method for dialogue?

I’m making a dialog system and I need a “click to advance” for it, which is something I’ve always struggled with.
I found out how to do it, but it’s not a great method nor is it very efficient.

local textlabel = script.Parent:WaitForChild("TextLabel")
local function write(object,text,length)
	for i=1,#text,1 do
		object.Text=string.sub(text,1,i)
		wait(length)
	end
end
write(textlabel,"text 1",0.2)
game:GetService("UserInputService").InputBegan:Connect(function(input)
	if input.UserInputType==Enum.UserInputType.MouseButton1 then
		write(textlabel,"text 2",0.2)
		end
end)

I use a function that detects if the player has pressed the left mouse button, then make it so that if it’s the case, progress to the next line of dialog. But if I have more than one of these, as in:


write(textlabel,"text 1",0.2)
game:GetService("UserInputService").InputBegan:Connect(function(input)
	if input.UserInputType==Enum.UserInputType.MouseButton1 then
		write(textlabel,"text 2",0.2)
	    if input.UserInputType==Enum.UserInputType.MouseButton1 then
		write(textlabel,"text 3",0.2)
		    end
		end
end)

Not only does it get very messy, but you’ll obviously see a problem: Since multiple functions are always looking out for the same input, obviously all functions will trigger at one once I press the left mouse button.

I’m a coding amateur and have absolutely no idea how to tackle this; I need help.

1 Like

You can always make a dialogue system yourself, utilizing UI and camera manipulation, to make it seem more surreal. The only downside would be it would take a lot longer to create. Here is an example of what I am talking about.

The Code itself isnt messy, but some of the stuff your using is just outdated, and not really a good idea to be using anymore, like fot example: you are using wait(), wait() is basically outdated compared to another method known as task.wait(), task.wait() is faster than wait() and yields until the next heartbeat,

wait(1)      -- old, slower
task.wait(1) -- Better, faster

If you test them out, you’ll notice their Differences real quick, but with this, we can apply it to your write function.

local function write(obj, str, dur) -- I change the Argument names so I could understand
	for i = 1, #str do -- this for loops third Argument defaults to 1, so basically useless.
		obj.Text = string.sub(str,1,i)
        -- Alternate method for string.sub() would be obj.MaxVisibleGraphemes.
		task.wait(dur) -- should be faster than wait()
	end
end

This would improve the speed of the write effect to be more accurate.

But now, What about the Connections firing at the same time, we can check if the write function is firing or not by creating a Variable to keep track of it, like this:

local isTypewriting = false

With this variable we can then check if its false of not by either doing if not isTypewriting or if isTypewriting == false, its really up to you how you want to decide how you want it, But we will add this to the Connect, Like this:

local UIS = game:GetService("UserInputService")
local InputType = Enum.UserInputType.MouseButton1 
-- this is just so its easier to read the code

UIS.InputBegan:Connect(function(input)
	if input.UserInputType == InputType and not isTypewriting then -- this will check if its the Correct Input and if isTypewriting is Disabled
		write(textlabel,"text 2",0.2)
	end
end)

So within the write function, we can then say that isTypewriting is true and have it write without issue.

local function write(obj, str, dur)
    isTypewriting = true -- Prevents the Connection from firing the if statement
	for i = 1, #str do
		obj.Text = string.sub(str,1,i)
		task.wait(dur)
	end
    isTypewriting = false -- will disable after the loop is finished
end

Hope this helps!

2 Likes

Thanks! Did some tampering with it and got something I liked!

1 Like

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