How to make Text Writing Effect in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we're going to make a very nice text writing effect each letter gets written one by one with variable speed and the text position is preserved as it gets written let's begin [Music] hello and welcome I'm your code monkey and this channel is all about helping you will learn how to make your own games with in-depth tutorials made by a professional indie game developer so if you find the video helpful consider subscribing so this is the effect that we want to make the text is written letter by letter with a custom speed as you can see the text position is preserved so each letter gets written exactly where it should be there is also the ability to skip writing this text by clicking while C text writer is active so quick starts and click and it skips and you can also hear a nice talking sound effect that is active long the text is being written and as soon as the text finishes the sound stops you might recognize this setup since this is pretty much exactly the assistant from Ballarat I could this is an excellent effect to polish up any text you have in your game alright so this is our goal let's get to it here we are in our starting scene so let's begin by making the UI visual so over here in the canvas let's make a new game object and call this the UI assistant now inside let's place a new UI image and over here in my textures folder I have the assistant image straight from Ballarat icon now in here let's make a new game object this will be our container for our message then in sign let's add an image for the arrow another image for the background all right this is the visual now for the UI text in here let's write some random text let's set it up right there and expand the size to occupy the entire box now here to make the support any amount of text let's add the best fit and put a nice maximum okay all right so this is our UI setup we have a nice assistant visual and the text object set up to support any amount of text that we want okay so with this set up let's go into our code so let's first go into the scripts making you see sharp script this will be our UI assistant drag it on to our game object okay now in here let's begin by first storing a reference to our text object so let's grab it on our private void awake we need to be using Unity engine UI okay okay we have our reference for our text field now just for testing let's try setting the text on our start so in here we simply do message text dot text then let's put this on text okay let's try it out and see if our text changes and if there it is there's our nice text okay so far so good we have our UI set up and the code is running now let's make our text brighter so over here make a new C sharp script this won't be the text writer let's make a game object to run our script so in here make our text writer and drag our script okay okay so let's begin by making a function to add a writer to write some text so let's call this simply add writer now in here we need to think about what parameters were going to need now first of all we obviously need to know where we want to write so we need a reference to the target text object then we also need to know what text we want to write so a string for our text to write and finally we need to know how fast each character should be written so let's receive a float for the time per character alright that's it this is all the information we need now let's store these as variables okay now we also need to store a timer so a simple float for our current timeline and now let's do our update and on our update first of all we're only going to run this if we have a UI text object so we do with something live so if it does not know then our text writer is active then in here we simply reduce our timer by the time double time then we check if the timer is under zero then we want to display next character so the first thing we do is reset the timer so we increase the timer by our time for a character that way the code in here only gets run every this amount of time and now in here we need to know what is the next character so that means that we need to keep track of the current index that we are writing so up here we store an int for our character index then we add the writer we set this simply to zero then on the update we increase the inlets so every time we go through this we increase it by one and as we increase it we set the text so our UI text our text we set it to a substring of the total text that we want to write so we do a substring we start off on index zero and we go all the way up to the character index so over time this runs the character index increases so we print another character right so just like this we should have our basic text writer working so let's see how we're going to run this code and we need to do is call this function so in order to do that we need a reference to our text writer so let's go to our UI assistant and in here let's a civilized feel for our text writer so let's drag that reference we're here in the editor there's the assistant with our film and just drag the reference yep there it is alright so now in here we can call our functions so on start instead of setting the text directly let's call our a driver let's pass in our message text for text right let's pass in this same message and the time for character let's put it whenever so we're going to print one character per second alright let's test if there is one character another one another one and yep everything seems to be working right it's printing one character each second so let's see what happens when reaches the end any of there you go we have an error here in the console we can see we have an argument out of range exception as it says the index and the length must refer to a location inside the string so the index cannot be passed in length so we need to test for our end condition so let's go into our code for our text writer and in here on the update we increase the character index okay and now in here let's test if we are already showing the complete string so we simply do an if the character index if the character index is bigger than the text to right point then we have the entire string display so in here let's stop our code so in order to make sure it doesn't run again let's set the UI text back need-to-know and we simply do a return so inclusive this then the next frame UI text will be no so it doesn't run again until it receives another writer all right so let's test and see if everything is working okay here it is and the message is still being written one character per second let's see it at the end and there it is the end of the message helloworld and if there you go no error as soon as it reaches the end the string everything stops and everything is great right awesome so far so good now the coding here actually has a sneaky error so let's say if we go in here let's try to print so here let's say we want to write 20 characters and we want to write it at a rate of 10 characters per second so 0.1 seconds per character so essentially this whole message should print in just few seconds so let's see it running normally there it is and yep after two seconds yep the whole message is ready okay great however now let's go in here and let's forcefully only with our frame rate to just 3 frames per second so go into the application and set the target frame rate to just 3 so again let's see if the message does write in 2 seconds and here we are and nope the message is not being written in 2 seconds it is taking a lot longer now the reason for that is because each frame is taking a ton of time to render so what happens is over here on the text writer our dump the time is massive so that means the timer goes down by a massive amount but we are only doing it simple if so the first tons of time won't put the timer a massive amount under 0 but it will only print 1 character on this update so on the next update it will only print 1 character and so on and so forth so if the depth of time is bigger than 10 per character then the code will not work perfect so the solution to this is actually very simple we just work place in if with a while so whilst we're still in the same frame we're going to print as many characters as the timer allows so let's see if our code running at 3 frames per second still writes that home message in just 2 seconds any of there it is you can see each frame more than one character is written in order to make sure that everything works great right great so even when running at an extremely low framerate our code cell works perfectly all right now one potential issue you see is with the position of the text since the text is centered as it gets written it becomes very hard to read since the text is always moving around so it would be a lot better if we could keep each character in its final position so let's do just that back in our text writer so let's head in here as an extra option let's receive just a bullion now let's call this the characters let's store it okay so now in here let's go into our update so in here we increase the index we calculate the substring okay let's hear store this on a string text and then we set the UI text our text to our text okay however before we do that let's do a simple if for our invisible characters and if we want to render the invisible characters then let's add the rest of the text but set the color in order to be invisible so we increase our text by the substring except in this case it's starting on the character index going all the way to the end and then we simply wrap this with a color tag the color in here is in RGB eh so we have our red then our green then our blue and finally our alpha so with an alpha of zero this text won't be hidden alright so that's pretty much it all we need to go is go back here and on our text writer let's trim on our invisible characters let's see any of there it is each character is being written one by one and now we can actually read it a lot better since every character stays exactly on its final position if we pause when the effect is active let's inspect our text object and in here you can see what's going on so we have the visible part and then we have our color tag and the remainder of our text without this being invisible right awesome so our text writer is working but right now we have one pre-baiting limitation in here and let's simply duplicate the UI assistant push it to the left I'm okay and now let's see what happens and as you can see the issue is that only one is working this one is completely static so essentially when we add a second one the second one overrides the first one so only one is active at a time so let's modify our code in order to support multiple text writers at once now there are many a pro we can take here for example we could create a new game object and add the text writer to it whenever we create one however that approach would create a lot of game objects which would severely affect performance so the approach we're going with is to have just one main text writer script and then internally we're going to handle various instances of text frames that way we just have one game object handling as many instances as we want so here on the text writer class let's make a missive class and this will represent a single text wrap okay now in here let's copy our code and the add writer function will essentially be on the constructor alright so we put our code in our nested class and over here on our main class let's simply store a film or a text writer single and when we add writer we created then on our private boy updates if it is not known then we simply call update on it all right so that's it we have our main class just responsible for receiving the function to add a writer and then we have our logic inside our nested class so let's test and see what happens and yep there you go the text writer is still working and everything so working fine exactly the same as previously so we modify the internals of the class but we kept the same exposed function so everything works without having to modify anything else all right now that this new structure is working let's add support for multiple text writers so in here instead of storing just a single text for instance let's store a list then on our private void awake let's initialize our list when we add a writer let's add it to the list and on the update we cycle through the list alright that's it so just like this we should have had a support for multiple text reps so let's test and see if both writers are working any of their it is we have our both text writers working at the same time awesome okay so everything is working but let's see how we can further improve our code now right now in here our objects never get removed from the list so we can't add we add an instance to the list and we keep updating it forever and the update just tests if it's not known so it doesn't break but we keep adding more instances to our list so after quite a while this list would be filled with zombie instances so let's make sure we remove an instance from the list when it is completed now one way I like to do that is by going into the update and just change the return value to boolean and essentially what it does is returns true on is complete so we no longer need to test for UI text to be not null since it won't always be valid then when we reach the end we simply return true and if we don't return true then we return false all right so we have our update function correctly updating and also telling it if it is complete so going back up here where we are cycling through our instance and here let's simply store the return for our update let's call it destroy instance and if we should destroy instance so if the update returned true then let's remove it from our list so going here remove index and since we are doing this inside our four we need to go back and index in order to not skip one alright that's it everything should be working so we're here on the update let's do a debug log on the single list in order to make sure that it goes up while active and then goes down okay here we are and the log is indeed saying two so we have two instances of our text writer and when they both finish their message and there we go it goes back down to zero okay awesome so we no longer have zombie instances wasting performance now one more thing we can do to make our class easy to use is to make it work with simple static functions so that is very simple we simply make here a private static text writer insolence and set it on awake and now let's make this function private and expose a public static the static function simply calls the internal function on our instance alright so we now have a static function and the benefit of this is let's go back into our assistant and in here we don't want to need to store a reference for our text writer in here instead of that we simply come by the class name X writer and we call the static function and that's it now our class is much easier to use this way we don't need to keep passing around references to our object we just come out using the static method so my tea and everything should still be working and there it is both of them still work but we no longer need that reference ok awesome now that we have this let's add the ability to cancel a right so before we see why that's important let's write some code to click on the window in order to skip and show the message so in here we can now get rid of the e secondary assistant ok here on the message game object let's add the button UI component this is part of the code monkey you Tonys that you can grab for free from unity code monkey calm now let's go into our assistant code let's grab the reference to the button and reset the click function to be something all right every time we click let's show a different message okay here's an array with a bunch of messages let's just play a random one all right let's s and see if when we click we can get a new message okay here it is let's click and if there you go there's a nice message click again and yep there you go nice message click again and yep there you go another message click again and yep another message ok great so we are correctly capturing our clicks and posting a different message however let's see what happens when I click multiple times and if there you go everything is completely broken so essentially what happens is that we have multiple text writers competing for the exact same object so we should really destroy the previous one before starting a new one so let's go make that function here on the text writer let's make a function for remove writer and let's identify it with the UI text object so what we do is we cycle through our single list and if this one we test for the UI text object so let's make a function here to return that object so now we can use this all the way up here so if the UI text matches the one that we are looking for then let's remove this one okay so we are correctly removing it from the list and now here on the end let's another optional parameter let's call this remove writer 54 ad and if we receive this as a true let's go remove right all right that should do it let's just go into the assistant and add true on our final remove right okay let's test okay click and yep some words normal now spam clicks any up there you go as you can see it goes back and only plays the very last tax credit so if I stop yep there you go there's one there's another one another one click a bunch of them and yep we no longer have that but okay awesome so another great thing to add to our text writer is in order to be able to skip it when we click so essentially if we click when one is active and click again we should be able to completely see that message before spawning another so for that let's go into our assistant code and in here let's store the text writer text writer single instance so when we add a text writer let's receive that instance so let's modify this in order to return the instance that is created so we just go here modify this return value return from this function modify this return value and then in here we created and just like this okay so every time we call this function we get a return value of the instance that was created so back in here we now have this one and I mean here when we click essentially we want to know if we have a text writer and if it is active and if it is we want to skip and if not then we want to show a new message so we need to test if the taxpayer is active so let's go in here in order to make that function so we make a public return a volume call it is active and here we simply return ap character index is under the text to write link if it is under that then we still have characters right so we are still active so back in the assistant we can out do our if so if the text writers single first of all let's test if it's not known so if it's not the very first one so not know and text writer single dot is active so we have the currently active text writer and if not then we do the same code as previously in order to spawn a new one okay so if it is active then we want to complete it instantly and destroy it so let's make that function or not our text writer single in here making public void and let's call it right all and destroy in here what we're going to do is write the whole thing so let's set the UI text add text to be the full text to write so we write all the text and then let's come up here our remove writer function so in order to not need to pass in references and let's make a static version of this function all right just like that so down here first we write on text and then we context writer dot remove the writer and we pass in our UI text all right so we simply call this in here so if we have a currently active text writer then we call extra a single dot right and destroy now here the is active is testing for the character index so let's make sure we also change that to be the text to write that link so the next time that this is called it won't be false all right so that's pretty much it essentially when we click on our message first we check if we have a text writer and if it is active if so then we call write and destroy so if we click once the text is being written it should display the entire text string and if not then we simply play a new text ring okay that you do it let's see okay your arm let's click OK I'm let's see more longer message click OK it's active click on any up it skips in order to display the entire message so click starts click skip click click click click ok awesome so we have successfully mated that we food click once the writer is active it instantly writes on the text and if we wait for all of it right then we click then it simply prints the next message all right awesome now let's just add one more thing over here in the project found I have this nice thumping effect I made this ages ago and it was heavily inspired by the sound effect on GTA and GTA 2 here it is what's here there it is as you can see just a very nice mumbled honking sound so we want this to play once the text is right so in here let's add the sound to our game object okay here's the talking sound game object now let's go into our script let's grab our reference and in here when we instantiate our ad writer let's start playing our sound just like that alright let's see if the audio starts when we start writing a message okay here we are let's click and if there you go the sound started when I click OK brick now obviously you can hear the problem is that it never stops so in order to fix that we need to know when the text has finished right so for that let's go into our text writer and all the way up here let's add another parameter this will be an action which is inside the using system namespace okay so we have an action which is essentially just a voice delegate and let's call this on complete so let's pass this to our instance function and also to our constructor so here we store our action and down here on our update when the entire string is displayed if we have a nun complete then let's trigger and do the same thing in here when we right on and destroy alright that you do it so we now have a nice compact function so we can go back into our assistant and in here we pass in our action so let's make a function that will work as our action let's call it the stop talking sound alright just like that so when we add a new writer we started talking sound and then we pass in the stop talking sound which won't be triggered when the text writer has finished okay so let's see that okay here we are let's click there is a sound and when it finishes yep the sound stops awesome so he clicked and reaches the end and stops now we click and we skip and it stops as well alright awesome so here we have created a very nice text writing effect this is great for anytime you want to polish the text you're showing the players you can see this effect in action in the assistant for battleground thank you it looks much better like this than just printing the text instantly we created a very nice clean class to handle everything it supports multiple writers and the whole thing is done using a single turn so it's very simple to use using our static functions anywhere else in the code all you need to do is call our static functions and everything will work flawlessly so there's no need to pass any references around so here it is our nice text effect one with some nice sounds as always you can download the project files in utilities from Unity code monkey comm if you liked the video subscribe the channel for more unity to turrets post any questions you have in the comments and I'll do my best internal alright see you next time [Music]
Info
Channel: Code Monkey
Views: 67,820
Rating: undefined out of 5
Keywords: unity text type effect, unity text writing effect, unity ui effect, unity ui text animation, unity text animation, unity typing effect, unity ui text, dialogue text unity, typewriter text effect, unity writing, unity typing game, typewriter text unity, code monkey, brackeys, unity tutorial, unity game tutorial, unity tutorial for beginners, unity 2d tutorial, unity 3d, unity 3d tutorials, unity tutorial 2d, unity2d, unity3d, unity
Id: ZVh4nH8Mayg
Channel Id: undefined
Length: 30min 59sec (1859 seconds)
Published: Fri Sep 13 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.