I have a system to write a text onto a TextLabel in an amount of time, but this can be called mutliple times.
If one is called at the same time as another then they’ll both write at the same time.
I’ve been trying to find a way to halt the ongoing writing but I can’t really figure out how.
This is the code I’ve been using:
local function titleWriteAsync(text, timeToWrite)
coroutine.wrap(function()
local interval = timeToWrite/#text
Title.Text = ""
for i = 1, #text do
Title.Text = Title.Text .. string.sub(text, i, i)
wait(interval)
end
end)()
end
I did have a boolean “isWriting” and it’d wait until the other has finished, but that isn’t what I’m trying to achieve.
Any suggestions are as always greatly appreciated.
So like a qued text system? If so it’d be done like this:
This probably won’t work, but give it a try?
local cue = {};
local writing = false;
local function titleWriteAsync(text, timeToWrite)
if writing == false then
writing = true;
coroutine.wrap(function()
local interval = timeToWrite/#text
Title.Text = ""
for i = 1, #text do
Title.Text = Title.Text .. string.sub(text, i, i)
wait(interval)
end
if #cue !== 0 then
titleWriteAsync(cue[1][1], cue[1][2]);
table.remove(cue, 1)
end
end)()
else
table.insert(cue, {text, timeToWrite})
end
end
This is a good opportunity for the gods to look down upon my makeshift approach for overriding simple synchronous operations. If anyone knows of a better way, I want to hear it for sure.
For this particular response, I will be encapsulating some of the data into a Writer function. It doesn’t add much complexity, but it permits the flexibility of multiple text writers. You can pull it out of the function if you dislike the approach.
Finally, the overriding centers around the writerequest and thisrequest variables. thisrequest is created once you begin to write, and is compared to writerequest every time you’re about to write something. Anyways,
local Title = script.Parent
local function createTextWriter(TextObj)
local writerequest = 0
local function write(Text,TimeToWrite)
writerequest = writerequest + 1 --update currrent writer. Will likely never exceed 1.7 × 10^308
local thisrequest = writerequest
local interval = TimeToWrite/#Text
TextObj.Text = ""
spawn(function()
for i = 1, #Text do
if thisrequest ~= writerequest then return end --if something updated writerequest, don't perform
TextObj.Text = TextObj.Text .. string.sub(Text, i, i)
wait(interval)
end
end)
end
--return the writing function
return write
end
wait(2) --for testing purposes, so I can see the results when I join studio
local TitleTextWriter = createTextWriter(Title) --create a TextWriter for this object
TitleTextWriter("Hello sir.",2) --set that text
wait(0.5) --delay to show overriding
TitleTextWriter("ehdwayhdwaiuhdaw",2) --set that text
I’ve been experimenting, and I ended up with this code, which of course can be optimized and rewritten.
Code
local label = script.Parent.TextLabel;
local current;
local function typeAsync (text, duration)
local function run ()
local current;
local interval = duration / #text;
local i = 0;
local active = true;
coroutine.resume(coroutine.create(function ()
label.Text = "";
while active and (i < #text) do
i = i + 1;
label.Text = label.Text .. text:sub(i, i);
wait(interval)
end
print("DONE")
end))
return function ()
active = false;
end
end
-- If there is a current process of typing, stop it
if current then
current() -- This will set "active" to false in the function's scope
end
current = run() -- Now, run the "new" function
return current; -- Return current, so they can also stop it
end
-- // Checking if it properly "override" the flow
wait(1)
local a = typeAsync("hello", 1)
wait(.25)
typeAsync("Bye bye", 1)
wait(2)
-- // Checking if you can stop it
local a = typeAsync("time for test", 2);
wait(1)
a();
Thank you a ton @WoolHat & @1TheNoobestNoob; your method was pretty great Noob however Wool’s seemingly works much faster hence why I’ve given the solution.