Learn Unity 3D and C# By Making Games | Rusty Smith | Skillshare

Learn Unity 3D and C# By Making Games

Rusty Smith, Learn Unity 3D by Making Games

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
10 Lessons (4h 11m)
    • 1. Learn Unity By Making Games - Preview

      1:08
    • 2. Variables And Methods in C#

      7:05
    • 3. Classes and Namespaces in C#

      6:02
    • 4. Installing Unity and Visual Studio

      1:17
    • 5. Unity Introduction

      10:34
    • 6. Player Creation and Control

      39:04
    • 7. Camera and Game Over

      34:05
    • 8. Block Generation

      49:50
    • 9. UI Creation

      46:11
    • 10. Final Game Polish

      55:47
113 students are watching this class

About This Class

Welcome to Learning Unity and C# By Making Games.

This is the first of a 4+ part series where you will learn Unity and C# by making games.

You will learn to create a full game in each course with custom art assets included with each course.

Download the Starter Asset Package from the Class Project Panel upon starting.

Join the Course Discord discussion group at https://discord.gg/9WYC2sQ to discuss anything related to the course with other students and the teacher.

Transcripts

1. Learn Unity By Making Games - Preview: welcome toe Learning Unity 2017 by making games. My name is Rusty Smith, and I am a unity asset producer and game developer based out of San Diego, California This is the first of a four plus part Siri's, where you will learn unity and C sharp by making games. Over the course of this series, you'll be introduced to creating two D and three D games over a variety of genres. In part one of this series, you will learn to program in C Sharp, learn about using and navigating in unity and create your first game. You will be introduced to creating a game from the ground up, including programming concepts, best practices and training on debugging code within unity. This course provides custom art assets for you to create a full two D game, including animation, audio player collision and designing a user interface. You're provided with code samples every step of the way for help if you need it. And in addition to code samples at the end of each video, there is a custom discord channel for all students to get suggestions, discuss new ideas or get help from the teacher or your peers 2. Variables And Methods in C#: Hello, everyone in this chapter, we're going to be going over variables and methods within C Sharp. First, let's start with variables. Variables could be declared within a class or a method and be given a name you can use to reference it in other places. And C sharp variables have to be explicitly declared using a type declaration in front of the name for the variable. When declaring the variable, you will put the type declaration in front, followed by the name for the variable. If you are giving the variable a default or starting value, you'll put an equal sign followed by the value than a semi colon, a semi colon and C sharp is used to represent the end of a line of code. Int is used for inter values or whole number values. Float is used to represent floating point numbers and his best to be used for values that will not always be a whole number. Float values must also always have an F on the end to declare them as a float type. Variable bull is used to declare a true false variable. You can only assign a bull as either true or false these air best used for simple logic gates or logic checks. String is used to declare and store a string of characters or text. When declaring a string value, it must be encapsulated in quotation marks. Quotation marks are what notifies the compiler that the word or words that are written or a string of text rather than other variables for it to fetch. One of the other frequently used things that you will see in code is code following to forward slashes. These air used to start a line of comment. Text. We will use this to comment our code with notes to improve readability as well as write notes toe ourselves of unfinished things with within methods or classes. Anything followed by these two forward lines will show Oppa's green in your editor and will be ignored by the compiler. It is the best practice to comment your code to describe or explain any bit of code that maybe convoluted and may be hard for another programmer to instantly understand. Methods are used to story list of actions to be referenced within a class. Avoid methods are a function that is called runs the code within the method and has no value returned from it. To write a new void method, you will first write void, followed by the name you want for the method followed by parentheses. It is important that you use names for your methods that a representative of what the method does or how it is called, say we have a method called attack. In this method, it will play an animation for the attack, then apply a 10 damage to all enemies within five range. If we have a zombie survival game that we're making, both the player and the zombies will have an attack that they use one of the things you will want to try to avoid. His code repetition. Any repetition there is means if you want to make changes to the code, you will have to remember to update it for all copies of the code. For example, say we wanted to add a sound effect to our attack for both are zombies and our players. Instead of going through an updating all of our classes with our new changes for the attack , we could have both player and zombie referenced the attack method. By doing this, we will only need to worry about making changes in one place with methods. You can also declare method parameters for variables or objects to be passed to the method itself. In our case, our zombie and player may have a different attack, damages or attack ranges. Instead of having a static value for each of these, we can declare an attack. Damage an attack range variable. To declare method parameters. You have to give the variable type as well as the name for the variable. So in our case it will be int attack Damage comma into attack range to separate a list of variables. In a method definition, you will use a common between each variable. Since we're now passing an attack, damage and attack range value to the attack method. We will now call Attack, followed by the values for attack, damage and attack range for both player and zombie. When passing in values, you can pass in values directly or passing. Declared that variables you'll see here for the player attack. We will pass that the player attack damage when the player attacks. It would read the current value of the player attack, damage variable and do that amount for this case, it would be five. The other commonly used method type is what is called a return method. A return method will run a set of commands or checks and then return a value afterwards. Say we have a player who has the ability to jump. We, of course, wouldn't have a player that could jump forever. So we will want to check to make sure the player can jump before we run any jump command. First thing with the return with it is instead of writing void, we're going to be writing the variable type that will be returned by the method itself. In our case, we will be returning a true false value on whether the player can jump. So we will write. Bull can jump. All return methods must have a variable returned as well. In our case, we'd have say a player can jump value that we would modify to false after doing a check to see if the player is already jumping in the air to recap. Variables are a name that we can use to reference data. They must have a type specified upon creation, and their values can be modified during runtime variables can be created and used in both classes and methods themselves. Any variable declared within a class could be referenced in any method within that class. The variables declared within a method are not accessible outside of the method unless they're returned out of it. Methods can be created as either a void method or a return method. Both of them will run a list of commands. But return methods will return a value after running the code from within the method. That's going to be it for this lesson and our next lesson. We're going to be learning about classes and name spaces, and then we're going to begin creating our first game. 3. Classes and Namespaces in C#: Hello, everyone. In this lesson, we're now going to go over classes and name spaces. Classes are used to organize sets of variables and methods that all share something in common. It is recommended to name your classes in a way that an outsider could understand what type of code they will find within the class itself. When writing a new class, you'll write class followed by the class name and then opening and closing brackets. Everything within the opening and closing brackets within the class will be contained within it. There are two commonly used class structures when it comes to writing and or organizing your code, the first of which is class inheritance. Imagine we haven't enemy class containing the methods that all different enemies have in common. In our case, they all attack, and they're all able to be damaged, similar to method referencing with the attack method. Example. Instead of rewriting code between every different enemy type we have, we get simply have each one of those classes inherit the enemy class. When the dragon and zombie class inherit the enemy class, they will inherit all of the methods and variables declared within the enemy class because dragons fly and zombies do not. We can add just the methods in variables that are unique to each without having to rewrite the common methods between them. When creating a new class to have it inherit from another class, you use a colon, followed by the name of the class you were inheriting from. Having a strict inheritance structure rather than a composition class structure can lead to a lot of edge cases, causing issues further down the line. For this reason, well, primarily use a composition class structure in this course, instead of focusing on a strict inheritance structure, will focus on creating a set of very generic component classes, all focusing on one specific thing. So instead of having an enemy class, we could have an attack. Take damage, walk, fly, run and talk classes that can all be inherited individually by other classes, which will use those components. For example, if we have to separate enemy types in our game dragons and zombies, the Dragon class will be inheriting the attack class because it attacks the take damage class because it is the unit that can receive damage and the fly class because it is a unit that flies the zombie, on the other hand, will inherit the attack, take damage and walk classes. When a class inherits from another class, it will inherit all declared variables and with its from within that class. By default, all classes, methods and variables are considered private unless explicitly declared as public. Anything that is private can only be accessed by other things encapsulated in the same parent. For example, if you had a zombie class with two methods attack and set target. But leaving the attack method is private. Any class that inherited or reference to the zombie class would not see the attack method as an available method due to it only being accessible from within the zombie class. The same accessibility applies to variables that air declared within a class or name space as well. It is important to only expose variables and methods as public when they're required to be accessible from outside the class itself. By only exposing required variables or methods outside of the class, it will ensure that internally used dynamic variables aren't accidentally manually set by mistake. Having a clean code structure will help the right better code and revisit code with less time re familiarizing yourself with what you had written. The last thing we're going to cover in this lesson is going to be named Spaces Name Spaces Air used to organize a set of common classes. Name spaces Air Not mandatory at all, but they do allow you to use more generic class names without fear of having conflicts in your project. If you end up using other assets from the Unity Assets Store, we're riding existing code to your project. You can use name spaces to prevent two classes from having the same name causing issues in your project when defining a name space your right name space followed by the name of the name specie. Want, followed by opening and closing brackets that will go around the name of the class or classes you're putting in the name space. Two acts of it. To access a name space, you will have to use what is called a using directive. The using directive is simply a list of all of the names spaces that a given class or application will be using frequently. This will save you from specifying a fully qualified name every time a method from that name. Spaces called, for example, if we wanted to make a reference to the zombie class found within the coffee enemies name space. We can reference it by using its full name, coffee enemy, Stott Zombie. Or, if we're going to be accessing many methods and glasses from within the coffee enemies name space, we can add using coffee enemies semi colon to the top of our class, then access the zombie class merely by using the class name as the name space is already referenced. This is just a quick first glance at some of the larger concepts will be covering in this course. I do not feel the need to memorize your master all of this just yet, as we will go over everything more in detail and in further lessons. 4. Installing Unity and Visual Studio: the first thing we're going to want to download and install is going to be unity from unity three d dot com From the home page, you can click, get Unity and select the personal edition. Once unity has been downloaded, go ahead and run the installer. When installing, select the additional build choices that you plan to build for. Ensure that the standard assets is also checked, as we will use those in further projects. Once Unity has finished downloading and installing go ahead and start installing Visual Studio 2017. This is the program we're going to use as our script editor and the program that will be writing all of our code in. You can use other programs if you prefer them, but all videos will be from the from within visual studio, so it will be easiest to follow along if you're a newer if you're using visual studio as well. When installing Visual Studio 2017 you'll want to click modify and ensure you select the unity. Adan's as well as this will give you guidance and tips. While you're writing your coat from within visual studio, you can click tools options and adjust the color layout to your liking. 5. Unity Introduction: upon opening up unity for the first time, you'll see a project selection box. We're going to click new and create a new project, since our first project is going to be a two D project going to select the two D box Selecting two D or three D only sets the default camera view in your project to the selected dimensions. The first game we're going to make is going to be a variation on Flappy Bird, so we're going to name it Flappy Firefly. Feel free to use any name you would like for years if you want. When selecting a location for unity projects, I recommend a spare storage drive or a spare location you can easily navigate to once you selected a location for where you'll be placing your project and naming it. Go ahead and press create project. All right, so when you load up unity for the first time, you will notice a lot of windows. The six main components that you're going to be using immunity are going to be the hierarchy seen game Inspector Project and council. Each one of these windows here can be moved to a location of your choice And once we go ahead and move these in our case, I'm gonna move the hierarchy down here. We're going to go ahead and split up the scene and game views and ensure we separate the project and constantly use as well. Once you have, ah, layout that you do, I prefer, then you can go ahead and click up here where it says default and you can click, Save layout and this will be whatever you want to name it. In my case, it's going to be, Ah, new default. I'll go ahead and save this layout. Each one of the windows here, you'll notice, will have a different function. The scene itself is going to show all of the game assets that air currently loaded into the scene itself from the hierarchy is where you can actually get a drop down selection of all the different things that are within your scene. The hierarchy here is where you can control and select all of the different assets that are in the scene. If we right click on a empty area of the hierarchy over here, we can go ahead and select a to D object and let's go ahead and select a sprite just so you can see what this looks like on the scene itself and, um, within the hierarchy. So in our case, the Sprite doesn't actually have anything on it yet. So in the scene, you're just going to see this, um, tiny dot showing the size of the spread itself on the inspector Here is where you can see all of the classes that are attached to each, um, object within your game. So when we select the new Sprite object, we're going to see the transform that comes on every single unity object that our game object that is going to be in your seen. It will always have a transform. And then, in this case, because we loaded a sprite, it's gonna have a sprite render. If we select this little circle here, we can go ahead and just select one of the default stripes that Aaron there. For now, we're just gonna go ahead and select this knobs right, which now you can see this on your game view as well. So the game view is going to show you whatever can be seen from your main camera within your game. So in our case, it is this main camera. So if we move this main camera around, you'll see the object move around in the game view. But it will not be moving around in the scene view because the object is not actually moving at all. So a mere we're just gonna go and reset it back to cereal. The project portion will show you all of the assets that are currently within your assets folder of your game. So when you are importing new assets into your project, they will go into this Assets folder, and we're going to go over my recommendations for how to organize your assets folder To make things easier to use as your projects start to get larger and larger and last but not least, the council window is what will be used whenever you have either warnings, errors or debug code that is written to the council. You can use this to help you debug features or how to check features while their works in progress. So the first thing we're gonna want to do now is see if we can just get something written to the council. So before we go any further. Let's just go ahead and right click here on the assets folder itself when we're gonna go ahead and click, create and we're going to create a new C sharp script. And we're just gonna name this console test. Once you've created this script, before you open up anything you're gonna want to go up here to where it says edit and under preferences here in the preferences menu, you're going to be able to select which, um, which script editor you're going to be using for your programming by default is gonna be set to mono develop. In our case, I'm gonna recommend Visual Studio 2017. And that's the one we've downloaded. And go ahead and select Visual Studio 2017 and then check the box for editor attaching if it's not already checked, the other features in here will allow you to change some of the colors for default things within the system. And you can also set some, um, key commands. Have you choose to use them in this Siri's? I'm most likely just going to be using, um, the mouse for everything just because it's easier to track and follow and you don't have to rely on memorizing any of the hockey commands. One of the other features were going to be using is that you're gonna want to set up is the G I cash. So this is going to cash your assets and files for use within the editor, Um, so it's going to keep them pretty loaded in to memory to be access so you can stream things faster when you're actually running the the your game through the editor itself. So go ahead and set this to a location that you have a lot of space. If you have, like a storage drive, I recommend changing it to that and then setting the cash size to whatever you feel comfortable with. In my case, it's at 20 gigs, and my cash is going on six gigs. But this is after a year, so of project, so it doesn't feel it too quickly. Under two D, you're going to have a Sprite atlas cash as well. Go ahead and set that to a size that you feel comfortable with as well, and then you can go ahead and close out of preferences menu. Once you've set your script editor to visual Studio 2017. If you just go ahead and double click on this script here that we see down below, it will open in visual Studio 2017 from already within your project. From here, you're going to notice a few windows. The first main window is going to just be the actual script that is selected. And then the solution Explorer will show you the folders of all your script that are within your project. So these folders are gonna look similar to what you see within unity, but you won't necessarily see all of the non script assets in here as well. The properties window will show you the specific properties for a given for a selected, um, object for this were most like they're not really going to be using this very much. This is more so for, um, editing different projects or standalone projects outside of unity. All right, so now that we've opened up the consul test script, you're going to notice a few things. First thing you'll notice is that by default, you're going to see these two methods already created in here. The void start and the void update by default and unity. Anything that inherits from the model behavior class. Uh, if it has a start method, this will be called immediately as the scene has started. And then the update is going to be called once per frame. So we're gonna go ahead and delete the update method for this test and then under void start, we're going to go ahead and write. Um, we're gonna go ahead and write debug dot log, and we're gonna right the parentheses and then in quotation marks were going to write consul tests and then make sure we end our line of code with a semi colon in C sharp. Any line of code has always ended with a semicolon. Once this is done, we're just going to go at it. Control s to save our script. And then from here, we can go ahead and go back into our scene. Okay, Now that we've opened up unity again, we're going to go ahead and click on our new sprite that we created from before. We're going to select this consul test, a script that we just created, and we're gonna drag and drop it on to our new Sprite. And once this has been dropped on. We're going to go ahead and it control us to save the scene for you. It's going toe prompt you to save your scene. At this point, I've already done it. I went ahead and named Main scene for this test. Go ahead and name it. And then once this has been attached and saved, we're going to go ahead and go up here to the play button when we're going to go in and hit play. And the only thing you should see is down here in the console window. You're going to see where it says Consul test. So this is gonna be our first line of code. And then from here, we're actually going to start creating our first game and importing our first assets and unity. 6. Player Creation and Control: Hello, everyone. For this lesson, we're going to import our first unity package and asset package into our brand new Flappy Firefly project. For this one, I have provided a flappy Firefly Starter pack. This is going to include the art assets that were going to be using because in this tutorial, I won't be going over, um, creating specific art assets because I'm not much of an artist myself, So I'm not the best person to be teaching it to anybody. So with the asset that you have downloaded, go ahead and just double click on it. You should see it prompt with a import window within unity itself. Just go ahead and click import, and it's gonna import all of the files from within that package into your project. You'll notice an audio folder with a variety of sounds, a Scripts folder with a Helpers folder that has a few scripts in it that will get into a bit later. And then you'll see a textures holder as well, which is going to include our Sprite atlas with all of the art assets that will be using this project as well as some extras. And in the next step, we will begin actually creating our firefly and getting him to move. All right, Now that we've imported the asset package into your project, you can go ahead and click. What's his new sprite? Over here. You're going to see the Consul test script here. We're gonna go ahead and click this little gear next to the Consul Test script, and you're going to go ahead and click. What says remove component. Once that's been removed, you can go ahead and right click on the Consul Test script and go ahead and click the delete key on that. Once that's been deleted, we're going to go ahead and take this new Sprite here, and we're going to turn this into our player. So by double clicking or clicking on the object itself, you can go ahead and rename it to player. You can also rename the name of the object from within the inspector itself. So now that we've renamed this two player, we're also going to give this a, um, a new sprite right now. So we're gonna go ahead and click the little circle again, and you should see a pre flap her firefly, um, Sprite that you can go and select within your project. Go ahead and select that for the player. Object itself right now. You should see that on your screen on the camera. Right now, The, um, Firefly will be very small for the main camera here. We're gonna go ahead and set the size on this to 1.55 and then under the clipping claims we're gonna go and changes the negative 10. We're going to be using this more later. But let's just go ahead and change it now to get it out of the way for the background color here. We're also going to If you just click on the blue area, it will bring up a color selection. Bucks. Let's go ahead and drag it down. We're going to go and set this to Black for now. Go ahead and close this out. Once that's been selected from here, you should just be seeing the Firefly on a black background from here. Now we're going to go ahead and go to the scripts folder and we're going to create our player script. So if you right click on the scripts folder and go to create, you should see C sharp script. Can you go ahead and name the script player, Go at it, entered a created and then double click on it. And you will be able to open up visual Studio 2017 from here again since the cigarettes for Monta behavior. Gonna see those start and update methods already in your script. If you go ahead and move these down before we start on anything, we're going to go ahead and declare the variables that we're going to be using for the player class starting above. So since we have the, um, Firefly that we're planning to move across the screen, that's going to be moving throughout the world, we're going to go ahead and give the player a velocity, which is going to be used to measure how fast the Firefly is moving either up or down for now. When we first declared, let's go ahead and set it equal to vector 3.0, which is basically saying we're giving it a velocity of zero and then we're going to create a public Sector three and this is going to be for gravity. So for this we can leave this sunset for now, to seize a semicolon again to, um, and the line of code. This will allow us to adjust the amount of gravity that we apply to the firefly. If you want to make your game, if you want to make it toward the firefly falls faster or slower. You can adjust that here. We're gonna go ahead and have a value to determine if the player clicked the mouse or clicked on the screen in order to have the Firefly flap its wings in order to make it go up . So we're gonna have a bull did flap. I'm gonna go and set this to False by Defoe. We're gonna have another public Sector three. This is gonna be flat velocity and we're going to just leave the sunset for now. This will be how much forces applied to the Firefly itself when the player does actually click on them in order to get them to flap their wings. And then we're going to have a value for Max speed and forward speed. So let's go ahead and do a public float Max speed and we'll go ahead and we'll set this to five for now. Remember, for your float values. You need to have them end with an F to ensure that its declared as they float value. And then we'll have a public float forward speed and then we'll set this toe one. So by default, the fireflies always going to be moving, Um, one unit forward, and then the flat velocity is just going to add upwards velocity to the character which will insure that you get that classic arc that you see in Flappy Bird. So now that we've created thes variables up top that we're going to be using, you can go ahead and hit control s again to save this. And then for now, we are just going to a just a couple methods. So under this update function, we are going to create our first, um if logic eight, which So we're going to write if and then parentheses. We're going to write the, um basically, the logic check to determine if the code that's going to be within the brackets after the if is actually going to be ran. So in our case, we're going to be checking for input dot get mouse button and we're gonna get in about Spartan zero which is gonna be the left mouse. This also includes the single touch on a android or IOS device. And then after we have this in quotes, make sure we put the whole thing in parentheses. Then you're going to use brackets to close the statement. So this is going to check if we have pushed down. Um, sorry, it is going to get but mouse button down. This is going to check. If we pushed down during this specific frame, this is going to check if we pushed down on the screen, which will make the, um, firefight flap. So if we did push the mouse button down, we're gonna go ahead and do did flap equals true. So for this right now, it's not actually going to do anything yet. But from here, what we can dio is what we're going to want to be doing is in unity. There is a specific order that everything actually runs in within the scene. So when we pull up this image right now, all right, before we get going any further on this, let's go ahead and pull up a quick overview of the execution order of events in unity So this will be something that you can reference. I'm going to include a link to it that you can reference for when you start building more complex projects. That gives you an exact order of everything that is being loaded within your scene and within your project. So you'll notice here under this lifecycle flow chart that the first thing that is going to get called on every single object is awake. So awake is where you're going to be placing any initial initialization that needs to be put on any object within your scene or anything that needs to be set up before everything else can run. And then after awake on enable will be, um called, um, any on enable functions for any object that is enabled within the scene itself. On enable will be called, um, when you first start the scene and then start will be called, um after both of those, the ones that we are most interested in are going to be in regards to the fixed update versus update. So update is the one that is used by default, and that's going to run every frame. But there is also another one called fixed update, which is run on every single physics check within your game. So because depending on which device a game is being run on, the amount of frames per second that the game will be running on will vary. You want to ensure that anything involving any amount of physics or movement is always going to be handled during the fixed update, because if you have it running during update, then you'll be getting inconsistent results. So if someone's running your game on a computer and they're getting 200 FPs versus someone who is running it on their phone and they're getting 50 FPs than the person who's on the computer, everything is gonna be moving much faster for them because it's going to be checking during the update check rather than the fixed update by running things during fixed update. It's going to happen during every single physics tick that happens during the game, and then, um, after those, it's just going to go through all the other ones. For now, we're not gonna really go over them any further, but feel free to read through them if you want. If not, we'll cover them or later has become across them within our project. So given this information that we now have, what we're going to want to check for now is during Thea Update, we're gonna leave it here. Um, we still want to be checking for inputs. Uhm during every frame just to ensure that there is a minimal amount of latent see between when the player hits a button and when they're actually seeing in action coming out of character. So when it comes to actually moving our character, though, we again want this to be handled during the fixed update. So we're going to do avoid fixed update, and it's going to go ahead and automatically create itself out. So once you type two fixed update, if you do hit tab, it should auto complete the method for you, as you just saw do here on my screen. So for here, we're going to go ahead. And instead of including all the code that we're going to be using for moving the player, we're actually going to put it into a different method. But for now, we can just called the move player method. Go ahead and give a parentheses and put a semi colon here. From here, you're going to notice this red line underneath it. That basically means that the compiler is recognizing an error in some way. In this case, it's because the move player method hasn't been created yet. When you click show potential fixes, one of the options that will give you will be to create the method for it, and you can go ahead and click that or just manually type it in yourself. Let's go ahead and create it by default. It's gonna ample Throw are created with a default exception in there basically stating that it's not implemented yet. We can go ahead and delete this line of code for now. Let's just, um, clear out everything for now and then Let's have the move, player. What we're going to do just for our first test is we're going to set the, um, velocity dot exe equal to the forward speed, and the velocity is going to be, um, equal to velocity, plus the gravity. So another way that you can write this as well if you want to make your coat a little more more concise is you can write the velocity and you can write plus equals. So in C sharp, you can use these shorthanded iterations toe where if you write plus equals gravity, for example, this would be the same thing as writing velocity equals velocity plus gravity. So all this does is basically shorthand for saying you're adding this value to the original value and the same thing can be done with minus equals or, um, multiple equals or divides equals. So in our case, we're gonna go ahead, and we'll just leave it as the top one for now, just cause it's easier to read for the people who are newer to the C Sharp Syntex. So let's just go ahead and hit. Enter here and let's go ahead and go back to our project now. So back on our the main seen here, we're going to see our player object here. You're not gonna have the player script attached yet. Go ahead and again, Um, instead of dragging the player script this time, if you go ahead and click words this player, you can click over here where it's his at component. You can also just type player and you will see that script that we created go ahead and select that. So by default we're going to want to set the gravity to negative 0.5 And we're gonna slept the flat velocity to one and under the max speed, Let's go and change this to 1.5 and will set the forward speed point for All right. So if we were to just go ahead and click play right now, even though we have these gravity enabled on the player itself, you're not actually going to see the player actually move anywhere or go anywhere because it does not have a rigid body attached to it yet. So go ahead and stop words this play. We're gonna go ahead and click. Add component here and we're gonna add a rigid body to D. So what a rigid body does is it tells the physics engine from within unity that this is an object that you want to be affected by gravity itself. So under the body types, you'll have a few options here. Dynamic means that it's that it's affected by all physics objects within the scene and all physics within the scene. Kinnah Matic means that the object will only be moved by code itself. So this is good for objects that say you have, like, sliding blocks or moving parts within your scene that you want to be moving. Um, this will ensure that you know someone running into them won't move them or have them go flying away, but they will be able to move. However you code them to actually move using physics. So for this, we're going to go ahead and leave the mass at one linear drug is going to dampen the speed of the object. But while it's on the ground and then angular drag will damp in the speed of the object, well, it's in the air. So we want to ensure that we change the angrier grabbed 20 because otherwise it's going to have an impact on the player itself in regards to, um, how fast they're able to go and they'll be getting so done in the air. So under constraints, one of the things we're also gonna want to do is we're gonna want to freeze the rotation on the Z axis. This will just ensure that they don't start spinning in some way. Um, otherwise, this will be different than what we were actually gonna be doing is tilting the player itself in a different way instead of having it rotate with the physics that are being a blood to it. So was live This zero ensure we have the rotation set to, um, that we have it frozen on the Z axis and then that we have the mass at the one and the gravity scale. We're going to go ahead and set this. We'll leave it at one for now. And then as you click play, you'll notice immediately the player will drop out of the sky until they're gone. So if we said this scale to zero, you should not see them move it all. But we're gonna go ahead and leave it at one still, all right, so now, so we can actually see what's going on with our player. Let's go ahead and let's create a new object. We're gonna go ahead and create a new, um, to the object and we're gonna create a sprite. We're just gonna go ahead and call this sky. Let's go ahead and set this to position 1.25 and two. I believe the skill here. One. Go ahead and hit the little circle here again to bring up the image selection. And you are going to see the sky texture here. Go ahead and select that. And then the next thing we're gonna go ahead and do is we're going to create another two D object. And we're going to put this one. I will name this one ground, and we're going to select the ground texture. Yeah. So the ground we're gonna have this 10 negative coins. Negative 0.6, Onda one. Okay, Clear. Started zero and one, and then let's go ahead and go up here. We're gonna want to do, um for a game. We're going to go and design this to be 800 by 400 for this project. So we're going to go here where it's this file and build settings, and this is gonna pull up a new menu here, go and click. Add open. Seems so. This adds to seem to the build, and from here you will see a button. This is player settings. And under here, you're going Teoh. Just see the company name and the product. Name this for Mary against that the icon and cursor and such for the cursor itself or for the Icahn for the game, rather. And then you can go and close this Build sittings until now, we're gonna click resolution and presentation. Let's go ahead and change this to uncheck the box for default is native resolution. We're gonna set this to 800 by for 80 and then you're gonna inject the box for default asshole screen as well. We're just gonna go ahead and save these and you can uncheck the box for display resolution toe dialogue and you can just tell it to, um, be disabled. That's fine. Okay, once that's been done, appear, what's this free aspect? You can change it to stand alone. This will allow you to actually see the game. Um, based off of how you're going to I want it to actually be viewed or how it will actually look from within the game itself. Then under the camera here, let's go ahead and move the camera up slightly. We're gonna want to move this to about 0.95 and this will give us about the look that we're going to be aiming for in the final game from here, the sky and ground, even though we've created them. If you click play, you'll notice that the firefly is still just gonna fall right to the ground. That's because we haven't created any colliders for any of the objects yet. So colliders are what insurers that basically any objects with gliders will actually stop when they hit each other. So for the player object, we're going to go ahead, and we're going to give it a circle colliders to go and click at component on the player. Give it a circle collider if you look within the, um, seen window, if you use the mouse wheel to scroll in and out, you'll actually see the Circle Collider on the player itself. And that will show you the size of the actual Circle collider and what it actually looks like in comparison to the texture. If you want to scale this, um, based off of the size of the um Sprite itself by default, it's a 0.12 You can learn at the 0.10 if you want to make it slightly easier or allow some clipping from within the spread itself. Let's go ahead and just lower it. 2.1. Um, for our sake here. So for this crying ground textures, we're not actually going to be applying the colliders to them because we're going to actually be moving the sky and ground itself in order to get that parallax effect that you saw in the preview for the game itself. So let's go ahead and we're gonna make two objects here the first time. Let's go ahead and create a new empty and we're gonna name this, uh, ground collider And then if you actually one of the quick key commands you can actually use is going to be controlled de that will allow you to duplicate an object. Um, quickly. So what you can do is you can actually just, um, let's go ahead and create the you can just control de that will duplicate it. And for the 2nd 1 this is going to be this guy collider. So, for the ground collider, we're going Teoh, go ahead. We're gonna want this to be at the same level is the ground which is zero negative, 00.60 and then we're going to give this a box collider two d and the scale for this one. We're gonna want it to be much larger. So if you see here in the scene, view the this is just covering directly under the fireplace. So let's go ahead and let's scale this up to under the size here, you can actually change the size of just the box collider itself. This keeps the scale of the ground Clark to the same. So we're just gonna change the X value to 15. And let's change the y value 2.97 So the reason why we're gonna change the life value is we just want to give the player little bit of leeway in terms of where the ground texture actually ends versus where they actually collide, which will cause them to lose. So once this one has been created, we're going to go ahead and give this a rigid body as well. But with this, instead of leaving it as dynamic where it will be moved and affected by gravity, we're actually going to just change this to B cinematic. So by being Kinnah Matic, this will ensure that no gravity forces air applied to it, and nothing can affect it in that way, But it is still something that can other objects can collide into. So from here, what we can dio we can just go ahead and we're going to do the same thing for the ah Sky Collider. We're just going to give it a box collider to be We're gonna set the sky box. We're gonna set this 202.8 and zero, and then we're just going to set the size on this to 15 and we're gonna set the Y value to be 150.5. So again you'll see this is going to go slightly outside of where the camera Is this a lot of the player to get a little bit of distance, um, at the top of the screen and get a little bit of bouncing off of it instead of being clipped immediately. So for the Sky collider, you'll notice here we're not actually gonna had a rigid body to this guy collider at all. The only reason why we're adding one to the ground collider is later on. We are going to be having certain events that air triggered whenever the player actually hits the ground. So, in order to have something trigger what's called a collision event or an on trigger enter or on collider enter. It requires a rigid body in order to be signed up to actually send those messages. So because we don't want the player to be losing if they at the skybox, we're not going to apply the rich body to that. But we're going to have it applied to the ground collider so that when the player does it the ground, it does cause them to lose the game. So now that these are both been created to go ahead and control us to save yours, save your scene and go ahead and hit play, and when you hit play, you should notice that the player will drop to the ground and they'll immediately laying on the ground and nothing else will happen. So from here we can go and hit the stop button, and then let's try to get the player object moving a bit, too, where we can actually flap its wings. Okay, so as we incorporate the movement of the player itself were actually going to make some changes to how things have been done right now, we've just been using the gravity in order to drop the player. But what we're going to be doing to be adding this curving or our king effect to the firefly as it flaps, is we're actually going to be adjusting the direction that the firefly is flying. So when the player is not flapping the year, they're going to start varying their nose down, which is going to lead them into the ground. And then when they are flapping, its going to actually kind of point or shoot them back up, similar to what you're seeing in Flappy Bird. So we're gonna change the gravity scale to zero and then go ahead and open up the player script again. And from here, we're actually going to go under the move player, uh, script here. So the first thing we're going to do is we're going to want to check if the player, uh, did flap their wings during this, um, specific frame. So or if they've, if they've flapped since the last update frame rather so every since the update checks or the update calls are going to occur more or less frequently than the actual physics checks . Uh, this will be the point where we actually clear the fact that the player hit the button in order to actually flap their wings. So if the player did flap, the first thing we're gonna want to do we're going to go ahead and set it to where they didn't again. And then from here, we're gonna handle all of the effects that actually occur when the player actually flaps their wings. So the first thing we're gonna want to check for once the player does actually flap their wings is if the player is currently moving in a downward direction. We need to reset that velocity before we add the new flat velocity that they're getting. Otherwise, the amount of tapping we're doing isn't going to immediately shoot the player up from what you're normally sing. So we're gonna do another check here. Another if statement check. We're going to check if velocity dot Y is less than zero. So we're gonna do again. Same quotes. What this is going to do is basically check if the player is currently moving down, then what it's going to do is it's going to set the velocity dot why equal to zero. So this will just reset the players a velocity back to the base state before we apply any upward momentum to them. And then the next thing you want to do, we're going to write Velocity, um, plus equals flap velocity. So this is gonna add whatever the flop velocity number that we have applied to our character to the player itself when we actually flap the wings. So one of the other things we want to do again, we want to ensure that the player doesn't start moving too fast. So this is why we have included this Max speed that we want for the player itself. So in order to set the max speed, there is what is called the ability to clamp the value. So we're gonna go ahead and do Vector three because we're still using effective through value here, and we're going to do clamp magnitude. So what is going to do? This is actually going to clamp the value of the players velocity to the max speed that we have set for the player. So in our case, we're just going to pass. The first value is just going to be the velocity of the player itself. That's what we're gonna pass to it. And then the max is going to be the Max speed that we said above and once that's it again, send me going to end there. So now that we have the velocity, what we actually need to dio is apply this velocity to the character itself. Since we're not using the built in gravity at all for what we're doing, we're actually just going to be applying this and using this to move the characters transform itself. So every object within unity will have a transform that we were using before to actually move objects around. If you look at the player here, this is the actual transform of the player. And from here you can move the X left to right or move the Y value up or down. And that's what we're actually going to be adjusting when we're moving the firefly so back on the player object itself to apply, um, or move the transform. We're gonna do what's called a transformed up position, and we're going to set the position we're going. What we're going to do is add to the position of the velocity and then we're going to do times, time, dot delta time. So what Delta time is is going to be the exact time in milliseconds that it took to complete the last frame that occurred for a time fixed Delta time. I'm sorry. So this is going to set it to be equal to the exact amount of time that's occurred since the last physics, Um, update check on the player. So what this is going to do this is going to ensure that it's going to update it by just a small, tiny amount every single time, because the physics checks are going to be happening maybe 25 or 30 times a second. You need to ensure that you're multiplying this value by that so that you don't end up moving your player much faster than you anticipate. So if we were to go ahead and implement this right now, so far, what we're going to see is the player object will be moving up, but you're not really going to see them move down at all because there's currently nothing to actually force the player to move down at all. From here, they'll just move across the screen. But they'll just slowly drop. But they won't actually kind of get that tilting effect that you're looking for in order to get them to really fall. So the next thing we can dio so we go ahead and go back to our code. Here is what we want to adjust is the angle that the Firefly is actually pointing its nose . So let's go ahead and set the angle to zero by default. So this angle value that were actually declaring here in this move player method because we're declaring this value within this method itself and nowhere else, it can't actually be accessible anywhere else. And as soon as we're done running the method, it will just be disposed of. So for the angle itself, we're going to do another. If check, we're gonna check the velocity dot Why again, we're gonna go ahead and see if it's less than zero. And if it is, what we're gonna want to dio is we're just going to set the angle. We're going to set it to a math EFTA slurp, which is just going to be an interpretation based a linear interpretation of how, um far down the nose of the firefly should be leaning down depending on how fast it's moving down. So the faster it's moving down, the further that's going to basically start going almost straight down at some point. So we're gonna clamp this. We're gonna go between zero and negative 45 because we want the maximum downward angle for it to basically be heading in to be negative 45. So it doesn't again go just quite straight down. And then for this were actually going to check this, We're gonna have this balanced against the negative velocity dot y, um, divided by the max speed. So this will actually said it toe Where again, the longer you've gone, since you've actually flipped the Firefly's wings the closer towards that 45 degree angle, it's going to start tipping its nose. And then for this, what we're gonna want to dio we're going to set the transform dot rotation. And when you're setting the rotation of the transform, you have to set it using what's called a quitter. Nian, you don't need to understand what attorney and attorney and is if you've taken calculus, you'll already know. But for everyone else, just know that they do magic things and you use them when you're trying to rotate things on a sphere. So for our sake, we're gonna use acquit Ernie induct Euler, which this will take a vector three and will then convert that vector three into a specific rotation around an object. So in our case, this is we're just trying to rotate on the Z axis, which is the tilting up or down. We don't want to tilt on the X or ideologists because this is to d. So we're not trying to rotate the Sprite at all. So we're just gonna leave thes first to it zero and then the Z value. We're going to set that to the actual angle of the transform itself. So from here Now, if you go ahead and save this, go ahead and go back to your game from here. When the player starts to go down, you should see their nose start to tilt downwards. And when you pushed them up and then they will start to basically lift up again and start sitting straight down. If you do want the player to drop faster or you want their nose to tilt down faster you can increase this angle from negative 45 you can change it toe negative 75 and you'll notice the difference between how fast and how quickly they are going to just shoot straight down and start heading straight down the second you stop, um, including or stop flapping their wings at all. So let's just changes back to 45 for now. And go ahead. You'll notice. Throughout this, I compulsively will be hitting control. Asked to constantly be saving any, um, updates that I make to the code, I highly encourage you do the same. It's just always a good habit to get into. That will ensure that if anything were to happen, you will always have a up to date version of your code in case something crashes or something like that. So that's gonna be it for this lesson for today and the next one. We will start to include the movement of the camera so that it actually follows the player when they're moving, as well as introduced the first generation of kind of, um, a failure state for the player. So when they hit the ground, it will actually cause them to die and reset, and then we will start to introduce some of the interaction with the, um, blocks within the sky and other things like that. 7. Camera and Game Over: Hello, Vera. In today's lesson, we're going to pick up where we left off and we're going Teoh implement um movement of the camera to ensure that it follows the player. And then we're also going to implement the blocks in the game as well as implement the interaction with the failed state for the character. So when the when the firefly will hit a block or the ground, it will cause the player to lose or caused the game to reset. So first thing we're gonna want to do because we're going to start having the camera itself , actually move. If you remember from the prior lesson, we actually created these ground and sky colliders as well but what we're going to be doing and to ensure that their properly moving and that they're always underneath and above the player where they need to be, we're just gonna go ahead and select each one of them. If you just go ahead and hold the control or shift keys, you can select both of them. We're gonna go ahead and drag both of these and we're gonna we're going to drop him right on the main camera component. So what we just did. Here is if you have other objects, you can actually attach them to another object, and they will become child objects of the main camera. So now when the main camera moves so if we dragged the main camera, you will see that all of the Children objects will be moved with that camera. So we're going to do this and then we're gonna be doing is we're going to be having the camera actually moved with the player. So at this point, I would like you to pause the video and think about why we're not going to just go ahead and attach this camera to the player itself as well. Since we want the camera to follow the player, What is the reason why we wouldn't just attach it to the player itself? All right, so the biggest reason why we're not going to be doing this is because the player is actually going to be moving up and down as well. So if the camera was attached to the player, then you would be seeing the camera be moving up and down as well. But word we don't want that. So we're actually gonna have to do it with the script. So let's go ahead and go down into scripts here and we're going Teoh go to create, Um and we're going to create a C sharp script when we're just gonna name this camera. Um, let's go ahead and in this player camera instead, right? Once the player cameras and made, go ahead and look, look on it again. It's going to start with these, um, with these methods already created for us. So for our sake, we're going to add a a couple of variables in here. First thing we're going to add is going to be we're gonna add a transform a public transform for the player transform we're gonna call player transform. This is gonna be what we used to follow the player or always tracked the player. And then we are going to add in a offset X. So this offset value that we have here is going to be used to determine the, um, offset that needs to be added to the, um, X value of the camera versus the player, um, to kind of keep the player always at the center. So what, we're going to have it do is at the start. We're going to have the offset we're gonna set offset X equal to the transformed up position dot Exe so we're taking the exposition of the camera and we're going to subtract the position of the player from this. So this is going to give us the difference in the X value so that whatever difference we have at the start will be maintained throughout the rest of the movement, that the camera is actually doing so because this offset value is something we don't want to accidentally end up trying to set through the editor itself. We're just gonna leave. This is private, so we don't see it in the editor. When we attach it to the camera, the only value will actually see that we can actually set will be the tramp. The player transform. Okay, so during the update, um, method that's called every single frame we're gonna be doing is we're gonna be moving the camera to match the exact position of the player. So because we can't set the just the X value of the position individually, we're gonna have to make a new Vector three. We're just gonna name this position. We're gonna set it equal to the transform dot position. So we're setting this to the position that the camera is currently at, and then we're going to set position dot exe equal to, um, the player transform thought position dot Exe plus the offset X. And this will ensure that the camera is gonna follow smoothly buying the player. So then we're gonna set the transformed up position equal to this new position that we have here. So go ahead and save this and you'll ahead and go back into your unity project from here under the main camera, we're going to go ahead and attach this player camera script again. You can drag and drop it or type in under at component. And then from the main camera here, we're going to take this player object. We're just going to click on it and drag it into the player transform here because this is the transform that we're actually going to be following with the camera itself. So from here, we can go ahead and test this out. Make sure we saved seen again. And when we go ahead and hit play, you should see it now that the camera is now gonna follow the player. But the background is not set to move it. Also, the backgrounds are actually gonna follow the player at all. And when you hit the ground, nothing ends in. All right, so now that we have the player moving, the camera is moving. But now we need the background to ensure that it is going to be moving and also get refreshed as it moves forward. So here is where we're going to introduce what are called tags. By default of you'll see a few objects will. Either they always start is untaxed, except the main camera will always be tagged as the main camera. Unity uses this to find which is the main camera in the scene. So under the player object here, we're gonna go ahead and we can change its tag to player. And what we're actually going to do as well is we're going to create some new tags. So what tags air used for is when there is an event for two objects with colliders running into each other, which will be called like in an on collision enter event that occurs. What? What you can do is you can actually check the tag of the object that that is being ran into two. Figure out what you want to do with that action. So say in our game, if the player is picking up an item or something like that, we're gonna want to treat that differently than if the player is crashing into a block or crashing into the ground. So because we already stated earlier, we we want the sky to not kill the player when they touch it. We're going to go ahead and go under tax here, and we're gonna click ad tag. So here, under tags, we don't have any custom tags created yet. So we're gonna create one here, and we're gonna name it Sky. And then we're just going to leave. Um, that one For now, I'm trying to think we're gonna want to use some others. Okay, let's actually create one. Maura's well, and let's call this background. So because we are going to be moving the background objects and we're gonna be moving them , we don't want to just create an infinite number of backer and objects just because that would take up a ton of memory, and instead of creating a bunch, we're going to use Justus many as we need to. So if you look here, we can see the size of the screen and the size of the background that we actually have. It looks like if we're actually if we are moving the backgrounds constantly, whenever they are overlapping with the player or starting toe overlap, or when they're gonna be falling off the screen entirely. At that point, we can actually replace them and move them back in front of the player. So in our case, we're going Teoh. Let's just go ahead and take this sky and ground and let's just go ahead and hit Control D , and that's gonna duplicate both of them. And let's just move their positions here. Teoh lets just slide there. X values over, and let's get a little precise here. It's go ahead into man. It should be about 5.84 is what we're gonna be looking at. You shouldn't see any seem in there at all. Maybe just where the little texture is lined up because I didn't let it up very well when I created it. But this is just for testing and prototyping, So art doesn't have to be that clean yet. When you do make your own our assets for anything that's gonna be tile based deal, of course, want to ensure that its lined up better than how I haven't lined up here. But once the whole games in motion, you'll actually see that you can't really notice the patterns that much. And it does end up flowing really, really well with the Parallax. So we have these new sky and ground objects here as well. Let's go ahead and select all four of these and we're going to go a head and click on tags up here. We're going to set these all to background tag and we'll make sure these are all set here and then on. All four of these were actually going to go to add component. We're going to give these all box colliders so you should see on your screen now that you should see green edges around the outside of all the backgrounds that have selected. So we're going to give these colliders because what we're actually going to use is we're gonna use a what's called. We're going to just use, like another object that we attached to the camera called a cleaner object that we're going to use to basically clean up the other basically the background objects and the blocks and other things that the player isn't picking up or didn't run into, that we want to duplicate to move forward into the level so that we are pooling our objects instead of just creating an infant amount of them. So we're gonna go ahead and go on the camera. Now we're gonna click. What's this great empty? We can just name this object cleaner and let's go ahead and give this object a box collider to D as well. Let's set the Y value on this 23 to ensure that it's big enough to ensure that it's gonna capture anything that gets, um, picked up by the player. And let's go ahead and move this back to about negative 9.4. That should ensure, since each one of these is, um, 5.85 and the size of the screen at negative 9.4, it will constantly be moving things before we get to the edge of the screen or before we can see the edge of the screen where things go off further. So once you have your cleaner, um, we're also going to ensure that we add a rigid body two D to the cleaner as well. And we have to make sure we set this to Kingdom attic because we don't want this to be affected by physics at all. But again, when it comes to those collision trigger events, one of the objects needs to have a rigid body on it. So while these background objects do not have any rigid body on them, the cleaner object does so it can trigger the events for everything that's hitting it and then determine Attn. That point. Each of those objects can get moved to where they need to be moved to based off of the collision trigger. So let's go ahead and make a new tag as well for this cleaner here, let's name this cleaner and then go ahead and it save gave you at the plus button that will allow you to create new tags for this, and I almost forgot the Sky Collider box. We want to change this to B sky, so go ahead and save this now. All right, So now that we have the cleaner created and we've said it to the tag of cleaner, we're going to actually create a new script here. So again, right, Click create C sharp script. We're gonna call this on background cleaner, and we're gonna go ahead and double click on this. And this is going Teoh, open a visual studio, this student Open it yet. So stubborn. Click here. So on this one, we can actually remove the starting update methods because it's not actually gonna have those. So we're going to be attaching this to the cleaner object. And the only thing it's going to be looking for is, um, collision triggers. So we're gonna do a private Boyd on Trigger Enter two D. It's important you select the duty here because otherwise it's only gonna be looking for three D colliders. But everything in this game is to d. So we're gonna use to Deacon colliders for everything. So you notice here that this event actually passes in the collider that was involved in the collision. So in our case, this is the object that is going to be crashing into the cleaner object. So what we're gonna do, we're gonna do it if collision dot tag we're gonna do equals equals, we're gonna set this to background. So when you're using a and if, um, statement when you're actually using the equals equals, what you're doing is you're actually that tell you, right? Basically able operator. So what this is checking is if collision tag equals background is true, then it's gonna go ahead into the f statement and if it is not true, it's gonna skip this everything that's within the rackets below. So one of the other things you can do instead of doing equals is if you use the exclamation point equals that is the equivalent of writing. If it's not equals two. So you can use that, um, to basically check for something that is not equal to background will use some of those later. But for this one, we're just gonna leave. It is equals equals background. And so what we're gonna want to do is for all the background objects, whenever they do hit the cleaner object, we're going toe, want to just move them exactly to the other side of the next background object in front of them. So because each one of the background objects will be the exact same size, we just need to actually check for the width of the object itself. So we're gonna do float with object we're gonna set this equal to we're gonna check for the , um this will be will make to parentheses. Here, the 1st 1 we're gonna write box collider to D collision. So the reason why we're declaring this box collider to D here part is that we need to explicitly define, um, that we're working with a box collider to d. So that weaken when we hit the period here, it's actually going toe pull up all of the different, um, variables and methods for the box collider to D. So we're actually checking against the, um size for this box glider to D, and we specifically want just the x value. So we're gonna take the X value of the box glider that we actually hit. That's gonna give us the width of the object, and then we're gonna do a Vector three position, and we're gonna set this equal to the collision. I thought transformed up position when I'm typing, you'll notice I don't finish the words. Most of the time when you're typing, the inspector will automatically fill the word that you're trying to type out. And if you just a tab, it will automatically complete the word for you. So we're getting the starting position of the object, and then we're getting the width of the object, and we're going to We want the position dot exe and we want to add to it. So we're gonna use a plus equals the width of the object, and we're going to multiply it by 1.99 And because this is a float value, we need to put an F on the end. So the reason why we're using 1.99 instead of two is that when you use, um to, you'll start to notice, like a one pixel line that starts to, um get slightly larger over time. So if a player is playing longer and longer into the level on their surviving a very long time, you'll start to notice this gap in the background. And for me went testing this. I know that it looks better if the background just slightly overlaps by one pixel on bits less noticeable over time. If that's occurring versus that one pixel line because it just forms this white line that's very visible, and you can it really stands out when you have that. So this is the new exposition that we have and again because we can't just at it the X value of the transformed position of that collider. We're going to take the collision that transformed a position when we're gonna set this equal to this new position. Now we've modified that is on the other side of, um the background and bumps it back in front of the character. So the reason why we have this checking for the background tag is other objects that may be running into the cleaner are going to be treated differently or move in different ways. So later on in the project, when we start adding blocks, those air going to be moved and randomized in their position a bit so that you're not just seeing the exact same pattern and the blocks every single time as they come through. So let's go ahead and save this, go back into unity, and here, under the cleaner we're just gonna go ahead and click at Component and we're going to add the background cleaner. Just enter. You should see it attached. There's no variables or anything we need to attach to this, So this will be completely fine. One of the other things that were going to be using here is under edit and project settings . You'll see physics to d down here. Um, and what we're interested in is going to be in this chart down here in the bottom corner. This is the collision matrix. So what this signified with the check mark is that the default, anything that is on the default layer will collide with any object that is on any of these other layers that are here. So what we're going to want to change is we need to add the other layers to the game that we're gonna be using. So in our case, let's go ahead and go to layers here at it layers, we're gonna have a few different layers that we're gonna be using. Let's go down here two layers. U I is already here. We're going to create a new one for cleaner, and then we are actually don't need agree one for cleaner. Let's go ahead and create one for background and then let's create one for blocks. So blocks are going to be what the player can run into in order to lose. And then the background will be, um, the background objects that we have that we added the tags for us. Well, so we have these backgrounds in these blocks. Let's go ahead and go back over here to edit project settings, physics to D. So you'll notice these new layers that we just added the background and blocks the background layer. We don't actually want this to collide with anything. Um, so we want to ensure that we remove the background from having collision on anything. We want to ensure that the blocks do not interact with the background the you I or other blocks. Okay, so let's go ahead and change this here and what we're going to dio. So you'll notice here that the background layer isn't set to collide into anything, so I'm sure you're thinking, Well, then how is it going to hit the cleaner back here? And one of the things that you'll notice under here, where it says queries hit triggers. There are multiple ways that you can set up colliders so you can have colliders as actual physical barriers, and then you can set them up to also be triggers. So these will come in handy. Say, if you had a monster in a game that you wanted it to, um maybe become aggressive toward the player at a certain range, you could have a collider that is on the monster itself. And whenever the player entered that range, the monster would immediately No, it's in the rain should start moving towards it. So in our case, though, we're going to go ahead and change these sky and ground objects. If you just click on the top one, hold shift and select all four of them. You noticed this check box here, this is is trigger. So we're gonna go and check this because we do want the background objects to be, um, triggers because they don't actually have any physical collision. So we want them to trigger um, basically as a triggered event, um, which will allow them to still, um, process it trigger with the cleaner, even though they don't actually have any physical collision with any objects in the game. Um, the reason why we do this is because if the background object actually had physical collision with the cleaner when it first hit the cleaner, it would end up, um, getting its position offset slightly. And then we would have to account for that when were doing all the calculations. Only move it. So let's select these four objects again. Change the layer on these two background and go ahead and hit Enter cleaner Object has already set. This could be in default. Layer doesn't matter and let's go ahead and start the game. Actually, before we start, I noticed we made a mistake. So let's go ahead and go back in the layers here, and we do actually need to make a layer for the cleaner here. So again, if you click layers up top at it layers, you'll see this one here, and we're gonna add a cleaner layer, and the cleaner does actually need to still be colliding with the background. I misspoke earlier. Sometimes these mistakes happen, but it's all about catching them in time. So we set this to the cleaner here. We're gonna go under project settings and under physics to d verify the cleaner object here . We only want the cleaner object to be interacting with the background and blocks because those are the only things that's going to need to be cleaning up and moving. So we're going to go ahead and uncheck all the other boxes so the cleaner isn't interacting with any other objects. We're gonna go ahead and save this. Verified that the cleaner is set to the clean earlier. These others are set to the background layer. And for our sake, let's go ahead and just move the cleaner closer, just so this triggers a little bit faster. We'll remember it was a negative 9.4 before, so let's just set this at negative five for now and go ahead and click OK and hit Play and you'll see this. Start playing right away and you'll notice on the scene view immediately. As these objects hit the cleaner, they're going to be moved. But now you remember why they were set to negative and I'm poor for, because otherwise they get moved too quickly so we can verify here again that both sets of them are in fact moving, going to enter here. Let's change this back to negative one point for And let's test it again. Let's just increase the max beat on the player toe, Remove the forward speed on the player to to move him a little bit faster and will change the max speed to two as well. Just for testing sick. No, they're moving along really fast. So as we move, you'll notice that again. The background is constantly being duplicated across and not noticing any. Seems with the creation and we dio it's zooming along. Okay, let's just go back out of this. We can reset this back to 1.5 and 0.4. Okay, go ahead and save this. The cleaner is set. So one of the next things that we can go ahead and start to put in is we can have the player check to see if it is hitting something in order to trigger a game over event. So, for this, let's go ahead and go into the player. Double click on this script. We're going to go down to the bottom, are gonna had a new private on, um, collision enter to D. We're gonna do a new event. So, um, so far in our game, the only things that the player can run into, or either the sky or the ground. So we're going to do another. If check, we're going to check the collision dot tag. Um, collision A transformed a tag. I'm sorry. And we're gonna check if this is not equal to sky because again, we don't want the player to lose if they at the sky. But we want him to lose that They hit anything else? Um then we can dio IHS from here. We can actually look in here. Let's do a set the time It's time. The time scale equal to zero. So what this is gonna do is gonna pause the game immediately, and then we can do a debug log. And for now, we're just gonna say, game over when that's it, game over and it's gonna posits game will force you to basically closed the game and cancel it out. Once we add the you I into the game, then we can actually have it reset the level every single time. You, um, hit the ground like that. So, for now, though, we're just gonna have us at the time scale back to zero and then trigger game over. So let's go in here now. Let's go into the main scene. Let's go ahead and test it. What? The player Fall down immediately and you should notice it immediately. The everything freezes that state's game over, so we know that the collision on the player is working properly and it's triggering properly off the ground. Let's double check Teoh ensure that the we don't lose for hitting the sky Collider. So let's go ahead and just spam click up until they get the sky yet. So we're not actually losing. Forgetting the sky, it does let us go into it a little bit and we could drop right out of the sky. Anyone causes still lose again. So we know that this is working properly now as well. From here, we can go ahead and start to create our first blocks. Now it's time to create our first block. So if you go down here under textures, you'll see this blink moth sprites file. Just click on the arrow here and you should see a selection of blocks. We're just going to go ahead and take this block one for now. If you go ahead and click on it and drag right into your scene, you'll see that the game will automatically create a new object for it. Galardi. Name it. Block one first thing we're gonna want to do. We're just gonna add a component to it. We're gonna add a box collider to D. So this way that the, um block itself will have a collector on it for the player crash into. And then we are going to At this point, we're going to take the block itself on and let's go ahead and set its tag or its layer rather two blocks and let's go ahead and click the arrow, appear for the move tool, and let's go ahead and move it. Um, somewhere on the screen, just for testing sake, and that's just said it here. And see if this causes the player to lose. If they crash into it, go ahead and make sure you fly directly into it and you'll see the men. So no, the block is working fine in that sense, but we haven't set up anything yet to handle moving the blocks. Once they've gone off screen or ensuring we move them further along for the player and ensure that we can randomly set them out. So in the next lesson, we're going to build the block generator as well as the, um, set up that we're gonna be using to place the blocks randomly between various places. So last thing before we close this one out, we're gonna go ahead and go to the Assets folder here and we're going to right click. We're gonna make a new folder. We're going to do an underscore here, and we're gonna name this pre fabs. So pre fabs are basically any prefabricated objects that you're wanting to save in any way by using pre fabs. This is basically a good way that you can store an object and you can make you convey basically make clones of that object at any time. So because we're going to be spawning more than one block, one object at once, we're gonna want to go ahead and just move this into here. Let's move it into the pre fabs, and we can close this one out for now and then in the next lesson again, we will create the scripts for the block to handle moving the block as soon as it goes off screen to move it to the next position, as well as, um, the random placement of all the blocks within the scene. 8. Block Generation: Hello, everyone, welcome back. We're going to begin creating Mawr blocks now and then we're going to create the block generator to move them and place them at the very beginning of the game to ensure that its random every time, as well as randomized their placement when they are being reset as well. So for now we have this block. One object. Let's go ahead and just move this thing up above and out of the screen and let's go ahead and click back on textures again. And let's take this block five here. Let's drag and drop this onto the screen as well. If you just double click on this object, you'll see that it will go to exactly where it is in the scene. You can also hit F will have you lock onto another object as well. Once we have this selected, let's again at the component to it that a box collider to D And then let's go ahead and say we're seeing Click on our pre fabs folder and let's make a prefab of this Block five as well. So these are the two blocks we're gonna be using to show this for now, what we're gonna do is weaken random. I place these for now. If we want to take these pre fabs here, you can just drag and drop him. If you just drag it right from the prefab seen you can you will be able to notice. Here you can drag and drop them right into your scene any way you want. Go ahead and randomized the placement of these and so we can kind of just move in places where we want See if we can get the player to be bouncing around and avoiding these. Let's see if we can just make it through these 1st 3 hoops here and good you'll see were flapping along. And let's just go ahead and hit one of these little blocks to make sure they make us lose as well. And they dio So making go and exit out of this and all these new blocks. You see, we just dropped in. You'll see they have these extra numbers after them. That just means they're not the originals that were in the scene to the end up. Basically getting this extra number after them, we can again shift, select all of them and we can just go ahead and delete them. One of the other things we can do it you know as well is under textures here. If you see these three Firefly textures, if we actually select all three of these and we drag and drop them right on top of the player itself by default, Unity will take the three textures that we created and actually create an animation from them. So we can do this. We can select all three. Drop mon, go ahead and back up into your assets folder. Here, let's make a new folder. Let's just call this animations and then here we'll just call this player in the mission. So this will be the animation for the player, and it will automatically touch to the player. And for our sake. In this game, it's just always gonna animate, and you know it's not gonna ply an emotion or anything to the player at all. But when you get play now, you'll notice that you'll actually see the wing slapping on the firefly. So that's a quick and simple way to do animations. We're not really gonna be applying any other animations at all in this lesson will start applying the more in some of the future games that were great. So now that we have these and we have these two block objects appear, we are going to create our block generator. So we're gonna make a new script here. Let's go to create C sharp script, name this block generator and let's go ahead and double click this to bring a visual studio and you'll see the book generator here. So some of the things that we're going to need to be doing is we want to ensure that when the game first starts, there's enough blocks going down along the line that, um, we can see blocks all the way on the edge of the screen so that we don't ever get to where we can't see what blocks air coming up. And we also want to ensure that the blocks air spaced out enough that we can actually jump between them, because if they're too close, then we're going to run into cases where the game is impossible to move forward and you don't want to do that. So the block generator here is going to be our first look at um, loops as well as our first look, Pat. Um, using the in stan, she ate function to, um, create objects from pre fabs or from other game objects themselves. So let's go ahead and get rid of these. Start an update functions. We're not gonna need those. So the first thing we're gonna want to do, we're going to make a list here, A public list. So a list is just one of the methods that are one of the ways that you can use to actually a store, Basically a list of objects. There's also a raise. There's dictionaries and other things. For this case, we're going to story list. Um, in the inspector here, you'll see where it shows t in there. That just means that you can put in any other, uh, class type in there for our sake. We're gonna be using a game object, and we're gonna call this small blocks. We're just gonna put a semicolon afterwards because we're not actually creating this list at all yet. We're going to create a public list game object, and we're going to call this large blocks, so we're gonna differentiate between the small blocks and large blocks because if to block two large blocks were both to get set on the same row. Then you're going to run into cases where they will be two of the long tall blocks and the player won't be able to get through it all. So for this one, we're going to be pairing up a small block with a large block every time. And then we're gonna be randomize ing their position on in terms of their actual why value in terms of how, like, higher, low each one of them actually is. So the other things we're gonna do here, we're going to add a, um, public int blocks to generate. We're just gonna set this equal Teoh 12 for now, and we're going to store a private value called block Number. I'm really just gonna set this toe one. So this block number is what we're actually gonna use so that when we place our list of blocks were actually gonna be able to know, um, where the blocks are so that we can actually move them to the proper place when they need to be moved. Okay, so we're gonna be looking to do with the blocks themselves. So say we have the blocks here. We got our blocks that are all set up and in a row. But we need to be doing is ensuring that each single block gets moved to the exact place where we need them to be. So this block's gonna be moved here, and this one's gonna be moved here. And this one here, etcetera. So the way that we're gonna do this is by using those block numbers that when we first generate the blocks, were going to pass this block number to them, and then they'll be able to use that whenever they get moved, so they know exactly where to move to. So the first thing we're going to do here is we're also going to create a new, um, random number generator. So we're just gonna type in system dot random. We're gonna name this Rand, we're gonna set this eagle to new system dot random, and then you gotta put the parentheses afterwards. You could put a specific seed value in here, and that will ensure that it will roll the every single time. When you start up the program, the blocks will be in the exact same place. And they will always randomize to the exact same place based off of the seed value you give it. But we're just gonna leave it like this, which will end up generating it based off of system time. And it will be truly random for her sake. So we're going to for this method, we're actually going to use the awake, Um, a portion of our seen this is gonna be the first thing we want to actually happen. Or the first thing we're gonna want to actually occur. Um, during the scenes is we're gonna actually want the blocks to be generated. And, um then we want the game to actually be able to start from there. So, um, first things first, let's go ahead and, um, do a check here to let's go ahead and do a four. This is gonna be our first introduction to loops. So the way that you do a loop, you started with four and we're gonna go ahead and start with int I equals zero. So the first portion that goes into a loop is the generator for our sake. Generators just gonna be I and it's gonna start at zero. The second is going to be when the loop should stop. So this is gonna be I As long as I is less than blocks to generate, then we're going to use another semi colon. Then we're going to continue to Then what is going to be done after the flu is done before it starts the next one. So it's going Teoh loop through this list, starting with, um, the first object which is object to zero in the array, and then it is going to increment. This I value. So it's gonna keep selecting the next object within the array or within the list. So we are going to first check for a sense on each, um, section, we are going to refer the amount of blocks to generate. That's actually gonna be the number of rows to generate. We're going to generate a small block and a large block for each. So we're going to do an int small block to generate. It's good this we're gonna set this equal to rand dark. Next, we're gonna have this go between zero and the small blocks docked count. So this is going to give us a random number between zero and the total number of small blocks that are in the array. So, um, a raise will always the final number within an array or list will always be one less than the total count. So because it starts on zero, it's going to count through every single one. So if there's four objects in the list or in the array to get the last object in the list, you're gonna be looking for the object with the element idea of three. So here we have a small block stock count with, um system dot random. When you are using integer values, the max value is not included in the, um in the possible selection. So while the max value is in, our case is still going to be set toe one. It's not actually going to be included here, so it's no matter what's going to be zero. But if we had four objects in there, then the maximum value would be three. So this will ensure we don't actually try to select a value that isn't within the range of the actual list itself. So from here, we're going to do a game object. Let's leave this capitalize. We're gonna name this game. Object. Small block. We're gonna set this equal to game object. Got in. Stan. She ate. So game object in Stan she ate will allow you to. Basically, this is going to clone theon object that we pass into this and create a new copy. So for our case, we're going to select small blocks. So this is going to pull up the list of small blocks that we have appear and we're gonna use the square brackets here and in the square brackets is where we need to put the index for the small block that we actually want. And in our case, because we're using a randomized one, we're going to use this number here, small block to generate. So this gives us the exact index for what we actually want to spawn. Now that we have this block generated, we're actually going to want to pass some information to the block itself to tell it, um, what its block number is and where it should position itself after being spawned. So we're gonna go back into our scripts folder here, right? Click Go. To create C sharp script we're gonna create. Call this block. We're gonna go ahead and double click on block here. And so they block script itself is going to be doing a few things it is going to handle, um, moving itself once it has hit the cleaner at the end as well as it needs something to store the block generator and whatever block number it is and then determining whether or not it is a small block. So let's go ahead and create a new public transform. Call this block generator. We're going to give this a block number beginning even. Just make this event block number. I guess none of these need to be public so we can go ahead and said he's this way and then the pool small book. So we're going to determine if it's a small block or large block, because what we're gonna want to do is every we're gonna alternate which block is on top, whether it's a small block or a large block. Um so it needs to check so that it's making sure that it's reversing itself, but not gonna place itself over under one of the larger blocks when we passed the values to it. So we're gonna make a new void here, a new void method so public void. And we're gonna name this method set, Block, number and spawn. So what this method is going to do, it's gonna set the block number for the block itself, and then it's going to actually spawn that block. So there's gonna be a few things passed to this block. The first thing is going to get past two. It's going to get past the end underscore block number. So we're going to get a block number passed to this from the block generator. We're also going to get a transform underscore block generator. So the block generator is going to pass the reference to itself so that the block in storage as well, then we'll have a full underscore small block. So we're gonna pass these values too. The block itself right now, we're gonna set the block number on the block equal to the past in underscore block number . We're going to store the block generator. We're gonna set that to the underscore block generator, and then we're gonna also store the small block is equal to the negative small block. Okay, so we're not gonna write any of the code yet for the actual spawning part portion yet from here, let's go ahead and go back to our block generator script now that this method has been created So that under block generator here Now that we have this small block, the first thing we're gonna want to do with it is pass in these values and tell the basically the block itself. Hey, this is your block number. This is where, um, this is where I am or who I am so that the block itself will know where despond itself. Because we're gonna have the block generator set ahead of the camera so that it will just be spawning blocks on top of itself, its own X value and then using a different, um, why value, which is the vertical value to determine where the block will be and that will be determined at random. So the way we're gonna call this is we're gonna type in small block, and then you can use dot and you can take get component, and then you are going to write these brackets here, and, um, the component we're gonna be looking for is Block. This is the specific script that we're gonna be looking for on this small block object that we want to actually activate. We're going to use parentheses because we're not actually gonna be. I'm looking for any values that way, and then you're gonna hit, period, and you should see the method that we created on the block script that is public is going to be this set, block number and spawn. So because this is that, ah, public, we can access this method from within another class. So from here, then we're gonna make thes parentheses. We're going to pass in the block number. We're going to pass in, um transform, which, if you just type transform on an object that's going to return the transform that's specifically attached to the game object that is making that call, and then we're going to for a small block. It's going to be set to true, because this is the small block for this actual block number. So know that we have this created these air being passed. We're gonna do the same exact thing. But this is going to be for the large block so we can go and just copy this good and selected all hit copy. Go ahead and paste it and we can actually do a replace here. And if we go ahead and hover over this, we can just do it find and we're just going to look for the word small and we're going to replace it with Arch ninja Sick. Replace all, ensure that this is set for a selection and you'll see this That's going to convert all these to now be these thistles, the large block to generate. The last thing we need to ensure we dio is again under the set block number and spawned because this is the large block this needs to be changed to false so that the block doesn't think that it iss one of the small ones and try to position itself in the incorrect spot. So the next thing we're gonna be doing since there's gonna be more than one block to generate what we also need to be doing is changing the block number and we're going to take the block number and we're gonna write plus plus. So what happened to any do plus Plus, it's very similar to, uh when you're doing the plus equals plus plus is the same thing is writing plus equals one . So what this will do is this will increment the block number by one every single time. So when the scene first starts, the block number is going to start on one, and then this block number is going to be passed. So the first set of blocks we have their block number is going to be one. The next set of blocks, we have their block number will be two and three and move up through each, um, federation through this loop that it goes through. And then once it gets to the end of the total number of blocks to generate, it's going to move out of this four loop, and it's going to continue on to the next portion of code that we have below. For now, there's nothing else that we're gonna be spawning. So we're just gonna go ahead and save these so we can go back toothy block script now and under the block hair. We are going to, um, want to do a bit of math. So from where the player is, we want to ensure that if we have these two blocks here that we need to ensure that there's always enough space for the player to either go above the blocks or below the blocks. So if the blocks air spawning in a way that there isn't enough room for the player to go either above or below, then we are in trouble. Because then we're making a game state which the player cannot actually pass, which is just not gonna be very fun for anybody. So luckily, I've done the trial and error and I've ran the math already. So you don't have Teoh. What we are going to Dio is for the first position of the, um of the block. When a despond, we're actually going to get a vector three dot position and so we're gonna make a new Vector three pos. We're just gonna set this equal to vector 3.0 for now, creation. So this is just gonna be the X y and devalues They're gonna be all set to zero. So we're going to set the position that X equal to camera dot main. So what this camera dot main function does? Is this is going to go out and find the main camera, and then we're going to take the position of this. The camera doesn't main transform dot position dot Exe. So we want the X value of the, um, camera itself. We're going to add 1.25 to it, and then we're going to add the block number two it. So, um, this will the blocks themselves are going to be separated out, um, by one unit, and then they're going to start, um, this far forward from the player themselves. So every single one will be separated by 1.25 basically, So this camera doesn't mean is, um, something. When you're working with larger games, you're gonna want to avoid calling this, but since this is only being called once for each block at the very beginning of the scene , it's not a big deal. But if it's something that is do that is happening repeatedly, then you would want to store that up above in one of the global variables for the class, so that you're not constantly having the game search for the main camera. So now that the X value is set, we're going to do. And if small block. So, um, when you see me past a bull variable into this me writing just if small block is the same thing as writing is small block equals equals true. So this is just a shorthand way to do it. Um, And if I was to wanting to check if this was false, I would just put that same exclamation mark in front of it that is used to signify Not so if that I'm checking if small block is not set to true. So in our case, we're just gonna check for a small luck. So from here, as I stated before, we're going to be alternating whether the small block is going to be on the top or on the bottom, and it's just going to stagger. Every other block will be either top or bottom. So go ahead and possibly to go here. And I want you to stop and think, try to figure out how you would determine whether or not the small blocks should be on the top or on the bottom. All right, so in our case, there is a handy operator that you can actually use to check if the number is odd or even That's one of the easiest ways to If you just have a binary kind of switch. If you need to know if it's top or bottom, you know, one or the other, you can just use this number to check if it is order. Even so, the easiest way to check if a number is odd or even is if we're going to do another. If statement here and we're gonna type block number and we're just gonna go ahead and type of the percent sign so on, and then we're gonna type two. So what this is is basically it's a, um it's a mod basically variable, which is going to determine if there is any remainder after dividing by two. So say we have our block number. It is set to one. If you divide it by two. Um, then it is going to have a remainder of one, which means it is not going to be an even number. So if we check for zero, all even numbers, when divided by two, are going to have a remainder of zero. Um, so we can have this check here now. So if anything is a block number, that's gonna be even Then we're going to set the position, not why? Equal to, um, we're gonna use the unity engine random this time. So we're gonna use unity engine dot random range, and we're going to select between 0.40 f and one. So, uh, here we are, and then we're going to set the transform that position equal to position. Actually, let's not set this year. Let's go ahead and just set this at the very end of the statement. Go ahead and just select this control ex ally to copy it and then control V you can paste the at the end. If we were to put it inside of each one of these statements, we'd have to repeatedly type it out. So let's not do that here. And then what we also want to be doing is again If the number isn't even we're going to do , we're just gonna write else and put quotes after so else will trigger whenever. If it doesn't match this first value, then it's going to fall through into the else, um, portion of the, um, Logic gate. So If it's even, then it's going to set it to the range above. And if it's not, then we're going to set position dot Why go to unity engine that random that range, and we're going to set this to 1.7 to 2.25 Make sure you put the EFS at the end so that it maintains as a float variable. And then this is what we want it to be doing for, um, for small blocks. So then we can copy this in here. We wanted to be doing the opposite for the large blocks. So here again, we can do another else, make the brackets and go ahead and paste in this logic from above as well. And then, since the small blocks when the block number is even, are going to be down below on the bottom, when the large blocks are even, we want them to be on the top. So we're going to have this be not equal to zero. So any time this is an odd number, then the large block is going to be on the bottom, and then otherwise it's going to have it be on the top So let's go ahead and save this year now and then let's go ahead and go back into our game and test this and see if this is working how we wanted to. All right, So let's go back into our seen here. We're going to create the block generator. Now. We're just gonna go ahead and place this on the camera so we can just right click on the main camera itself. We're gonna go to create empty. We're gonna make this name this block generator. This doesn't actually need to be on any or have anything else attached to it other than the block generator script. So under small blocks and large blocks, these they're both gonna be empty by default. But we're gonna want to position this ahead of the camera so you don't actually want to hear. We want this wherever the blocks are actually going to start. So in our case, let's set this to 3.35 and then under small blocks, we're going to go and click works. Its pre fabs are here. We're going to select our small block prefab that we have. We're just gonna drag and drop this into the small box. If you just drop it right on top of the wall box, you'll see it, get out it to the list and then under large blocks will just drag and drop the large block . On top of that, we will go ahead and save it and then, lads, starter game and see if it generates the's where we expect them to. No reference. All right, let's see. So if you ever get an error like this, the first thing you can actually do is if you just double click on the air, it will actually tell you exactly. It will should pull up exactly where the error is. So we double click on this little pullup line 25. This is saying that this right here block this component was not actually found on on the small block. That is because we didn't add the block script to these blocks yet. So go ahead and press the play button that's gonna endure. Paused the game again. If you selected these two blocks that we have here in the pre fabs, we can actually just select both of them using shift click, add component. We're gonna add the block, stripped to both of them and you'll see it'll just add the block script right here and because we added it to the prefab. This will also at it the pre fabs that are already within the scene, so you'll see these have already been at it a swell, so pre fabs also help you. If you're making adjustments to the prefab objects, it will adjust those values and things on all of the prefects themselves so we can go ahead and save this. You'll also notice the's are in a blue color that signifies that they are, in fact, pre fabs as well. So now these have actually been set on the blocks themselves. We can go ahead and it clear here to clear the air's and let's go ahead and hit play again . And now you should see all the bucks and we're gonna go ahead and you can just fly around, try to avoid these blocks as best you can, and then just go and crash out. All right, so now that we know that the blocks themselves are actually spotting where we want them to , we need to ensure that the blocks are moving as Well, so let's go ahead and create the move. Functions for the box now. So back under the block script here, we're going to make a new private Boyd. I was gonna be on a collision enter to D. It's already created for us. Um, we actually want this to be and on trigger Inter because we want this to trigger on trigger enter to D. So because we want the cleaner to affect the blocks differently, we don't actually want it physically colliding with the blocks, because then it's gonna be pushing them and offsetting them were actually going. Teoh, have it, um, go off of a trigger instead of off of a normal collision. And for this, we're going to again have a check for if collider tag, he goes up. Sorry. On on trigger Enter, we can have it go off the collider to D instead of collision collider. If the glider dot tag is equal to clean her, then we want this to trigger the move method. We haven't created the move method yet. Well, that's good. And create that right below. Boyd. Move. No, no, no. Just so by default. If you don't type private and he just write void. That is the same thing is having private. We'll just leave the private there. For now, though, it's a good happen to get into. And I'm so under here now we can pass in this other function. One thing I did just realizes instead of rewriting all of this code, we can actually make a new method called, um private void. Um, place, pluck American. Just pass in a Vector three position pos. We're gonna make quotes here for place, block, and what we can actually do is we can take all of this code that we have here. Um, under this underwear, it checks for small, block transformed position in all of this. Just go ahead and cut all of this right here. And we can go ahead and, um, paste it down here under place block. And what we can do is now up in the set block number and spawned. We can actually set this to place, block and weaken. Just pass in this position value. So this is just gonna set the initial X value for where the block is going to be placed, and then down here is we'll handle where it's going to be moved up or down for, um, that value. So under the move function this time, all we need to actually generate is the new X value for the blocks of where it's going to be horizontally. So we're gonna set this specter three position equals we're going to set this to transform the position. So set it to whatever the position is that the block right now, we can set the position X equal to the block generator Stop positioned X. So we're just gonna spawn this block exactly on top of where the box generator currently is , and then we can actually do place, block and pass in this position we just created with the ex. And then again, it's going to handle the same code that it was doing before when it first generated the block originally, and it's gonna place it where it needs to be down below so we can go ahead and say this. Now you'll see these four methods we got here and let's go back to our blocks themselves. So right now, the blocks just have the single box collider that isn't that is a trigger, but what we're gonna want to actually create is we're going to select both of these. We want to add another box collider to them, another box glider to D, and then we're going to set both of these two triggers. So he should each now have a box collider that is a normal collider and then a box collider to D, which is gonna be a trigger. One of the things we might notice is that some of the blocks that were actually coming up seemed like they might actually be cutting it a little close compared to, um, how much room the player actually has to move because of the size of this block. What we can do is we can actually go here under block. We can actually adjust the values for, um where the small block can actually place itself. So by default, we're setting it where it's going to spawn 0.4 off the ground, which is right at the ground level upto one. We can actually lower this to about 0.9. If we wanted to have it not goes high. And then for these upper values, we can have it toe where the upper ones cannot go quite as low. So we can change these to say, 1.8. For example. We can go ahead and go back into our code here and let's go ahead and let's lower the speed on the player. Little bits. We can see this a little bit easier. Changes the lawn What's good in your play. And let's see how this looks. These look a little bit more spread out now, Um, and with it just being these two blocks, there isn't quite that much variety with them yet. So we're seeing a lot of the same stuff, but some of these look like they might actually be kind of hard still. So one of the things we're gonna want to probably dio is ensure that the small block or small blocks that were using maybe aren't quite as wide. So what we can dio We have some other blocks over here that we can actually work with. So it's good changes, player and sure, we enable their collider again change their speed back 2.4. Let's go ahead and test it in real time and see how good we can do. Based off this setting, we currently have here and looks like we're moving along. And these were some of the spots to get a little bit harder. Maybe we have to go up to the sky for this one for this, and we're gonna have to drop pretty low to the ground rides. You can tell I've played this bit so gonna be a little bit better than some of the others. But OK, that's gonna get game over there. And so one of the things that looks like is we're not actually getting triggers for when we're hitting the blocks right now, because we set the blocks to check for triggers. So because of that, what we can actually do is so we're actually gonna want to Dio is create new box colliders on these as well. And these ones are actually going to be normal colliders for the player to actually crash into. So the triggers are going to be set for the cleaner because the cleaner itself is going to be setting off the triggers for those. And then the, um, colliders are going to be for the, um, player took a light into the blocks themselves. So let's test this here Now let's go ahead and turn on the Circle Collider here. Let's make sure the players actually properly crashing into these and they are that's good . And this out. Let's uncheck the box for servo collider. Let's make sure the blocks are properly being moved now. Going to play again? Blair shouldn't Clyde within this time, but the block should still be moved by the cleaner because of the trigger colliders on them and they go seeming seen. They're being moved long and there we go. So these will be living through just fine. There we have it. So these are being moved on and moving right through. All right. So from here, we can actually begin adding some extra blocks from what we currently have, so we can go back into the textures here. Just go ahead and go into this upper part of the window, go ahead and drag out one of these block sixes. I can drag out a block three handbook to All right. So from here, um, and that's dragon a block for as well. All right, so we have a few decisions that we can make based off of how things are currently set up. If you were paying attention there, you would have noticed the blocks will start to get slightly offset because they're not all of the same with That's something that we're going to go and leave in by default. Just because it's one of those things that has the level progresses, it will start to get more challenging because things aren't gonna be lined up is perfectly for the player. So it's one of those unintended things that I kind of like to leave in as just a, um nice, unintended kind of, ah, challenge to the game. So for these new blocks that we just created, we're actually just gonna select all for them. We're gonna go to a prefects folder here and we're just gonna drag them right in. We're actually going to drag him in one by one. It's not about that. It's just drag a man. Block six, look, three book to on block for So for these four blocks, we're gonna had all the same things to them that we have on the other blocks. So we're going to give them a box collider to D. This first one's gonna be a trigger. We're gonna add another box collider to D to them. This one is going to be normal. And then we're going to give them the block script. Then we can go ahead and hit. Save here. We should see this Get added to all of these new blocks here. And just to verify this is the same thing that's on the other blocks, which will be the two box gliders and the block script. So if we actually take these prefab values since we actually edited thes from within the scene itself, If you actually have a prefab that selected and you click the apply button up here, this will actually apply the changes you made to the prefab. So if you look right now, that says this block script in the two new colliders in it. But the Block six prefab doesn't have any of this stuff attached to it yet. If we select block six and we click apply, this will apply the new additions that we made to the prefab itself. And then if we wanted to do the other way around, if we wanted that we get select one of these when we get Click Revert and this would change this back to be specifically what the prefab is. We don't actually want to revert any of these changes right now, so let's select the other three blocks. Yeah, just like the one by one Select H one. Go and click apply so we can make sure we apply these changes to the pre fabs themselves. And let's just go ahead and move these up for organizations sick right now. So for each of these blocks, we're gonna notice they have a couple different sizes here. So under the block generator, this block six is pretty one of the other small blocks as well. So we can drag and drops this year on the small locks and for the large blocks we can add in the, um, the book to the Block Three and the block for Let's go ahead and save this And let's go ahead and just run this and see what it looks like with these new blocks in here. But players still moving a little fast here, so we're not really gonna be able to pull anything off. You didn't even turn on the glider again. We're gonna actually still look at it to see what we're looking at that and you'll notice here, this is gonna be one of the ones where, um you can use this to kind of see where you might be running into some issues. So this, uh, four block end this to blocker both really, really long compared to some of the other blocks that we run into, like, this block one here. So one of the things we can't dio you can actually just go ahead and just these blocks themselves. So what we can do is actually we can adjust the why scale of the subject which will shrink this down or make it a little bit bigger. So we want to shrink these. We can go ahead and shrinking both down, change into about 0.75 Let's go ahead and just want to be about the same 0.75 Let's go ahead and again. Make sure you have apply to apply the changes you make. Go ahead and apply this to Block three as well. That will apply the scale changes and let's go back to the player, set their speed back 2.4 and ensure we re enable this glider for them. Let's go ahead and hit a play and see what this looks like. Now, there we go. So we're going to think some variety in the blocks here and, um, players moving along and these air going to be, um, some of the different blocks you see, There you go. Ended a fitness got a game over. So one of the things that was noticed after recording this video was that the blocks themselves weren't all on the block lay 9. UI Creation: Hello, everyone. Welcome back where we left off. We had just finished implementing all of the blocks were going to be putting in the project , and we wanted to begin adding the background parallax elements to the project. So we're gonna go ahead and go into the textures here and under background. You're going to see a mid ground in a foreground. Let's go ahead and let's just add this over here. Let's put this right down below. Got a mid ground and we got a foreground. Dragon dropped both of those. We're gonna want to change their positions as well. We're going to change these positions to 1.25 as well. So for these, we're gonna want to change their why Value as well, and set them toe 1.25 from here is where we're actually going to start using the layers as well, because we're gonna be having these stacked on top of each other. We're gonna want to be adjusting the, um, Z value of each of the backgrounds here. So for the backgrounds were going to set the mid ground and foreground, we'll go ahead and set the mid ground to to and most of the foreground. 22 is well, but then we'll change the background layer on change. These two, this guy on a others right here. So you'll notice here that the sky layers will have an order to them. So under the spread render is where we can actually choose the, um, order that we want for the layering. So since we want this guy to be in the very back, we're gonna set the sky at negative eight. We'll go ahead and change this for the other sky as well. The ground. We can leave it at one. But we're gonna go ahead and change the order in the layer on both these grounds to negative two and then for the mid ground. Let's go and changes to negative seven in the foreground. Change this to negative six. So this is going to ensure that our background, um, objects are always going to be behind the player and the blocks, and then we'll ensure that the layers themselves are in the correct order that we want them to be in. So, for the the way that we're going to be handling Parallax is we're going to take the mid ground in the foreground. We're gonna have this the mid ground, the background and the foreground are going to be moving at different speeds. So to do that, we're going to use this. We're going to create a new script. We're just gonna call this script, so right, Click creates script, background mover. We're just gonna go ahead and double click here. Open a visual studio for this new background. We were script. What created? We're just gonna have a public float appear of, like, slow convergence at the sequel to Speed on by default, Walter 70.25 I believe it is afloat. So because this is going to be something we want to ensure is moving the same speed for everyone who were on the same speed for the physics checks. We're gonna change this to a fixed update so that the speed is consistent for all the users . Because otherwise, people with again very fast machines, the backgrounds gonna be moving much faster than for everyone else we're gonna be doing here. We're going to take the vector three position, bringing us that this equal to again the position of whatever the object where is already We're just going to take the position, X We're gonna plus equals speed, times, time fixed, delta time. So we're going to, um, basically add to the X value, um, the speed of the, um, object. We're just gonna basically increase that, and we're going to make that object move away from the background at that speed. So the, um, sky in the back will be moving, um, faster. So it's basically going to be offsetting the amount of movement that we're already getting from the camera by default. So once this is kind of here, we can go out and say this and let's go ahead and get the sky here. Let's go ahead and select both disguise. Actually, we can go ahead and select all of this the sky and the, um, mid ground and foreground. We can add this, uh, background mover to all of them for the sky. Here, let's go ahead and set the sky. Teoh 0.35 And then for the mid ground, we'll have the mid ground move that, uh, 0.2. And then we'll just have the foreground. Um, move that 0.1. So let's go ahead and Now that we have these values set on these, let's go ahead and duplicate this mid ground in foreground. Just again. Select the to hit control D. We're gonna drag these over to get their position offset, just like the prior ones. So the new X value and these should be 5.84 You'll see here. If you look in, you won't see any seems, um that should be good. G o The zones actually might want to be offset slightly more because of the way that thing is set up. Let's set this to 5.83 area 5.835 nine 5.839 works. There we go. All right, so now that these air set, they will have the speed set on here. And let's just go ahead and set the player to not collide with anything just so we can look at the Parallax in here. Let's go ahead and save the scene and then hit play and we'll see that the background itself appears to all still be moving at the same speed. Ah, I see Why. Ok, so we actually forgot a line of code here. We didn't past this position back to the transforms to transform the position equals pos. All right, let's go ahead and go back to the scene now on Save it again. It will reload that code so you'll see Unity Hiccup for a second. And now let's go ahead and hit play. And now you'll start to see that parallax in effect where again the foreground is moving by a little bit faster than the mid ground and the background as well to get that nice, cool looking Pai relaxing effect with the background there, you do notice this little tiny line. That artifact that is occurring sometimes can fix that by just overlapping the mid ground and foreground just a little bit more so 4.3 point 35 instead of 350.9, then that should kind of adjust that as well go and it save on this. And we didn't add a collider to these either. So let's go ahead and duplicate all these given box collider two D's and we need to ensure that they're set to triggers. So let's go ahead and select all for these mid ground and four grounds set them to triggers and save them, so ensure that they're being moved by the but the scene mover. Let's go ahead and just, uh, it play here and let's check to make sure they're being moved properly. So if you actually look in the scene view, you can actually see what is happening again. These objects are moving forward to kind of offset the, um, the movement to basically give that illusion of movement and of speed. So they're kind of moving with the, um, collider itself, the ones in the very, very back, because they're moving forward almost at the same speed of the player. Um, they're not really going to be picked up by the cleaner very quickly, but you'll see the first on their fallen behind, and it's actually phone behind enoughto where Rex, you're gonna need to create 1/3 layer of this that just noticed. So we'll actually see. So one of the things we actually just noticed is that we forgot to set the block layer for some of these blocks, and we probably forgot to set the layer for the foreground middle ground as well. So let's change these made ground in four grounds. Make sure we change the layer on these two background change the tag on them to background for all. For these, let's go ahead and save that. And under the pre fabs for these new blocks we created, we never changed them to be the layer blocks. So select out for them. Double check their on the blocks there. It's good. And save that and let's run another test, right? Yeah, One of the great things that the unity is again. It is quick to iterated through. So if you do find any bugs or notice any bugs, you can actually, um, fix them fairly quickly and you'll notice they never get the cleaner. Appears to be cleaning that up a swell and appears to be cleaning up everything like it's supposed to and move and everything along. So I know this looks like a really heard spot. It's probably gonna kill a bunch of people Right on. All right. It looks like a few of the blocks are still being missed here. So which block is this Block to is set to default. So we're actually gonna need to change this. So any changes you make, you're not gonna want to make any changes while the game is in play mode? Because if it is in play mode than those changes, air not gonna be saved. So we're gonna back out of here, and we're gonna set this to the blocks layer when we're not in play mode to ensure that any changes we make are saved. Um, there are some objects which the changes you make will stay. Um, and that's actually gonna be the next thing. We're gonna go over in. The next lesson is what is gonna be called script herbal objects. So script, it'll objects are going to be a bit different than game objects. And the way they're going to work is they're not actually going to need to be physically added to the scene at all. And what what that means is they're actually just going to be in the in memory for the game . So this is the perfect time to create a new folder. We're gonna create this one. We're gonna go to folder here, we're gonna make it underscore variables, and this is where we're gonna use those helper scripts that we imported in much earlier. We're going to right click on the variables here we're gonna go to create, and we're gonna create this new bull variable up top, and we're gonna name this player alive. So this player live variable were actually going to use to, um, determine if the player is, uh, still alive. Because there's gonna be things like, say, if the player dies, we're going to want to stop the background from moving. Um, things like that, uh, the background we're not probably gonna need to be using, but this will also be used to determine when the U I should pop up and pop up the game over screen or various other things. So let's go ahead and add this to the player. Let's go ahead and go to the floppy firefly here, goto player, end up at the very top. Let's just add in a new public variable player alive. So this is going to be used to determine if the player is alive. So let's go ahead and check this here and under the player. We're just gonna drag and drop this player alive into the players scripts wherever it is, right here. Drag and drop player alive in there. That's three. Enable a circle collider to before we forget. And some of the other things we're gonna wanna check for are going to be, um uh huh. Okay. Every time we start the scene again because this player live full variable isn't actually in the scene. It's not going to get reset with every scene. So if the player dies, if you close the game, the player alive, um, script, herbal object that we have created is going to maintain that player state. So once the player is marked is dead, it's going to keep the player marked as debt. So every time in the awake function, when the scene is first loaded, we want to set this player alive, and we're going to do dot value because we're setting the value of this bull variable back equal to true. So if we look under the hood here, this bull variable we looked at the code here. Um, this create asset menu is just the thing that allows it to when you go to that create object. You see that bull variable under there script? Herbal object notifies unity that this is in fact, descriptive all objects, so it inherits from scriptural objects. So it inherits all the methods that are under script herbal objects, so it's not going to be in the scene at all. But again, that means it's in memory. So it's state will persist between scenes and between loads and things like that. So here we have, um, just a, um, get set function set for the value itself. So when we set the value, um, of the bullets going to go ahead and set that value and when we want to get the value, it's just gonna return the value that's being stored right in here. So now that we have the player alive, we're gonna check this. Um, now that we are checking if the player is alive, we also want to be, um, checking if the player is alive before we handle any player movement. So if player alive dot value, this is going to check if the player is, in fact alive before it tries to move the player at all. So we can have that check for this. And then we can also have it checked for again under their own collision enter where it changes the time scale and says, Game over right now, we can have this set the player alive Value equal to false. So this when this actually occurs now, this is actually going to fully set the player to not alive. And then when we add the you I the u eyes constantly going to be checking if the player is alive and when they're not at that point, it's going to trigger the game over event and all the things that occur with it. Okay, so now that we have this and player alive, the next thing we're gonna want to add, we're gonna make another variable here, and we're going to make this foot variable. We're just gonna call this player score, so we're going to be starting to store a score for the player. And again, we're gonna want to, um, have the, um, player score stored here. And then we can also store a new variable. That's good. Said another variables. Well, cold player, highest score. So as we go, Teoh And as we go to implement the you, I were gonna want to have some sort of notifications. The player is getting a high scorer score they haven't gotten before, so we're gonna have the high score stored in memory as well. Um, And then that way, when a player gets a new score, it's gonna check it against the high score, and then it will display something different. If it is something they haven't gotten before, first thing we're gonna want to do we're going to go ahead and create a new script here. And let's just call this script, uh, start button. So we're gonna go ahead and create a stark button here. So go ahead, double click on this. Let's open up the script. So we're going to just have a you I button. It starts at the very beginning of the scene that the scene will be frozen whenever you first start the game until you click the start button, which will then, um, initialized the player and get them to start moving. So all we're gonna be doing with the start button is setting it to where the we're gonna make a new void here. Start game and we're just going to have it. Do is when the start button it's played. We're going to change the time dot Timescale equal to one. So when we first started seeing, we're gonna have it default to setting itself to, um, set the times guilt to zero. So let's go ahead and make a new public or another avoid a week. And during the awake, we're going to set the time that timescale equal to zero. So by setting the time skilled zero when we first start the scene, that will just ensure that the player isn't moving at all and nothing else in the scene will be moving it at all either. So when the start game button is hit, we're gonna want to start game button to hide itself as well as set the times guilt tow one . So what we're gonna do is we're gonna set the transform the local scale equal to vector 3.0 . So there's two ways we can go about, um, handling the why we can either have the windows scale themselves down. So in our case, we're gonna have the window skill down to zero. Or you can have the, um, start button actually just fully disable itself. I prefer to just use changing the scale for you element as opposed to fully disabling them , because if you are adjusting the scale on a large group of you elements at once. Um, it is less, um intensive on the processor than if you were to enable or disable a large batch of you elements at the same time, And the performance gains for having it in the background, skilled at zero are minimal as well. So let's go ahead and save this and let's go ahead and create our canvas within the scene. So the way the unity handles the U I is, if you just right click on the hierarchy here and go to you, I we're going to create a button the way that Unity handles the U I is using what's called a canvas system. So the canvas actually is in a completely different part of the scene, and it doesn't matter where is in the scene. It will always be paired to overlay over the main camera that is there. That's where these render modes come in handy. So if you wanted to be a screen space overlay or um, paired to a specific camera or paired toe worlds base, you can adjust that for our case. We're just gonna leave it a screen space overlay, so it's always going to be showing no matter what, We're not going to make any adjustments to pixel perfect or the constant pixel size under the scaler. We're just gonna leave this at one in 100. So underneath the canvas here, you'll see this button. We're just going to rename this to start button and then appear we're just gonna put this directly in the center of the screen. So if we change this position X and position, why both zero? It will center the button as well, because you'll see the anchor point for the button itself is actually in some of the screen . We're actually gonna just the y value on this a little bit. Just so it's underneath the firefly when we go to click on it. And then let's go ahead and to adjust the text of the button down below. You'll see the text value actually on the button it here itself So we can just go ahead and write. Start and let's change the color for text to a white here. And let's change the background color of the button to something else. Any color you want doesn't really matter. I guess I'm just going to use this blue green color over here. Go ahead. And it just the height to maybe 40 of the 30 and then under the text we can adjust this text as well. Let's I'm gonna increase it to about 22 if we want. We can actually had a shadow in here. So if you just type in shadow, you can make a new shadow on it. And I found too negative, too. It's pretty good for most standard text that we end up using in here. Um, just to get the button looking a little bit last year. So you can also have colors added on whether the button is highlighted or when you press it . In our case, the buttons gonna immediately disappear when you press it, so we're not really gonna make too many adjustments to it. So what we're gonna want to do is take the start button script and we're just going to drag it over here right onto the start button itself. And then once this script is on here, you'll see under this button script that automatically gets attached from a unity button. You'll see this event called on click. So this is what happens when you actually click on the button itself. And by default it empty. Go ahead and click on this. Plus here. So this will add a new event that occurs when you click this button. We're gonna leave it on run time only. And we're just gonna drag this start button script here, and you can just drag it right over here where it says none. And that will mean that when you when you click on the button, it's going to send something to the start button script. So if you click on this other drop down menu here, you'll see where it's a start button, and this will list all of the methods within the all of the public methods within the start button script. So the one we want is start game. So now when we actually start our game, if you go and save this and click start now by default, it should set the time scale to zero already. Everything will freeze in the second week. Like start, it will hide the start button and then the time will start moving forward as soon as we let go so we can go ahead and just have lose here and go ahead on because this the next thing we're gonna want to add is going to be a score. So let's go ahead. And you know what? Let's actually make the game over panel next. So let's make a you I panel here and we're just gonna take this panel and let's actually make it a bit smaller. So let's scale it in. Maybe 200 on, uh, 100 off the top, 200 off left and right, and maybe 100 from the bottom. Maybe 2 50 each side should be good. You can always change this later if we want to. So alternatively, we could also just instead of having it stretch, we could just parrot to the center here and let's just ah, we can just set the width and height to it to maybe for 90 by for 90. There we go. This will just be a full ban, a little cover up the whole screen and we can change the background on this if we want, or just go ahead and leave it. And let's go and change this to just a maybe a darker color. If you scale this Alfa Valley heroes. What will, uh, affect the opacity of the actual panel itself so can increase this to whatever we want? Let's go and change it to 25 for now. And on this new panel, it's going to rename this game over panel and let's go ahead and just create a button on this. Let's go ahead and create another button. Um, you know, it's actually just copy that start button here and just paste it right into the panel. Let's rename this to be retried button. So again, hovering over the start button, right click, duplicate or just take control D. So into this retry button, let's go ahead and remove this start button script and let's make another script now called Game Over Panel. So the game over panel so further along the line, the game over panel is going to be handling when the player scores calculated as well as displaying the high score. And if there's going to be like if the player is earning stars based off their performance , that will be handled in there as well. So for this panel, we're actually going to be looking at and following um, we're gonna want to know the the players. Score the players high score and if the player is still alive, So let's go ahead and make a public float variable. It's gonna be score. We're gonna make another public float variable, high score and then one more public, full variable player alive. So the way that we're gonna have the game over panel working is it's going to just be constantly calculating the score for the player. And then once the player is considered dead, that's going to immediately pause the game. It's at the time scale. It's going to immediately calculate the score at that point and then determine um, whether or not the player earned a bronze, silver or gold star. So let's go ahead and set an extra bull here called Visible. So we're going to use this to basically determine whether or not the game over panel has already popped up and whether or not it's already started to process the um, whether or not it's already started to process the game being over. So let's make a new void here called Game Over. This is what's going to be ran when the when the player actually loses, and they will make another public void. Uh, retry or reload scene. Because this boy is actually going to relate the scene. So, um, for the reload scene, we're actually just going to call. This is what's going to happen when we click that retry button from within the scene. This is we're going to actually call what's called seen manager, which I believe is under unity engine, don't you? I so we're gonna add a new using directive. Appears of you to state using unity engine dot You I This will allow the Heidi to actually see seen manager here. Seen manager show potential fixes not seeing seen. Manager still unity engine dot Seen management. Okay, so we need to add unity engine dot Seen management up here, not into the engine that you But we'll leave that for now because they'll lend abusing that later. So under here, we're going to use seen manager the load scene, and then we're going to load. Seen manager dot get active scene. Make sure you put the parentheses afterwards dot name. So what? We're actually loading here. Load seen actually takes in a string seen name, but since you may be using a different scene name for the main scene that we created. We're actually doing seen manager dot get active scene, which is going to get the scene that your act that is actually active within your game and then get the name for that and just return that and load that scene. So this is how we're gonna be reloading the scene when the player actually hits the retry button and then under update is where we're going to actually check if player alive dot value when we can do the equals equals true. Um, then at this point, we can actually have it, um, increase the score. But we also don't want it to start increasing the score before the scene has actually started. So we still at this point, we want to check if time that time scale is greater than zero. Then we want to apply, um, more to the score value. So begin to scored. Apply change and set time. Uh, Delta time times 100. So what this is actually going to be doing Is this just basically means you're gonna be getting, um, 100 points a second? Roughly, Um Yes, 100 points. Second. So, um, let's go ahead and then for else. So what we wanted to do if the player is not alive, we want to trigger a game over. So, um, right now, under the game over method, let's not feel that in quite yet under player here, we already set this to where it also it already is going to set the player to not be alive , which will then trigger the game over manager to, um, trigger game over. So we also want this to do else, if not visible or weaken. Do else, if visible is not equal to true. So this will check if the game over windows visible yet, and if it already is, it's not gonna trigger this again because the player is going to be still considered dead until we restart the scene. So then, under game over, the first thing we're gonna do is that visible equal to true. So this is just gonna let us know that we've actually started to display the game over panel and then also started to, um, display the game over windows. So the last thing we want to do is under transformed on a local scale. We're gonna set this equal to vector 3.1. So back to 3.1 is just a vector three of 111 which for in regards to scale, it's just the default scale of every object. And then here in the middle is where we'll actually handle all of the score components where it will actually store the score value and the high score value. So we're not going to sit that yet. Let's just go ahead and test this to make sure this is working out. We want it to let's go ahead and save this here. Go back to our game. Now that we have this game over panel script created, let's go ahead and drag this over here on to our game over panel and then for this retry button, we want a Rinne. We want to adjust the text on this to actually say retry so that we know when we actually click on this, it will retry the level. And then for the on click on this button, we're actually going to have it. Look at the game over panel here, its parent object, and then so we're just gonna drag the game over panel onto this. Click rights is no function. Select came over panel and reload scene. So go ahead and save this. And then by default, we want the game over panel to actually be at scale 000 for the game over panel script. Here, you'll see we don't have anything declared yet for these variables. We can either click this little circle here and just drag select the player scored double click it. It will fill it in. Same for player, high score and player alive. We can go ahead and set that here as well. Go ahead and save it. So one of the other reasons, or one of the other things that we can accomplish with the setting of using setting the scale to zero, as opposed to fully disabling the panel, is we can have this script running, but it will be running in the background even though we can't see the game over panel. But if we were to fully disabled the game over panel, this script wouldn't be running or calculating at all, so we would end up needing to put the script on another object within the scene. Um, in that case, that's where you'd use, like some sort of you I manager or you, I operator, that you would put on the canvas that would handle all the other panels and windows within the scene. Some of the other projects we do moving forward will end up including that. So in our case, though, we're gonna go ahead and leave this enabled and ensure that we have the values for score, high score and player live selected here. Make sure you set the scale to 000 for the game over panel. And then let's go ahead and hit play. Let's test this to make sure this is working for us. Go ahead and hit. Start Tragic. Eight. You are Firefly to crash immediately, and it will pull up the game over panel window here, and you can just go ahead and click. Retry and you'll see that it restart the scene. You could just start the whole lip over again. Here we are. Good and this let's actually add some game over. Text here to the panel. Go ahead and right click and gave over Panel under you, I Let's add some new text. It's changed this game over panel scale toe one by one. What we can actually do as well to make it easier to manage is under this game over panel. If we go back into the script, we can actually set, avoid awake and we can actually set this Teoh transformed at local scale equals vector 30 So we can just set it toward automatically hide itself whenever the scene starts so that we don't have to keep enabling and disabling it repeatedly as we move through, um, and build heard and set up this panel here so we can just name this came over text. Let's go ahead and I mean it's game over. If you look down here under the paragraph alignment, we can, uh, align this in the center here, change this color toe. Wait, It's good. Make this really big. So the player definitely knows they lost under with. We can actually adjust this make This is why it is we want to make it is white is the panel itself, which is for 90. And then we can increase the font size. We need to increase the height as well. They can change us to 200 or something. That's a little bit overkill. It's changing 200. All right, So, Weaken, increase the font. Here. 50. Seems good. If you look over on the scene view, you can actually see, uh, you can actually just drag it directly from the transform here. We can't even center it here to make it a little bit easier toe. We're going to get exactly what? For now, Let's just go ahead and put it over. Your near the top came over and then go ahead and save this. When you hit play, the panel should automatically hide. All right, So the last thing we need to add now is let's actually add the score up in the upper corner . So let's go ahead and add a new text here. We're gonna put this up in the corner. Let's call this score label because this isn't gonna be the the text that actually holds the score. This is just going to be the text that says score. We're just going to set this up in the corner here. So let's change the anchor up to the upper left over here. He reset these positions back to zero. You'll see it snap over here to the corner. We're actually going to increase the size of this text. So it's changed the height to 50 and that's increased the font size toe, maybe 25 seems good so we can take this score here. We're just gonna go and save this and then let's go ahead and actually duplicate this. You just select it. Control D we'll create another one. Let's go ahead and have this be put in a test score in there. That's a very big test score. This will be score. So one of the other scripts that we included is what is a one of the other script? Herbal objects we included here under the helpers, um, is a float to text center. So what this is gonna do is if we click on the score here and click add component. I've been float to text. We're just gonna add this script here. What this script is actually going to dio is it will, um, consistently update the text of this equal to whichever float variable we have. So in our case, we're going to be setting this to be the player score and then under text. We're just gonna click where it says text appear and dragger. I don't in here. Just make sure you check the box for always update. So it's gonna consistently look for whatever the players score value is and then set itself to that. So one of the other things we need to dio is in the awake method. We also need to make sure that we're resetting the players score back to zero at the beginning, at the scene every time. So we're going to set scored value where we're going to scored outset value. Rather, we're just gonna set the value to zero. So we're just passing in the value zero here under set value for the score. And this will actually set the players score 20 every time when we start the scene and then we go ahead and go back to our scene. Now, let this go ahead and load and save the changes we made. When we start our scene, we should see this score reset to zero. And then as we start to play, we'll see the score, um, starting to go off. So you're gonna notice here that it's actually including a bunch of decimal points, and the reason why it's including decimal points is because we made a mistake. So let's go ahead and go back into our code here, and we're gonna change this update to fix update. So we just we need the this to be occurring during every physics sick. That's normal so that it ends up landing on hold. A whole number values. So let's go ahead. And once that's been updated, go ahead and hit play here, and we should no longer see this displaying decimal points. Perfect. Okay, now, when this is over, the score will actually stop Game over. Riendeau didn't pop that time for some reason, but let's go ahead and just processor. Now I know why that's not doing either. So now we need the time the time scale to be set to zero in the game overseen instead of on the player because the physics fixed update checks will not occur unless the time scale is greater than zero. So if we go back to our player script before we were setting the time scale zero because we were debugging in the game over function because we hadn't implemented it yet, but we can go ahead and actually remove this code. Now we can leave the Debo code in there and go ahead and save this to make sure that the game overseen is properly popping up when we actually lose. So let's go ahead and hit play here, and then when we hit start, we'll actually see the score. But going up here and now we can just hit the ball. And there we go now, the game over scenes popping up like it's supposed to, and we can go ahead and history, Trey. So that's gonna be it for today's lesson. In the next, we will fully finish the game over panel to include the players. Score a notification if it's the players new high score as well as implement, um, stars. Basically a star rating for how well they did, as well as implement the final game mechanic that we're gonna have for this game and wrap up the entire project. See in the next one 10. Final Game Polish: school under one. Welcome back today. We're going to go ahead and complete the game. We're gonna finish up the game over panel to display the players score as well as a notification if they have a new high score as well as give them a star rating based off of the performance that they did, Um, this is a good point to demonstrate why we're using the's descriptive, alas, rescript herbal object float variables. Because by using a script herbal object, what we can do is ensure that, um, we can easily test the components that we after the panel as well as ensure that both panels are being updated. Um, without having to write a bunch of extra code to make sure that these are, in fact, updated. So on the game overseen here, we're gonna go ahead and add a few new things. We're gonna add a image. So we're gonna add a u I, um, image here. Let's go ahead and set these. Let's go ahead and go came over. Penhall. You I image Let's go ahead and move this up here. We're gonna have this actually be the star rating that you get. So if you click the little circle here we can go and set the Bronze Star by default, and this will be the score metal. We'll name this here in the game over text. Let's go ahead and bold this real fast said. That's the bold when we can give it a drop shadow as well. Good click Shadow. Make this too negative, too. Helps it pop a little bit. And then for the retry button, let's go ahead and slide this one down because we're going to be adding in the score and the high score into this as well. So let's go ahead and add a couple more text objects. So let's take over the game over text. You can just, um, copy this and we're going to go ahead and drag this down. We're gonna set this to a line to the left, since we're actually going to use this to write, score slower the size on this to maybe about 36. Sure, 36. It's good. And then let's add one more. For this will be the score score text label in the ad, the high score text label. So let's mean this other one high score text label. And let's go ahead and write high score for this one. And then we're actually going to, um, have a, um, have another score and high score object that is going to be reading the player I score and player score, um, variables. So let's make this new, and this is just gonna be score. Name this one. Score here. Go ahead, move this over. Just go ahead and type some numbers so you can get it filled in at first. Then we're gonna have the float to text center again. We're gonna set the text to this. Check the box rollers update, and the variable for this one is going to be the player score. And we can go ahead and duplicate this drag down and go ahead and lined it up with the high score double check the position the Y position to verify their both at the same to seek and assure their properly lined up. Rename this one down here too. High score. And then for this one, we can check this box here, make sure this is set to the player high score, and then the last thing we want to add, what at, um, a new little text here. This is gonna be the new high score text. Let's move this over. Let's make it say new. We're gonna have this pop up right above this new score. Here, it's good. And shrink this down a bit. Andi Yeah, Let's have a good and show appear. Let's have it show up in a bright color. That's maybe making a really bright blue. Here we go. We're gonna get this to say new. So we're actually going to do is we're going to have this notification that it is a new high score. Onley pop up When, um, the score that the player just got is in fact, the new high score. So we're going to go back to our game over panel here, and we're going to go ahead and we're gonna edit this code and we're gonna add the values for all the new fields. We just added. So on here, we're going to at a new um, we got a new reference to the, um, metal image. So we're gonna add a new public image. We're gonna call this metal image. So this is what we're actually going to be setting. This will be the reference to the image that we created that as the Bronze Star right now, because we're going to need to change that image depending on what star the player actually got. So we're gonna add a public Sprite. We're gonna set this to Bronze Star, another public sprite for Silver Star Public's Bright Gold star. And then we're gonna add the values that we want to be the thresholds for win. Um, the player will earn these other metals, so it's make a public event. Gold men score public and Silverman score and a public and Bronze Men score, All right, and then we'll add a public text, which will be the new high score label. So this will be that that text that we made that just says new with an exclamation point on this will check to see if the player did, in fact, get a new score. So now that we're going to be having this high score displayed on the came over panel, we're going to want to save the players I score so that whenever they start up the game again, this value is saved. So unity itself has a built in um, area of memory that your program can use called player preps. So this is basically one of the places where you can store player preferences. But you can also use this to store values such as high scores or other user data. It is edit herbal by the players, so we're going to use it for stuff that we're not that worried about or we're not, you know, worried about players cheating by making changes to it. This is a very, um, this isn't a competitive game, so it's not as big of a deal if we just use player preferences and further lessons will use something else that is more a bus vacated to ensure that players can easily cheat. So the player press file you can either story value or access a value based off of a single string value. So we're going to go ahead and do and if check and we're gonna look check if player preps dot has key and we're going to check for high score. So this is going to check if the player perhaps already has a high score in it, and if it does, we're going to set the high score dot value Eagle two player preps dot get float. So when you are pulling a value from player breath, you have to define what type of value it is. Since this is a float value, we're going to get the high score. And when we first start the scene, it's going to grab the high score that it saved. And it's going to set that to the high score so that so that it stored when it's pulled up . And then, uh, if it doesn't have a high score value than its if this is the first time that the game has been ran, it's going to go ahead and set that as they knew. I score. So it's gonna do a player, press stopped, set, float, and then we're going to set high score and we're gonna go ahead and set it to zero. All right, so now that we have this high score set at the very beginning of loading the scene, the other things that are going to be occurring are all going to be occurring during the handling of game over here. So we're going to have it, um, check things depending on the score. So, uh, if we're checking a value for the score, the way that we're gonna want to do it is check for the gold score first, and then if it doesn't meet that threshold, then it's gonna fall through and check for the silver score. And then if it doesn't meet that, then it will just fall through and default to the Bronze Star. Um, which means we don't actually need a Bronze Star. Men score here, So let's just go ahead and remove this up here. So let's go ahead and do it. And if scored up, value is greater than the Gold Men score, then we're going to take the metal image dot Sprite, and we're gonna set it equal to the gold star else. So the reason why we want to ensure that we use else is so that if it said it sets it to the Gold Star scorer than it doesn't start to check the other values. Because if it matches a Gold Star score than it's gonna match all the other ones as well. So this is going to be in else if scored out value is greater than silver men score we're going to set the metal image that Sprite equal to Silver Star and then else So if it doesn't match the 1st 2 criteria, then it's just gonna default. Teoh equals Brown star. We're just gonna defaulted to the Bronze Star here. So then the other thing is, we want to check if the, um if the score dot value is less than the high score value, then we're going to hide the new high score label. So we're gonna set the transformed at local scale of the new high score label and we're gonna set defective 3.0 and then else if it if it does, um, if the score is higher than the high score value, then we're going to set the high score dot set value. Um, we're going to set it to the new score value, and then we're going to save it to player preferences player press dot set, float, high score. And we're gonna set this equal to score dot value. Go ahead and save this and we need to actually take this transformed at local scale where we actually display the game over panel and we're gonna want to go ahead and cut this and move it to worry about him. Because you want to handle all the processing of this stuff first before we actually display it. Um, and then we can go ahead and say this and let's go ahead and go back to Unity here, and we're gonna have quite a few values to actually set in this game over panel here now. So for the metal image, we're actually going to go and click on this and we'll see the score. Metal double click this for the Bronze Star. It's good. And back out. Cook on the Bronze Star, Silver Star. Let's go and said this here to Silver Gold Star. Let's sit at the gold and for the gold minimum score and the silver minimum score, we consent him to whatever we want. For our sake, let's just said it, um, 5000 and 3000 for now. And for this new high score label, make sure click this year and said it to the new high score text. Here we go. This is the new high score text, so this will be hidden when it's not a new score. So let's go ahead and give this test. Let's go ahead and click the play button now that should automatically hide in Let's go and get started. So as we see as we're playing through, we can get it to savor score. And as we see here, it is gonna pop up this new high score. Here we can go and click, retry and test to see if the next time it's going to show a new high score as well. Just to make sure this is properly working. Go and click, retry. Crash immediately, and we'll see here that it does retain the high score that we had. We can even exit out of play here, and it will. The discreditable objects will store this value still. So these air sorting here. But this is also stored in player preferences as well. So because this these will actually be cleared out every time the scene is actually, um, when the player is playing the game, these will be closed or modified it basically back every time the player closes the game. What we're gonna want to do is again pull the values from player preferences and load them into this script. Herbal object. So we can go ahead and testis again just to make sure these air still in here. And they are 7 46 Okay, try. It's good and close out of it. So the last thing we want to do for this is we want at our own little twist on it. We don't want this to just be, Ah, another flappy bird game. So what I want to have us do is we're going to add an effect that actually will slowly start to black out the screen as the player goes further along and there will be little balls of light for the firefly to grab. And every time you grab a ball light, it's actually gonna lighten the screen and, um, give you, like, tore, you can actually able to see again. So first things first, let's go ahead and go down into our variables here. We're gonna make a new variable here, a new float variable, and we're gonna call this darkness. So from here, let's go ahead and create this darkness value here. And then let's go ahead and go to the canvas. We're gonna add a new So if you right click here, go to you why we're gonna add a new, um, image. And this image is just gonna have no sprite, and we're just gonna make it all black. And they were actually going to just set this to scale across the entire screen. So if you select this one in the lower corner, you'll see the blue arrows. That just means that it scales on all directions and we're just going to set all these margins to zero. And then what we're actually going to be doing is the darkness value that we saw before is going to be controlling the Alfa value of this. So as the um, as the timer goes along, if the player is and picking up balls of light, you'll be seeing the screen get darker and darker and darker and the player of able to continue until they actually crashed into something. So we're going to go ahead and leave this over here like this now and let's go ahead and rename this to Darkness. Then, from here, let's go ahead and create our light block. So if we click on the textures here in the Blink month sprites, we should have a new light here. We can just drag and drop this right into the scene. This will be our light object. Here. Let's go ahead and give this a box collider to D. Okay, Component. We're gonna give us a box collider. We're gonna set this on the blocks layer just because we want to ensure that it's still being hit by the, um just to make sure that it's still being hit by the, um, light, um, object there or by the cleaner Rather. And then let's go ahead and click on add tag. And let's give this a special tag so that when the player hits it, it will play a special sound. So let's just go ahead and save this new tag layer is light and then go ahead and click back on the light again. We're going to set its tag toe light. The last thing we're gonna want to do is we're actually going to make a new script, and we're just gonna call this script late. Oh, actually, that's gonna create an object. So let's just delete this and we'll just call this the light controller for light Operator . It was called light operator. There we go. So you'll notice there's air, actually a few different built in, um, class names that are handled by unity that will control different things as we just found their like dot CS will make a light object. And then if you make a game manager, that CS that will be handled separately by unity as well in a special way. So let's go ahead and go up here now. So the light itself is going to be treated, Um, thesis, aim as the, um it's going to be treated the same as a normal block. So we're gonna store a transform player. We're gonna story, transform block, and we are going to We're not actually gonna start back. We're just gonna store a transform player in a block generator so that we know the position of the block generator so we can move to it whenever we actually need to. Okay, so from here and then we want to have a reference to the darkness float variable, and we can make this public. And then we will also store a block number so that the, um so that the light objects know roughly where to place themselves. So if we want them to, um we want to ensure that they're always staggered. Um, just the same way how we're doing it with the blocks where they're gonna be staggered based off of their block number. And then we can make a new public float light generated when we can set this equal to, uh, let's just set it 2.2 for now. So we can just have the Alfa value still be handled on a scale of 0 to 1 so we can go ahead and remove these other things here, and we're gonna add a public void, spawn and set block number. So this again is going to set the block number for the light. And then we're gonna store the player transform player. We're gonna set a transformed for the block generator, and then those will be it. So we're gonna set the block number, go to underscore block number. We're going to set the player equals a player block generator, equal to block dinner, and then we're going to Dio is we are going to set the position of the light based off of the, um, block number. So we're gonna make a new Vector three here called position. We're just gonna set this equal to the transformed up position of wherever the light is by default. Then we're going to set the position dot Exe people to the player dot position dot exe plus 1.75 plus the block number. So you'll notice before on the blocks We were moving this by 1.25 So this is gonna offset and will insure that the blocks are that the light objects are appearing right between directly between each level of blocks. And then we're just gonna set the position that why equal to unity engine dot random that range between 0.40 and two. So these values can be adjusted if we want to have the light objects be able to be generated closer to the ground or closer to the ceiling. We can adjust those numbers later. And then once we're done with this, we're gonna set to transform the position equal to P. O S to the position. So this will handle when the block number is actually set. So what we're gonna want to do here is we're gonna do a void on trigger Enter two D, and we're going to be looking for the, um, collision here. So if the collider dot tag equals player and what we're gonna want the light object to Dio , let's go ahead. And this is a collision. We're going to have it. Um, we're going to have it set the renderers on this object to be disabled so that the light object disappears without actually disabling the game object. So we need to ensure that we're just disabling the render. The render component is something get that gets attached to any object that is actually rendered on the screen. So the sprite itself for the image. So what we're doing is when we pick up the light object, it's going to, um, quit rendering itself. And then it is going to, um basically, wait, um, you know, 3 to 5 seconds, and then it's going to just re enable itself afterwards. So, um, once they like, object is picked up, we're going to get again. Said it to disable itself. We're gonna set the darkness stop value minus equal to the light generated. So because we want the darkness levels to go down as the lightness picked up, we're gonna lower this And then we're going to do what is called an invoke. So invoke is going to, um basically, this is going to call another method after a given amount of time. So in our sake, we're going to call the method enable render, and then we're going to set this to three F. So after three seconds, then the light object will re enable itself and be ready to be picked up again. So let's go ahead. Make a new method appear Call this void, enable render. And then let's just do a get component Brender picture. Put the parentheses out the words dot enabled. We'll just set it back to true. And then we'll do another one else. If collider dot tag equals cleaner collision, then we are going to call a move function. So let's call move on. Let's go ahead and create this same move that we had similar with what we had with the other, um, blocks. All right. And for the movement, it on the light operator, we're going to set Vector three position equal to transform the position we're going to set position dot X equal to the block generator that transfer, uh, position that X and then for the position dot Why we're gonna set it equal to, you know, the engine random range euro 0.40 to 2.0 f and then we're going to set the transform the position equal to position to us. Go ahead and save this. All right, So now that we have the light objects actually looking at the darkness value, we're going to go back to the player camera. And this is where we're actually going to modify and handle the darkness values. So we're gonna make a reference on the player camera to the darkness. Uh, float variable. Make sure we spell this correctly, and then during start, Rex, we're gonna set the darkness stop value equal to zero. So we're gonna reset this the very beginning of the scene and then during the fixed update frame. Since we want this to occur at a fixed amount, we want this to occur during every physics check. We're going to check if the player is alive. We're gonna actually need a reference to the player life. It's a public pool variable player alive. So if player alive value, this is again going to check if the player live dot value is equal to true, then we're going to increase the darkness value by timed, fixed out of time divided by 15. We're just gonna and this here darkness, duct value plus equals there ago. So I never would say else we're gonna set the darkness, stop value equal to zero. So if the player has died, then we want to change the darkness value back to zero, so you can actually see the U elements on the screen. So from here, we're actually going to make another reference for darkness here. We're gonna make a public image which will be under we need to add a new using directive using unity engine you I public image, um, darkness image. And from here is where will actually apply that darkness value to the darkness image that we created before. So darkness, image dot color We're gonna set it equal to a new color. We're just gonna leave it a 000 and then for the Alfa Value, this is going to be set to the darkness. Stop value. So this is going to be on a scale of 0 to 1 for the, uh Alfa component. So that's why with it going up, um, as it does where the light blocks are basically lowering the darkness value by 20% or by, um, every single time, and then it will be going up at a fixed rate, has it slowly starts to get darker. So let's go ahead and save this here, and we're gonna go into the block generator now, where we're actually going to have this be spawning, um, lights as well. So we need to add a new light number for the lights when we're gonna set the secret one. And then let's go ahead and make a reference to the light object here. So public game object light. So this is gonna be the light game object prefab that we actually used to spawn lights. So we can actually just add this under the blocks to generate because we actually just need a light to be spawned in between each one. Um, so we can just go ahead and just name this light Geo. So this is a new light game object. Do game object In stan, she ate, uh, light. So we're gonna stand. She ate the light object then we're going to do get component on the new light we just created. We're going to call the light operator script the randy to despond and set block number. We're gonna set this to the light number. We're going to pass in, um, the player. So we actually to make a reference appear to player as well. So, public game object player, we're going to pass in the player. The France and the transform for this game object here, so there's gonna be the player. So it's to a public transform player. There we go. So we're gonna pass the light number of the player and the transform, and then we need to be increasing the light number after every time we create a new light, we need to increase the light number so that the next light gets the proper light number Touch to it. So let's go ahead and save this here. And let's take our life that we created Go ahead and save this into pre fabs appear under the camera. We need to make sure we add the's references to the darkness and in the darkness image under canvas. Here we can scroll down and find the darkness image. And then we got to make sure we select the reference to player alive as well. And then under the lock generator, we have you, We need to make sure we add reference to the light as well and then a reference to the player. So if you just take the player here and just drag and drop it right onto the player transform here, we can see this. That's what we missed the darkness. Um, you I Layer, we want to make sure we uncheck this box for Ray cast target because by having this be a rake house target since it is on top of the other elements, what is happening is that it was showing up. Um, is it was basically showing up over the start button and the other things so that when you go to click on them, it was hitting the darkness layer instead. So let's go ahead and save this and hit play. Make sure this loads that ever go. Now we can click the button. And as we can see, that screen is starting to get darker as we go through. And then we can actually still pick up our light objects here, which makes it light again on. And if we look over here, we can actually see the Alfred getting darker over time as well for each light object we're picking up so we can save this going click, retry and making go ahead and reset this. So if we wanted to ensure that the darkness panel was actually underneath the start buttons , um, instead of even having to adjust the sort layer if we actually just dragged us to the top of the canvas, this will be rendered before everything else. So it's gonna be rendered from top down. So whatever is on top, the next thing down will be on top of that, and vice versa. So if you see the start button here, the game over panel is below it. So that's why the start button is behind it. If we move this above this, you'll see the start button popped to the front again. Just leave it down on the bottom because it sort of hides itself anyways. So let's go ahead and save this. And the last little finishing touch we need to put on this is let's go ahead and add some clouds that kind of float by in the background as well. So we have a couple different clouds here that we can actually use. Uh, for our sake, let's just go ahead and make, um Let's actually just create all three of these for mine. I'm going to use thes misty clouds. You can use the other ones if you want. It doesn't really matter that is going to be up to you. Which one you want to use for your game? So for these were going to go ahead and save, um, let's actually make a new script here that we're actually going to use to move the clouds. So we're gonna make a new script here. We call this cloud mover. We're gonna load this up. This is gonna work similar to some of the other objects we were moving before, Where we are going to take a, um, reference to the, um, block generator. And use that to reset the clouds position as well as, um, so let's make it public. Transform lock generator. Um, well, we can actually have this pirate. It's fine. Well, just make a new void here, Um, or in a public void spawned cloud. We'll pass in the block generator to the cloud as it spawned. And then what Will dio is We will actually set the move speed. So let's make a value for moose feed your vector three move speed. Well, actually, set the, um, x value speed of the, um of the cloud equal Teoh random the range. Um, so we can make it negative 0.3 to 0. So this will just insured again. The cloud is going to be moving. So some cloud will be moving faster than others, just so that they kind of uncomfortable cells and kind of do some cool things as they're moving along. So we're going to make a fixed update here and during this is where we're actually gonna just the transform that position, we're gonna plus equal it to move speed. Um, times time dot fix delta time. And this one Sure that this is, um, moving basically at a consistent speed as we go through. And then we're gonna add a non trigger to D. This is where we're actually going. Teoh, check if it hits the cleaner again. If collider toe tag equals cleaner, this is where we're going to reset the position of this. Um, we're gonna set to transform that position. This is collision collider. Uh, the position dot Exe We're gonna set it equal to the block generator that position dot Exe And then for the position that why we're going to set it equal to random, the range we're gonna set anywhere between 1.8 and 2.4. So this should make it sure that it kind of shows up at the top of the screen, They'll be in the back, so they're not going to get in the way, the player at all. And then from here, we can actually adjust the move speed as well again, if we want to. Go ahead, lose be dot Exe Set it to random. That range Negative 0.3, float to zero again. And then we'll just set the transform that position equal to P. O s. The last thing before we move on from this cloud. We were a script. We need to ensure that we set this block generator, um, equal to the new block generator, that value that's being passed in. So it's actually a justice toe. Underscore block generator and set block generator equal. Teoh, underscore Block Generator. So another way you can actually do this. If you are passing in a value that is the same name as a, uh, global value that is set in here, we can actually set this thought block generator, Which will be This is the reference to the actual global variable and weaken. Set this stop block generator equal to block generator. So this will. This value is going to be the global variable, the one that's highlighted here. And then this variable is going to be the internal variable that is highlighted here. So let's go ahead and save this and then we can go ahead and move on to the block generator and we can go ahead and creating. We're gonna do another list up here of game objects and these air going to be clouds. We're gonna make a list to our clouds in their block generator again. And the last thing we're gonna want to do is let's get a number over here public and clouds to generate Well said that. See Goto 20 for now and then under this awake function, we're going to do another Luke. So for anti equals zero eyes less than clouds to generate Hi. Plus plus is gonna make sure we spawned the exact number of clouds we want and we're going to do the same thing. So, uh, we're gonna do an int cloud to generate, said it equal to Rand next, and we're gonna go between zero and clouds count. So this is gonna pick one of the clouds at random. We're gonna make a new cloud. So game object cloud equals game object that in Stan, she ate clouds cloud to generate. So this is going to give us the index of which cloud we want to generate. We're gonna make a copy of that right here under cloud. And then from here, we can do the float. Cloud height equals random dot range, um, 1.82 to put for, And then we're gonna dio a, uh, float Cloud distance is equal to random. That range 3.35 and 15. So this is going to distribute the clouds up above, um, from when we basically first, um, spawned the clouds. So we're gonna set the cloud transformed up position equal to a new vector three where the height is going to be the cloud distance. Then we're going to set the cloud height to the Y value. And they were just gonna leave the Z float at zero here, then do the cloud dot get components the, um, cod mover. And we're gonna do the spawned cloud. And we're gonna past the, um, the cloud generator or the block generator. Other, uh, transform way. All right, so we can go ahead and say this year What? Go ahead and make sure that we go back to the scene here under the block generator. We need to make a reference to these clouds. So let's actually create the club. So it's looked all three of them. Make sure we add the cloud mover too thin. And then we're actually going to add, um, box gliders to all of them bucks glider to D or didn't make sure we set to miss triggers as well. And then for the weekend said Thies to the box layer can go ahead and Markham there and then we want to do is the order in the layer. We actually want this to be a negative four. So if you remember, we have these other layers here. Let's make sure this is for all of them. Did the sky, ground and background and other things. They have different layers. So the clouds are going to show up in front of the trees and such, but not in front of the blocks or the other game objects. So let's go ahead and save this year for each one of the clouds. Go ahead and just drag and drop it into your pre fabs over here, then to go into the block generator. Um, from here, if you want to actually drop multiple items into the block generator once, If you actually click this little lock button up here, you'll see this actually luck. This will leave this block generator selected. So from here, if we actually select all three of these clouds at once, we can actually just drag them right here on top. Words. Those clouds and it will add all three of them to the list for us so we can go ahead and say this now and let's go ahead and give a test and see if these cards are showing up how they're supposed to from here as we start, we should see the clouds there in the background, kind of moving along. And as we can see, they are behind the blocks and they do stop with everything else when the game freezes. But as you could see, there was quite a bit of clouds here on different layers. If we want to, you know, do a little bit less, we can do that. The last thing we're going to do now is thesis sound effects for the player, so we're going to have a few different sound effects in here. We're going to have one for when the player flaps their wings, one for when they crash into a block or the ground and then one for when they pick up a light object. So let's go ahead and go appear to the top of the player script. We're going to add a public audio source, so this is going to be the player audio source here. And then we're gonna add a new public audio clip, and we're going to add the player flap Public audio clip, uh, player crash in public audio clip, player light. So now that we have these here, we can go ahead and at these into where we're going to want to put them. So under, um, did flap, which is basically when it triggers. Whenever the player actually did click down on the screen to, um, flap their wings, we're gonna go ahead and pullup audio player audio source dot play one shot. So play one shot just means it's going to play this sound one time. We're going to do the flap player flap, and then we can add 14 under here under the player so we can do if a collision glider tag, um equals light, then we'll do audio source. Player out your source, play one shots light, clear late, rather player lights. And then we'll just change this to be in if else would be, if else, if rather so else. If the collision is basically not the sky, then we will do the player audio source. Play one shot crash player crash. So here now. So it's going to first. When the player hits something, it's gonna first check to see if it was, um, a light, and if it was a light, then it's going to display the light, sound and if it was the, uh, ground or something else, then it's going to play the actual crash sound. So let's go ahead and save this and let's go ahead and go back into our scene over here and let's go ahead and test it. So as you start now, we should. That's good. Positive action at the audio source to the player. So have our audio source here. Let's go ahead, and we're gonna want to lower the volume, probably down to about 0.3 or so The volume it's actually tried 8.5 and see how lot ISS and then we can adjust it from there. All right, so once you have added the, um, audio source and, um, audio clips to the player, we're going to go down here and you're going to just go ahead and click at Component and at an audio source to your player. And then once that's been done, we're just going to click right here to add the player audio source. Select player under the player flap sound. We're just gonna add the flap. Sound player crash will add crash sound and clear light will add the light sound. Go ahead and save these on. Let's go ahead and press play to see if this is triggering for us. So now we can hear the flapping sound that's we got to pick this up. We'll see if we hear the light sound. That one is not figuring. And I actually know what. So the player here, we're actually going to add a new, um, void for the light itself. So we're gonna do a Boyd on trigger Enter to D, and this is where we're actually going to handle the The light collisions were not going to be checking for a collider on this one, so we can copy this removed else. And let's just make sure this is here and will make sure we're just checking for the collision dot tag on the light because there's no actual collider involved. Just triggers the collision for this one. For the tag, we can save it on. Let's go ahead and test it That play. We'll see if says you get this one picked up now. No, we get that beating when we actually picked up the light. No,