Triggering change scene in our Unity conversation

Making and ordering scenes in Unity

One of the first things you should do in any game (in my opinion) is make a start menu. This means that at any time, so long as you have a win and lose condition that lead back there, you will always have something that’s exportable and playable.

I make my menu as it’s own scene. In fact, I make everything as their own scenes. It’s not the only way to do it, I’m sure, but I like having the flexibility to move parts of the game around and keep things separated.

Screen Shot 2018-07-20 at 11.44.59

Start off my creating a new scene and naming it Menu. Save it, and then you’ll need to drag it into the Scenes folder that gets automatically created with your project (in the box at the bottom of your Unity application)

If you get confused and you’re not sure which scene you’re in, you can always see it in the top bar, like below:

Screen Shot 2018-07-20 at 11.45.58

What I did when making the menu scene was copy-paste the contents of my main scene into the new scene, then delete down until I had the canvas and eventsystem left (you need this so that your button clicks will actually do things like start the game). Doing this meant that I wouldn’t get a different screen size for the menu and the game.

Our overall goal is to have a button or game condition that changes the scene to a new one. This way you can click ‘start’ and go to your conversation scene, and once there you can make it so that it automatically loads the next scene once you get to the end of your conversation (or have choice buttons that lead to different scenes – does your character pick up the magical glowing orb of doom, or ask out the bishie Haru-kun?).

I’ll go through the process of actually making those buttons in a sec, but first you need to understand how to order your scenes in the Build Settings so that the button script we write will work. The script I use to move to the next scene will always load the scene with the next highest number, ie if you’re on scene 1, scene 2 will load next unless you specify a particular one to show. This might get difficult to manage if you have a ginormous game with millions of choices to make, so there’s probably a way of putting all your scene loaders in one script (“if I’m in scene1 and press this button, then load scene5” etc) but I haven’t had the time to research this yet. I have such plans for my own game in the future, so let me know if you’ve done something similar and want to share. I’ll be checking my emails weekly from now on.

Ok, so once you have your scenes made (even if they’re empty right now), they won’t be available in your exported game until you’ve added them to your Build Settings. Once you have a couple of scenes, you need to tell Unity which scenes/levels you want in the game, and which order they should be played in.

To do this, go to File->Build Settings…

Screen Shot 2018-07-26 at 11.12.39

When you first open the Build Settings, it should only contain the Sample Scene that comes with every new project. You can remove this by right clicking on it and choosing Remove Selection. To add new scenes, simply drag and drop them from your assets folder into the Scenes In Build box screenshotted above. You’ll want your menu to be item 0, as this will mean it loads first every time you load the game. If you had a pre-menu cut scene like Age of Empires II then you’d put that as 0 instead (and hopefully add a ‘skip cutscene’ keypress that takes you to Scene 1). Remember: computers count 0 as the first number, so any time you make arrays (lists of values, eg numbers or words) then the first item in that list will be number 0, not number 1.

You don’t need to click any of the build/run buttons once you’ve ordered your scene, since you’re not ready to export your game anywhere. Simply exit using the x in the corner, and it will remember what you did no worries.

To the far right of each scene you can see the scene number. This will be useful to us when writing the script that takes us from scene to scene, so make sure that you have all your levels in the correct order. With the method I’m about to explain, they will load in the order 0, 1, 2, 3… Unless you specify a particular scene number to jump to.

If you try to jump to a scene you haven’t added, you’ll get the following error:

Screen Shot 2018-07-26 at 10.28.48

Button creation in Unity

Going back to our menu scene, we need to create the Button object next. We can do this by right clicking in our Hierarchy and selecting UI->Button.

Screen Shot 2018-07-26 at 10.55.00

A button will now appear in your canvas, which you can place wherever you’d like. This is a guide in build, not overall design. If you’re interested in design then this article by Akhil Dakinedi seems like a good place to start looking into planning the look of your game’s UI and start menu.

In the Inspector area, you can change colour etc to match the theme of your game, or you can add an image behind the button (make sure it is behind in the hierarchy, otherwise your button will become unclickable because the image is in the way). You will also see a component called Button (script), and at the bottom of that component is this:

Screen Shot 2018-07-26 at 10.56.34

This is the box that decides what happens when the user clicks on the button. It may seem redundant since the component is already on the right button, but you need to tell Unity which button you really mean. At the moment nothing happens when you click a button, and it doesn’t know which button you want to click on anyway. Click the + button to add to the list, then drag your button from the Hierarchy on the left of your screen into the empty Object box:

Screen Shot 2018-07-26 at 11.20.04.png

Now you can see a coloured cube and your Button in the object area. Next up, take a look at the function dropdown menu (where you currently see the words “No Function” and see a whole bunch of functions. Unfortunately, we can’t select the one we want yet because we haven’t made it. But this is where all your functions will live, so you can make whatever you like and add it in here. What we need is a start button script. At the bottom of the Inspector, click on Add Component and make a new script. I called mine StartButton.

If you want to go straight to the code, I have uploaded the Start Button gist for anyone to see. I will also go through it below.

The first thing to do is to add using UnityEngine.SceneManagement;” to the top of the script. This allows us to use SceneManagement keywords and presets. You can ignore void start and void update, because you want to create your own function:

Screen Shot 2018-07-26 at 10.52.37

I’ve called this TaskOnClick, since that’s what it is. Inside, the first line is simply to help with debugging if I go into the game and clicking the button doesn’t work. If I see “You clicked” in the console log, then I know that the button has clicked successfully and the problem is with what comes after. If I click and this message doesn’t show, then I know the problem is that the button doesn’t know it’s being clicked on. This would probably happen if I put something in front of the button, such as an image or text box, even if it’s not actually visible in the game.

The second line of code is a really long winded way of saying “find which scene we’re currently on, and put the scene number into a variable called levelLoad”. The script will find that we’re on scene 0, and so the value of levelLoad will be 0. In the next line, we tell it to load the scene whose number is our current scene number plus 1, aka number 1. Therefore, the script says “tell the console that a click was registered, then work out what level we’re on and load the next one”. If you wanted to make this load a particular scene instead of the next one in the order, you can change the last line to read

Application.LoadLevel(n);

where n is the scene number you want to come next. This is also useful for when you want to make decisions in your scene. You an reuse this piece of code in your text scenes so that you have two buttons, eg [EAT THE CAKE] [DON’T EAT THE CAKE]. If you click the first button, it takes you to scene 4 but if you choose not to eat the cake, you go to scene 16 instead by reusing the code for each button and simply changing the number inthe LoadLevel(n).

That’s it! Save and exit.

Now all that’s left to do is to add this function to our button. Back in Unity, if you go back to the function list we were looking at earlier, you will see that the StartButton script is listed as a source for functions. Select that one, and amongst a bunch of standard functions, you will find your TaskOnClick:

Screen Shot 2018-07-26 at 11.19.16

Select that, and we’re all done! Now, so long as your starting scene is one number up from your menu scene number (in our Build Settings menu), you can start the game by clicking the button!

Our code for changing from text scene to others

The next thing we want to do, is to make it so that coming to the end of your conversation will load the next scene in your game. We used this mechanic in our game-jam game so that coming to the end of the first cut scene conversation automatically begins the shooter level of the game. If you like, you could manage everything entirely with buttons instead.

Going back to our original ConversationManager script, we just need to change our code in one place like so:

Screen Shot 2018-07-26 at 10.29.03

I’ve added an if statement, whereas before it always progressed the conversation number and then ran the SetText() function. The if statement checks if a parameter is true, and if it is then it runs the code inside the curly brackets. If the parameter isn’t true, then it jumps to the else statement and runs the code inside there instead.

So what does our if statement do? Let’s look at the parameter first – that’s the condition we placed inside (here).

if (progress == textItems.length) {then do this thing};

We’re basically saying “if the value we called progress, ie which numbered piece of text is showing, is the same as the total number of text items we have to show, then run this bit of code”. So if we have 5 pieces of text in our array textTextItems and we just progressed to number 5, then instead of running SetText() we load a new level instead.

At first glance, you might think – won’t that skip my last piece of text every time? If I’ve got five pieces of text and it never loads number 5, then surely it will miss out the fifth one? Well, nope. Remember that the computer counts from 0, so even though you have five items in your array, they are numbered 0,1,2,3,4. Therefore, number 5 is fine to skip to the next scene!


Yo Bruce, what does the ‘==’ mean? Why not just ‘=’?

This is simple once you know it. When you use ‘=’, you are assigning a property. By saying x = 5, you’re telling the computer that it’s true. You’re not asking it to check anything, you’re just dictating reality. That’s how it is now, Mr Computer, like it or lump it. When you use ‘==’, you’re asking the computer if it’s true. Typing x == 5 will return a value of true or false, depending on whether or not you’ve already told it that x = 5. In our example, “progress == array length” will return false if the condition isn’t met, telling the computer to go to the else statement. If it is true, then it looks inside the if statement and runs that.

Basically, ‘=’ is for assigning, and ‘==’ is for comparing.


Something else you could do, which I haven’t tried myself, is to make a button appear saying “Continue to next scene” or “start bullet hell” (or choose whether or not to eat that cake). This seems in principle to be quite simple, according to the ‘Best Answer’ on this forum post. You’d have your button in the scene, and in the above script instead of having your “int LevelLoad” lines in the curly brackets of the if statement, you’d add the line

continueButton.SetActive(true);

Then you reuse the code from our startButton to load the next scene. I’ll probably have a look at this on the weekend and make an update post about it next week if it works ok.

That’s about it for this one, I’ll be posting more stuff every week, on various topics (mostly software testing though). If you want me to expand on this in any way, then let me know!

 

 

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 )

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.