Scratch To Unity: Scripting Over Time

Beginner Scratch Tutorial Unity

Scratch has several code blocks that can take time to complete. For example, you might chain together several “say” blocks to present a conversation. Each block will then pause the execution of that stack until it completes. Up to this point, all of the code we have learned has been synchronous. This means that even if you may know enough to change the text on your UI, that each statement would run one after another so fast that you wouldn’t be able to read each message. Not to worry, we can also obtain a similar result, and we will learn all about it in this lesson.

Women in Entertainment Panel
Friday March 29, 2019

This is what diversity looks like—at The Los Angeles Film School Did you know that over the 91-year history of the Academy Awards, only one female has won an Oscar for Best Director? If you recall, the Oscar went to Kathryn Bigelow for The Hurt Locker. To add salt to the wound, Bigelow won the […]

The post Women in Entertainment Panel appeared first on Dua xe moto.

Getting Started
First, let’s create a new Scene named “Conversation”. From the file menu, choose “File” -> “New Scene”. Then choose “File” -> “Save As…” to give it a name.
Now, let’s create a label that we can print various messages to. From the “Hierarchy” pane’s “Create” button, choose “UI” -> “Text”. Feel free to edit the text’s size, color, and any other attribute to your liking via the inspector. You may also choose to change the background by editing the Main Camera.

German States
Wednesday October 24, 2018

Baden-Wurttemberg Size: 35,751 square kilometers Capital: Stuttgart Population: 11 million residents The state of Baden-Wurttemberg is located in the southwest of Germany and it covers an area of 35,751 square kilometers. This region is home to around 11 million inhabitants with around 600,000 of them residing in the capital and the largest city in this […]

The post German States appeared first on Dua xe moto.

This will actually create multiple Game Objects. If you look in the Hierarchy, you will see Canvas, Text, and EventSystem have all been created. The Canvas GameObject is the root object of all user interface objects that will be added. The Text GameObject is the actual label we will be modifying. The EventSystem object handles events that are important for many User Interfaces (like mouse clicks etc), though we will not need it in this lesson.
Use the “Project” pane’s “Create” button to create another script, and name it “Conversation”. Then attach the script to the “Text” GameObject.

Double click on our “Conversation” script in the “Project” pane to open it in the code editor. We will need to add a new using directive at the top of our script in order to work with the text label:

using UnityEngine.UI;

Women in Entertainment Panel
Friday March 29, 2019

This is what diversity looks like—at The Los Angeles Film School Did you know that over the 91-year history of the Academy Awards, only one female has won an Oscar for Best Director? If you recall, the Oscar went to Kathryn Bigelow for The Hurt Locker. To add salt to the wound, Bigelow won the […]

The post Women in Entertainment Panel appeared first on Dua xe moto.

Coroutine
To create our asynchronous code, we will use something called a coroutine. A coroutine is like other methods, except that it has a unique ability to hold a sort of book-mark in its execution. Code can run up to a point in the method, pause for some amount of time, and then continue running right from where it left off.
To see this in action, modify the definition of the “Start” method by changing its return type from “void” to “IEnumerator” like so:

IEnumerator Start()

Unity will still call this method for us automatically, just like it used to. However, it is now able to run over time. Add the following statements to the body of “Start”:

var label = GetComponent<Text>();
label.text = "Hello";
yield return new WaitForSeconds(1f);
label.text = "My name is Jon";
yield return new WaitForSeconds(1f);
label.text = "What's yours?";

In this code snippet we begin by creating a local variable named “label” which holds a reference to the “Text” component on the same Game Object. The reference is obtained using the “GetComponent” method. The type of component to get is listed inside the less than and greater than signs.
We then immediately set the text to say “Hello”. Both of the first and second statements are run right away, much like the synchronous code we have written elsewhere. The asynchronous aspect appears with the third statement. We use the “yield” command to cause execution to pause. The “WaitForSeconds” controls how long that pause will be – one second.
After one second has passed, we pick up right where we had left off. We still have the local reference to our Text component, so we can assign its text to be “My name is Jon”. We then wait for another second and print one final message before the Coroutine is completed.
Save your script, then head back to Unity and press play to watch our code run over time.
Chaining Coroutines
In the first example, we chained together multiple statements in a single Coroutine over time. It is possible to make things even more powerful by chaining together coroutines. We can do this by starting a coroutine from within a coroutine and waiting on that coroutine to finish.
Let’s change our conversation code so that it is typed out, one letter at a time. You see that effect in a lot of games where a character is speaking. Add the following method:

IEnumerator TypeOut(string message)
{
var label = GetComponent<Text>();
for (int i = 0; i <= message.Length; ++i)
{
label.text = message.Substring(0, i);
yield return new WaitForSeconds(0.1f);
}
}

The code above starts by getting a reference to our Text label, just like before. Then we do something called a loop. In Scratch, this might be similar to a “repeat” block from the “Control” category. This particular type of loop is called a “for” loop and it holds three bits of information. First, it initializes an iterator variable which commonly is named “i”. After the semi-colon, we tell the “for” loop how long it should repeat – in this case for as long as the value of “i” is less than or equal to the number of characters in the message. After the next semi-colon, we have code that runs after the each loop step, which is used to modify our iterator. We use “++i” to say “increment the value of i by one”. The “for” loop has its own body, much like a method and class do, which is marked by the open and close bracket. The two statements inside are going to be repeated with the loop.
Inside of our “for” loop’s body, we assign the label’s text to be a “Substring” of the whole message that begins at the beginning (programmers start counting from ‘0’) and spans “i” number of letters into the message. Since with each loop the value of “i” will increase, then we will see more of the message appear over time. We use another “yield” for one second after “typing” each letter.
Now change the “Start” method to look like this:

IEnumerator Start()
{
yield return StartCoroutine(TypeOut("Hello"));
yield return new WaitForSeconds(1f);
yield return StartCoroutine(TypeOut("My name is Jon"));
yield return new WaitForSeconds(1f);
yield return StartCoroutine(TypeOut("What's yours?"));
}

Now we are using the result of “StartCoroutine” as something to yield by. The parameter that we pass this method, is the result of us calling our other Coroutine and passing the message we want it to present. Taking everything together now, the first statement will pause execution until all of the letters of “Hello” have been typed out onto the screen. Then we use the “WaitForSeconds” to pause for an amount of time, and continue the same pattern with the other messages.
Save your script, then head back to Unity and press play to watch our cool new effect.
Polish
If you liked the “loop” we used to print out letters, you might like to see it used again. We can “refactor” our Start method to run in a loop since we are following a sort of pattern.

IEnumerator Start()
{
var messages = new string[]
{
"Hello",
"My name is Jon",
"What's yours?"
};

for (int i = 0; i < messages.Length; ++i)
{
var typer = TypeOut(messages[i]);
yield return StartCoroutine(typer);
yield return new WaitForSeconds(1f);
}
}

In the code above, I have grouped all of the messages into a single variable called an array, specifically a string array. Our “messages” array can hold any number of comma separated strings that we would like to give it, and the rest of the code will continue working without any changes. We could even decide to turn our “messages” variable into a field of our class, and then we could assign these messages in Unity’s inspector or provide it by some other kind of resource like a text file.
The for loop looks very similar to the last one, we iterate on “i”, until we have looped once for each message in the array. In the body of the “for” loop we can grab a particular message by indexing into the array. We specify which message we want within the square brackets. Like before, programmers start counting at zero, so our first message appears at index ‘0’. The other code, for starting a coroutine and waiting for one second, are the same.
Aborting a Coroutine
While the “TypeOut” effect is pretty cool, some of our users may get impatient, especially if they read quickly and the conversation is very long. It would be nice to be able to skip the TypeOut of each message to help speed things along.
Just like we are able to “StartCoroutine”, Unity also has the ability to “StopCoroutine”. You should note however that if you are chaining Coroutines like in this example, that a stopped coroutine will not finish, and so if another coroutine is waiting on it to finish, it will end up waiting forever.
Another solution is to to end a Coroutine using “yield break” which will return early from a Coroutine. It will still be shown as a “completed” coroutine even though it didn’t execute all of its statements. To implement this feature, start by adding a new field:

bool skip = false;

This variable will indicate to our TypeOut method whether or not it should skip its own effect. We will mark this flag as true inside of the Update loop, in the case that any key has been pressed:

void Update()
{
if (Input.anyKeyDown)
{
skip = true;
}
}

And we will check for this opportunity to skip, inside of the “for” loop body of our TypeOut Coroutine:

if (skip)
{
skip = false;
label.text = message;
yield break;
}

Here we use an “if” statement to control the flow of execution. The statements inside of the body of the “if” statement will only be executed when the tested condition is true. In this case our “condition” is simply the value held by the “skip” variable.
When “skip” is true, we first begin by setting it back to false. This way, our users will have to keep pressing a button for each message that they want to skip. Who knows, maybe they skipped by accident and actually really like the effect! Next, we assign the full message to the label, and finally we abort the Coroutine by using the “yield break” statement. There wont be any additional loop steps made, and the two statements after the “if” will not be run on this loop step.
Demo
At this point our script is complete. The full script should look something like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Conversation : MonoBehaviour
{
bool skip = false;

// Start is called before the first frame update
IEnumerator Start()
{
var messages = new string[]
{
"Hello",
"My name is Jon",
"What's yours?"
};

for (int i = 0; i < messages.Length; ++i)
{
var typer = TypeOut(messages[i]);
yield return StartCoroutine(typer);
yield return new WaitForSeconds(1f);
}
}

IEnumerator TypeOut(string message)
{
var label = GetComponent<Text>();
for (int i = 0; i <= message.Length; ++i)
{
if (skip)
{
skip = false;
label.text = message;
yield break;
}
label.text = message.Substring(0, i);
yield return new WaitForSeconds(0.1f);
}
}

void Update()
{
if (Input.anyKeyDown)
{
skip = true;
}
}
}

Save your script, then head back to Unity and try out each of our new features. Press play and allow the message to type out a letter at a time, or press a button to skip that effect and see the entire message all at once.

Links
If you want to dive a little deeper on the subject of Coroutines in Unity, then these links will help:

My Tutorial on Coroutines
Unity Documentation: Coroutines
Unity Documentation: StartCoroutine
Unity Documentation: StopCoroutine

Summary
In this lesson we learned about the differene between synchronous and asynchronous code. We learned that we can use asynchronous code to write things that occur over time. As an example, we created a simple scene that prints messages to the screen. We made it so that each letter of each message types on to the screen one at a time, and allowed users to hurry things along by using keyboard input. We implemented our asynchronous code using Coroutines and learned about the various methods Unity has in place to work with them.
If you find value in my blog, you can support its continued development by becoming my patron. Visit my Patreon page here. Thanks!