Making Conversations in Unity for Super Beginners

So I took part in my first ever game jam this weekend. As someone who has only messed around with Unity before, gotten confused by the various videos and tutorials – if they aren’t out of date, they make big assumptions for the beginner – and given up for the most part. It was amazing to be somewhere there was help available, and where others appreciated the knowledge I had and didn’t even know would be of value.

The event was Bristol Pride Game Jam, which was aimed at members of the LGBT+ community, and was organised by some super cool and active humans. I’d been planning to go solo and make a few scenes of a visual novel, but ended up forming a team to make a bullet hell game instead. I’m immensely glad that I did.

You can see our finished game, along with the others here: Bristol Pride Game Jam Itch! Ours is Just Go Outside!

This is the first of four posts I am planning about this subject. The second will be on creating and adding character sprites, the third on what you do when the conversation ends – how do you transition to the next part of your game? – and the last on some more general things I learnt at the event.

The bulk of the script (coding bit) was written with the help of Alex (someone who makes actual real games) and my teammate Kay.

What do I mean by a conversation manager script?

You’re probably thinking – so if you made a bullet hell game, why did you need a script for conversation management? Well, I still couldn’t let go of the idea of making a visual novel-like aspect, so decided to make a kind of pre-game cut scene that adds narrative and characters. This is actually what you get in real bullet hell games, but no one expects you to add that bit in during a game jam. You can see what I mean by playing our game at the link above, or I’ve included a screenshot here:

Game Screenshot

By conversation manager script, I mean a piece of code that allows us to change what’s in a text box whenever the player does something, eg presses space bar or clicks. In this case, it controls both the name and the conversation text (and the character image, but that’s for another day). The best part is, thanks to the way Unity works, we can then edit the conversations from Unity itself without touching the code ever again. Here’s an example of what that looks like in Unity:

15

Just gimme the code, I’ll work it out!

You can find the code here on my brand new github account, until I add functionality to embed gists.

Setting the layout

I’m going to assume that if you’re reading this, you already have Unity installed, and you know how to do things like create a new project and saving a scene etc. I’ll try not to assume anything else, as this is supposed to be an article that would have helped people like myself, aka clueless, bumbling, enthusiastic optimists.

The first thing you want to do is create a new canvas. This is like the pane of a window that you’re looking through. I made one with a set size, which is why when you play the game, it doesn’t fullscreen the cutscene parts. There are ways of changing this, but I haven’t looked into what effect this would have on the text size etc. So for now, this has a static size of your choosing.

Create a canvas by right clicking in your hierarchy tab (left-hand side), selecting UI and then Canvas. Zoom out so that you can see the entire canvas in your scene view in the middle of the Unity application. Inside this, you’re going to make two UI->Image and two UI->Text. You can see all three types in the menu screenshotted below:

1

The two images are the coloured rectangles your text will sit on top of, so set those out first, then put the text on top. You can control which objects are on top through the hierarchy. Things at the bottom of the list are on the top layer, so make sure your text is lower than your image! See my suggested layout below:

4


Bruce, help! I stretched my text object to be that big and now the text looks all pixellated and weird!!

No fear – this is a weird thing that happens. When you resize a text object, it uses scale automatically. This also scales the size of the text inside and makes it look bad. To change the size of the text box without scaling the text inside, you need to use the Width and Height to change it. You can find these values in the inspector on the right hand side if you have selected your text. Enter the size you want, and make sure that Scale is set to 1 on X, Y and Z:

2


Name your objects something easy and intuitive. I went with TextText for the main conversation and NameText for the smaller text box that will contain the name of the character speaking.

Writing the Script

Okay so we’ve set that all up. We can change what shows up in the two text boxes outside of playtime, but we want to make it change when the player put in input.

First off, let’s create the script. A script is a file that contains instructions, basically. It tells the game what to do and how to act. If you make a button, you need to tell the game what to do if the button is clicked. If you want to change the text, you need to tell the game what input makes it change, and where it can find the words you want to put inside.

I made this script through TextText, but it doesn’t matter if you make it through NameText. Just click on the textbox in the hierarchy to the left, then scroll down to Add Component in the Inspector on the right. This opens a drop-down of components you can add, and you want to select “New Script  >”. You’re then prompted to add a name for the script. Note that whatever you name it here, you should keep because otherwise you have to change the name inside the script as well. I called mine TextManager. You will see this component added to your Inspector:

5

You can open the script in VisualStudio, the text editor that comes with Unity, by double clicking the small box inside. Once this is open, it should look like this:

6


Bruuuuce, I don’t know what any of these things mean!

That’s understandable. you don’t have to be a software engineer to make games in Unity. In fact, you don’t even need to know what any of these things mean, exactly.

At the top, the lines starting with “Using” tell Unity what it needs to know to be able to read your code. We create things called functions, variables, and use lots of different types of brackets, how does Unity know what any of this means?? We tell it, that’s how. Sometimes you will need to add something to the top, such as “Using UnityEngine.UI;” or some physics etc. Don’t worry about it for this.

Underneath that you have a public class with the title of the script. A class is just a box, and we’re going to put lots of things inside it. The box has TextManager written on the side in sharpie so that we can tell our friend “Hey, can you open up the TextManager box and use all the stuff I put in it?” If it didn’t have a name, they’d never know which box you mean. Adding Public before this means that it can be accessed anywhere. Most importantly, it means that Unity can access it.

Everything inside that class is inside the squiggly brackets, which are like the sides of the box. Including some other smaller boxes which have brackets of their own. Void Start sets the state of the game when you start. Anything you put in here, will be there when the game starts, eg. five enemies, a text box, a HP counter… Void Update listens for input, tracks and changes the state of the game while you’re playing it. eg has anything died, or has a key been pressed? And what changes if so?

Oh, and the lines starting // are commented out. The computer will ignore these when running the script. You can write // at the start of a line, and use this to make notes or comments. You can delete these lines without breaking anything.


In order to decide what to write, we need to break down what we want the script to actually do. This is my list – a list of problems to be solved:

  • Show text in the text boxes we made
  • Know what order to show the lines of conversation in
  • Change the text inside the box when the player presses the space bar
  • Let us change the text and number of lines in the Unity application

Alright! Let’s go.

We start by telling the code that we have two Text items, and naming them so that we can refer to these later. I’ve matched them up to what they are called in Unity – this does not mean they are connected up already, good naming simply makes more readable code. I’ve put this above Start, and made them public so that Unity we can see them in Unity later.

7


If you’re not used to coding, just keep an eye on where there are spaces here. You’ll also note that I called them textText instead of say TextText or texttext. This is called camelCase, and is readable. If you create a class such as TextManager, then you capitalise both words. Don’t add a space between text and Text.

There’s a ; on the end of these lines. This helps the computer know that one piece of information or a command is finished, and it can go on to reading the next one.


Ok so we have two text items. You can save the script at this point, open Unity and press play on your game. If you look at the Console tab, you shouldn’t see any errors. If you do, check again that you’ve added “;” on the end of each line, and put spaces where appropriate. Next up, we want to make a counter that will keep track of how many conversation lines have been, and which to show next. Otherwise, how will it know if Bob is saying “Hey babe”, or Pippa is saying “Everybody’s dancing in the moonlight”?

Luckily this is simple:

8

Underneath what we already wrote, we add the new line. This creates a variable called progress. This is just a tiny container you’re storing in your big box. It only has one thing inside, and that’s the number 0. Using the keyword int tells the computer that the container is always going to contain a number. You couldn’t put a word in, it’s for numbers only. We can change the number inside though. We can make it so that while the number is 0, the text box will say “I love chairs” and if the number is 1 it says “It’s nap time” and if the number is 2 it says “Don’t eat shoes for breakfast, they’ll give you indigestion.”

For this, we need to make a list of what the textboxes can say. We call that list an array, and we define one by using square brackets, as below. I’ve written two lists just above the integer (number) we made, one for each text box we want to change.

10

We’ve made this public, so that we can access and change these lists through Unity, so we won’t be writing the script out here. We want to add a name for the arrays, so that the computer knows where to find them if we are looking for them later, so you can name them by typing out the name after the closed square brackets. Remember to use camelCase, and name them something recogniseable but different to ones you have used before. The word string is like int, but instead of saying this container is just for numbers, it means this container is only for words, no numbers allowed. If we were going to write the list items out here, we’d do it inside the square brackets like

public string[“Hey man”, “Oh hey, do you mind using gender neutral term pls?”, “Yeah no problem, my human friend”] textTextItems;

but you can see why this is just going to be annoying and difficult to change around later if we want the characters to say something else. leaving the arrays empty in the script also means that you can reuse them! If you want to add conversation into a different scene later, just copy-paste! You’re set for life, almost.

Now that we have all these different elements, we need to add them all together so that they do the job we want them to. We’ve told it what we want to say, but we haven’t asked it to actually do anything. Our code right now is like a sentence full of nouns, and no verbs. Everything’s just there, not doing anything at all. We need to create a function – the verb of our script.

9

I’ve done two things here. Above Start, under everything we’ve written so far, I’ve created a new function called SetText. It’s currently empty, apart from a comment to remind myself what it does. Just creating a function won’t make things happen though. You have to “call” the function. You can see how to do this inside void Start, above. We’re creating a function called SetText, and we’re telling the computer “do this at the start of the game”.

We can’t leave the function empty though, or we’re telling it to do nothing. Inside the SetText function, I’ve added the following:

11.png

If you remember waaay back to the beginning of time, the first thing we did was create textText.text and nameText.text. Now we’re actually setting them. We’re taking the text, and we’re saying “this needs to equal the nth item in our array, defined by the integer we called progress earlier”.

So if we have an array textTextItems[“Cheese”, “Ham”, “Avocado”], and our progress is 0, then it will make the text equal to “Cheese”. If progress is 1, then it will show “Ham”. It’s worth noting here that computers think 0 is a number, so the first item in an array is 0, the second item is 1, the third is 2 and so on…

The last thing we need to do, is make a way for the integer “progress” to, well, progress. It’s just going to be stuck on 0 forever unless we tell it to change. We already set out in the bullet points that we want to change the text when the player presses the space bar. Let’s crack on.

12

Inside the Update function that has been there, ignored from the time of creation, I’ve added an if statement. In human speak, it says “If the player presses space key, increase progress by one and then call the function SetText.” It looks confusing on the screen, but it’s very simple once you know that if statements are always set out the same way:

if(this thing happens) {do this, please}


But Bruce, how do you know that’s what it says?

There’s lots of documentation about this stuff. For example, you can find how to correctly write GetKeyDown (“is a keyboard key being pressed”) in the official documentation here. If you don’t want to use the Space bar, you can use KeyCode.A or KeyCode.Z or whichever key you like. Alternatively, you could add a “Next” button, for which you don’t use Input.GetKeyDown().

progress++ is just a shorter way of saying “progress = progress +1”. If progress was 0 before, then it will become 1. Every time the space bar is pressed, the number value of progress will increase by 1, thus allowing us to change the text. We then have to call our function SetText straight afterwards, in order to refresh what we see in the text boxes.


Finishing the job in Unity

Your script is done! That’s it! Save it (ctrl/cmd+S) and press play on your game to check if you’re getting any errors in the console. If you have something that sounds a bit like “there’s something called y but then it’s never called or referenced” then you’ve probably misspelt something somewhere. Go back over it very carefully, and remember to always use the exact same name when referring to variables. That includes upper and lower case.

But hang on, we’ve just written this script, and nothing’s changing. You’ve pressed play, but no matter how many times you press the space bar, it hasn’t changed. This is because we haven’t told it what the textbox should say yet – we left the arrays empty. Luckily, we made them public, which means we can now see them in the Inspector. Click on whichever object in the hierarchy you added the script to. Inside that, you will see that things have changed. There’s now a bunch of boxes in the TextText:

17

When we made textText.text and nameText.text, the top two here are what was created. We now need to tell Unity which text boxes we mean. This is super easy, we just need to drag the right text boxes from the hierarchy and drop them inside! Now Unity knows where to put the text on your canvas.

Underneath that, we have the two arrays we created. Click on the arrow to open up the drowdown, and you will see size = 0. The size is how many different pieces of text you want to show. When you enter a number, it creates that many text fields for you to write in.

19

You’ll want your size for both the name and the conversation text fields to be the same, and then you can create a conversation like I have here. Charlie says “Yo, what’s up?”, to which Timothy replies “The sky”, and Charlie says “Lol”. In-game, it looks like this:

20

Or maybe it doesn’t for you, since the default camera background is a blueish colour. You can change this to whatever you like by selecting Camera in the hierarchy and looking in the Inspector. You’ll be wanting to add a background later though, so this isn’t important.


I can play through, but when I’m done I get this error in console!

21

No worries! Remember that progress counter we made? Every time you press the space bar, that’s going to increase by one. So if your array size is 5 and you reach the fifth piece of text, the next time you press space bar it will increase to 6. The script will try to play the sifth piece of text, but there isn’t one. This won’t affect functionality of this part of you game, but I’ll go over how to trigger something different when you reach the end of your text another time because this is one looooong post.


Phew!

That’s it. This has been a much longer post than I had imagined, but as I was going along I realised that there were more and more things that a beginner wouldn’t know. I hope that this has been a good introduction, and I have tried to balance it so that you see not only how to write a script, but how to make it act on things that are actually in your game. If there’s anything you feel I haven’t explained adequately then feel free to comment or email me via the Contact Bruce page!

I’ll be writing up another post on how to add a character image to the game, and we’ll be adjusting our script so that we can change that character image to show who’s speaking. Very exciting stuff!

 

 

 

 

1 thought on “Making Conversations in Unity for Super Beginners”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.