Unity Development - Create Your First Platformer Game! | Tirion Learning | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Unity Development - Create Your First Platformer Game!

teacher avatar Tirion Learning, Software Engineer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Class Trailer

      0:46

    • 2.

      Lesson 1 - Setting up our scene

      15:24

    • 3.

      Lesson 2 - Creating our character

      8:00

    • 4.

      Lesson 3 - Adding player movement

      24:28

    • 5.

      Lesson 4 - Introducing prefabs

      20:10

    • 6.

      Lesson 5 - Generating our map

      32:06

    • 7.

      Lesson 6 - Adding sprites

      24:52

    • 8.

      Lesson 7 - Animating our characters

      22:04

    • 9.

      Lesson 8 - Adding more interesting enemies

      21:30

    • 10.

      Lesson 9 - Introducing hit detection

      19:14

    • 11.

      Lesson 10 - Adding player health

      18:11

    • 12.

      Lesson 11 - Introducing gems

      25:11

    • 13.

      Lesson 12 - Creating a game loop

      16:05

    • 14.

      Lesson 13 - Saving our game

      6:42

    • 15.

      Lesson 14 - Improving visuals

      41:09

    • 16.

      Lesson 15 - Creating a starting hub

      22:16

    • 17.

      Lesson 16 - Adding sound effects and music

      28:45

    • 18.

      Lesson 17 - Final touches

      20:47

    • 19.

      Lesson 18 - Building and exporting

      7:51

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

310

Students

6

Projects

About This Class

Hey there, and welcome to my class on creating your very own platformer game in Unity!

In this class, we'll be developing an intermediate platformer game from scratch, and learning all the basics of game creation in the process! We'll be using Unity and C# to develop our game, and will be covering all you need to know about getting started with game development, from the basics of coding to all the specifics of our game engine.

Over the last few years, I have created and released several games, for mobile, web application and PC platforms, entirely on my own. Now, using the skills I acquired, I have created this as one of several, complete classes, covering the basics of game design, in the hopes that you are able to easily enter the world of game development yourself, by taking any one of these!

In my experience, game development can be quite intimidating to beginners, and running into issues, and spending hours or sometimes even days searching the web for simple ways to overcome them can be a bit demotivating. As a result, I created this class, which covers everything I wish I had known when I started game development, so that the process is much less tedious for you, no matter your prior experience.

After completing this class, you will have gained all the Unity and C# knowledge you need to begin creating your very own games and apps by yourself! In addition, you'll learn several more advanced concepts of game design, such as map generation, audio management, sprite animation, and much more!

This class will cover everything you need to know to begin creating your very own games in the Unity engine, be they for mobile, PC or any platform!

If you choose to enrol, you'll learn a valuable and in-demand skill, and have fun while doing so. I hope I get the privilege of teaching you.

Have a great day! :)

Meet Your Teacher

Teacher Profile Image

Tirion Learning

Software Engineer

Teacher
Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Class Trailer: Hey there, and welcome to my class on creating an intermediate platform, a game using the Unity Game engine. In this class, we'll build from scratch the game you're seeing right now. And in doing so, learn all the fundamentals of game design and development, including everything you'll need to know to make a game exactly like this on your own. This class will be split up into 18 videos, each covering a different topic of game design and a new stage in our games development. From getting started with writing code all the way to particle systems and audio management. By taking this short six hour class, you can in less than a day, learn everything you need to know to start developing your very own games and Unity. For more information about this class and its format, check out the other class trailer below. And I'll see you in the first lesson. Cheers. 2. Lesson 1 - Setting up our scene: Hey there, and welcome to the first video of this course on building an intermediate platform, a game using Unity. Now, before I begin, I just want to say a huge thank you to you for your support in enrolling in this course or class. It's support like this that allows me to continue to make courses. And I really do appreciate that you chose mine. Now if you've watched the road map, you'll have basically seen an overview of what this course is going to entail and all of the different videos and sections we're going to be having. You'll also have seen the game that we're going to be making by the time this course is done. Hopefully, this game looks pretty cool and you're excited to be able to make a game like that. If it looks complicated, don't worry, it isn't actually that complicated at all. And you'll be quite surprised at how capable you are to make a game like that. Not that much time at all. Now that being said, obviously making a game does take a little bit of time and we can't make it all in one video. All we're going to be doing in this lesson is we're going to be introducing the Unity editor. And we're going to be creating our scene to set up where we can start making our game. Now if you've never used Unity before, I do suggest you watch this entire video. If you've used Unity a little bit and you actually understand the layout of the editor, you can skip ahead to a timestamp or put on the screen right now where you can skip to, because when we start actually using Unity to make our scene. But if you haven't used Unity before, I do recommend just watching the next few minutes while I explain exactly what everything is and how the editor works. So let's get started. Before we begin, I'm using Unity version 2023, 0.1 0.5 and I have the default layout on. I recommend you change to the same layout as me, so you can follow along the way. You do that is you go right up to the top here you click Window, then you go down to Layouts and just choose the default one. It should reload your scene and make it look like this. I don't like this little AI navigation window. I'm just going to drag that down there and it's going to go away. And then we basically have the entire Unity editor at our disposal. I'm going to start over here at the top left, This is our scene. And you can see we start with a scene named Sample Scene. This is a default scene that Unity made for us. And if we click this little arrow, we can see all that's in the scene right now is a camera. Now this camera is basically what's going to be recording our game, and this is basically going to be the eyes of our player. This camera is actually what's called an object, I'll get into that later. But basically you can think of a scene as kind of like a level in a game and think of object as the things in the level. A player, a bullet, a coin. These are going to be objects and then a level would be a scene. Right now, we only have one level and our only object is the actual camera. But you'll see as we make our game and we develop further and further, we're going to populate our scene and add more and more things in basically this hierarchy window over here is where you're going to create objects or things in your game, you want to make a character. If you want to pretty much change anything about your scene, you're going to be doing it over here in terms of adding or removing objects. Then over here, this big window in the middle is actually where you're going to be editing the layout of your scene, or where things are, how big they are, all of those kind of things. That's where you're going to be doing it. Here, it's kind of like this is your palette and this is your canvas if you want to use an art analogy. But as we use the Unity editor more and more, this is just going to become second nature to you. How to use these two things, especially as well as the inspector, which I'll get to in a minute. Then before I move on to the inspector, the last thing I want to mention is this game window. And this is basically just a testing space. It's just blue right now because we don't have anything in our scene. But if I were to put something inside our scene over here, let's say I put a little block inside and I went to the game window, I'd be able to see it. And I'll show you that later when we start actually setting up our first level, or rather our scene. Moving on, we have the inspector window, and this is basically where you're going to view information about a specific object. So you can see if we don't have any object selected, it's blank because we don't have anything we're highlighting. But if we click on an object like our camera, we can see all of the information about our object. And I'll explain this as we add our things to our scene. But basically this transform component over here, every single object has, and it's basically how you orientate your object inside this scene. It's got a position, it's got a rotation, it's got a scale which is a size. And you can change all of these values. Obviously, we're going to be using two D games, so we don't really need the z axis for most of these things. But it does come in handy for rotation because z axis rotation is actually this way. You can see if we change it like that, we can actually rotate it. But regardless, this transform is where we edit the position and our rotation and the scale of our objects. Underneath this, we've got a camera. And you might be confused because you're like, okay, well this is a camera. What's this? This is actually a script that's made by Unity. To program all of this for us, what Unity effectively does is it simplifies the game development process by having a whole bunch of code pre written for us in the form of these things which are called components. So this might sound like a lot to take in, but trust me, it'll become second nature as you use it more and more. Basically, this main camera is an object which has a position and a rotation in the scale. And then they've added this pre written Unity script which is called Camera, as well as this audio listener script, which you don't need to worry about, but it's basically part of the camera. And these two scripts make this act how it does. And you can add other scripts which are called components. Or you can add your own scripts which are just called scripts. And basically this is going to be how you program your game in Unity. We'll make a player object. Then let's say we want to add a sprite which is like image or a photo, basically how we're going to represent our player. We're going to add a sprite renderer component and that's going to allow us to add some art to our game. We'll add a box collider component, which is basically how we're going to be adding physics in. Basically the whole of Unity works by making these objects and adding in either pre written scripts, which are components, or our own scripts. Right, right now we've got the camera, it comes pre loaded with two pre written scripts. But we can obviously add other scripts if we wanted. And when we make our own objects, I'll show you which scripts we're going to add. If this seems all confusing like a bit much right now, don't worry about it. It will become very, very simple as we use Unity more, but basically that is the gist of how the object inspector works. Moving down over here to the bottom, this is just the project window. It's basically just a representation of the folder where your program is stored or rather your game is stored. You can see I've got one folder here called Scenes, which is in my Assets folder. But I've got assets and packages, and these are actually stored on my computer. This is just Unity's way of showing you, instead of using File Explorer, it's in Unity itself. So it's the exact same thing. This is how we're going to import basically files into our games or make new files. It's all saved in here, and then that actually goes on your computer. This is kind of just showing you where it is. And then lastly, the very last thing that we have right here is a console window. Now, this is not amazingly important at the moment because we haven't started coding. But it is very useful because this is where we're going to be able to print out things. If you've coded before, you'll be familiar with Hello World as the first program you write in a new programming language. Which basically prints out to the screen Hello World. If you were to write this in Unity, you would have it printed out over here. This is where you'll get error messages, you'll get warnings about your game. You'll get messages if you want to log things. Like if you want to, for instance, create a game where you have players fighting each other and you don't want to program health yet. You just want to see if the code that says, okay, this player hit the other one actually works. You would maybe print it out to this console and you would say player was hit. And that's basically how you're going to use this. It's very good for debugging or for basically outputting evidence of your code working in your games. That's a pretty brief summary of how the Unity editor works. If this seemed a bit confusing, like I said, don't worry about it because you will pick this up as second nature as we use it more and more. But hopefully it gave you just a bit of a better idea of how everything works. Now the last thing we're going to do in this video, since we've basically just introduced the engine and talked about the course, is we're going to actually get started just making a very simple scene so that we can get started with our player next episode to make a scene. Let's go over here to our hierarchy right now. This little star over here, I think it's worth mentioning. This means that our scene is not saved. If I click control S, you can see it goes away. If you see that little star there, maybe just go ahead and save your program. Either control S or file save. Just so you make sure you don't lose any of your progress. Now we want to make a scene for our player to be able to live in when we make it. And we haven't made our play yet. So we need to make, first of all, like a mini map. First, I'm going to make an incredibly simple one. I'm going to right click over here because I want to make a new object. And I'm going to select two D object sprites and I'm going to choose a square. What that's actually going to make for me right now is just a little square. All a square is a Unity object. It's got a transform, so it's got a position and its rotation and its scale, just like we mentioned. And it's got a Sprite renderer, which basically allows it to have the square sprite that is showing on my screen. If I click it, I can actually move it around. This is what I'm going to use as a platform for my player to exist on. So I'm going to make a couple. I'm going to make one platform up here. I'm going to make one down there. And going to make one more up here. When I program my player, I can add in jumping and see that it all works. Now there's a couple of things we need to do to set up this map properly. First of all, we can't have a platform which is just a square, because that's pretty hard to bounce on. Let's start by clicking and dragging it to make it bigger. You can do this in this mode here. This is basically like your Tools menu. If you select different tools, they allow you to do different things with the objects. For instance, this one is moving it around. This one is rotating it. This one is obviously going to be scaling it up and down. This one over here is like a combination. It's like you'll see in image editing software, but you can also actually do all of that from this transform window over here. Which is what I'm going to do because it's a little more exact and I can basically control exactly how much I want this thing to rotate or scale. So I'm going to first set my z rotation to zero. This over here basically chooses whether we want our scale to be constrained for x and Y. So if I click it, then as I increase x and y and z, they all go up or down, basically scales in proportion. But I don't want that. I'm going to make sure it's got a line through it and then I'm going to scale y down. So it's not a super long platform. Super tall, sorry. I'm going to scale x a little bit there, I'd say that's a good platform and I'm just going to move it down to over there. Now, before I make the other platforms, I actually need to finish making this one first. Right now all this is is an object with a sprite. So it's not actually anything yet. It's just basically like a photograph. If I now want to add in a player, there's nothing that says when I land on this, I should stop moving or I should do anything at all. It's actually just like a photo. I'm going to add a new component which is a new script written by Unity. And I'm going to call it bid tut or rather I'm going to search, box Alida, Tout. That's what it's called. And when I click on that, you'll see it adds a new little script to my object. Now my square object over here has a sprite renderer and a box collider. And if you actually zoom in with the scroll, you can see a faint green outline outside this thing. If you select it, obviously you can't see it if you don't, but maybe you can see it a little better if I enable this motor here. I don't know if you can see it on my screen, but hopefully on yours you can see a faint green outline on the outside of your platform, and that is the box collider. What a box collider basically does is it tells Unity that this thing is an object in space. If I have something that's falling and it hits the box collider, Unity will say, okay, stop falling because this is an actual object, it's a thing, right? Unity is going to automatically, in my case, put my box collider perfectly around my platform. But if I wanted to change it, I could click this thing over here, which says Edit Collider. And then you can see I can now basically have control there. You can see the green box. I have control over how big I want my colliders pie. If I wanted it to be like that, then if a player was falling, it would stop over there rather than falling all the way down. I don't actually want that, so I'm just going to click control Z and I'm going to have it right back to where it was. But this is how you edit your box collider. Now before we continue, one other thing I should mention is that this and every single other kind of label that you see over here are sort of like attributes of the script. You can think of them like variables, but what they really are is attributes of the script which basically allow you to change how it works. This script is obviously a very general script, this one as well. You can't have a box glider that says, okay, make a box glider of this exact dimensions because we want to be able to customize it. Unity is actually built all of that in for us. Generally speaking, when we add these, I'm going to be telling you what to change. So don't go around filling with them because they do change it quite drastically. Unless obviously you know what you're doing or you want to make something slightly different than I'm making, then by all means. But right now for instance, our box glider has all the default settings are actually perfect for us. This one for example, this is trigger. If I were to select this, it means that this box glider will not actually influence physics. It's going to instead send a signal and say, okay, I was hit. We could use that for something like a bullet or like an enemy. Where we want maybe the player to be able to pass through them. But we do want to be able to know when we've hit them for this platform. However, we definitely don't want that because we want to be able to have the player stop when they land on it. Let's leave all of that for now. As well as the sprite render, these are all actually good as the default settings. And then what I'm going to do, because I don't feel like doing all of this again, is I'm just going to say control C and control V and I'm going to copy our square platform and move it down. I said I was going to have one up here and let me maybe make it slightly more short and then I'm going to do it one more time and I'm going to move it over here to maybe down a bit. I'm going to make this one shorter as well and move it over there there. We have now made three objects over here. We've called them square square one and square two, which aren't very good names. We'll rename them in a minute, but basically these are going to be the start of our game. These are the three objects we've made which we're going to add a player in next lesson. And we're going to be able to jump on these objects to show that our movement and everything works. But I'm getting ahead of myself. Basically, this is the start of our game. We have three platforms, and they all have box colliders to show that they are objects in space. Last, I'm going to do is I'm going to name them. I'll name this floor one. I'll name this one floor two. I'll name this one floor three. The very last thing I'm actually going to do is I'm going to organize our scene a little bit. First, I'm going to save because I can see that icons there. Then I'm going to say, okay, I don't actually want all of these to be on the same level as main camera. I want to make like a folder, you know how in Windows or in File Explorer or Mac, whatever, you'd store your files in folders. You wouldn't just have all your files out in the same place. The same thing here. I don't want these three objects to be on the same level as my cameras. I'm going to right click and I'm going to say create, empty, empty. Technically it's an empty object. It obviously has a transform because every object has to have a position. But you can use it like a folder, like it's basically just like an empty folder which you use to store other folders. That's how you can think of it. I'm going to name this one storage. I'm going to put my three floors inside storage by holding down shift and selecting them and then dragging them in. You can see now they are stored inside it. Now I have a slightly cleaner scene and it makes it look a little bit better. If I want to see where are my flaws, I just click this little arrow and I can see all three of them are there. Hopefully, that was a pretty good introduction to this course and how it's going to be structured. I hope that you were able to follow along and just make three level platforms. They don't have to be exactly the same, but obviously just have three platforms. And we're going to get started in the next video with adding in our player character. Thanks. 3. Lesson 2 - Creating our character: Hey there, and welcome to the second video of my course. Now in the last video, we introduced the Unity editor and basically explained what all of these different windows do. Once we've finished with that, we set up this basic scene for us to start building our game on. Now all we have right now in our scene is this main camera and the storage object which has our three pieces of flaw inside it. But this isn't much of a game right now, in fact, if which we didn't do last time. But I'm going to show you now, there's not a hell of a lot exciting that happens. We just have three objects which are actually just three sprites, so they're like three photos with colliders. So they are objects in space, but they're not much else. If we want to make a slightly more interesting game than this, which we do, we're going to have to add in another object and actually a whole bunch more objects. But the first other object we're going to add in is going to be our player. Because if you don't have a player, you don't really have a game. We're obviously going to want to add in our player. And then we can start adding in our other objects and our enemies, and everything else. That makes a game a game. But let's not get ahead of ourselves too much. Basically, what we need to do in this video is we're going to add in our player object. We're going to add our player object in the exact same way that we created these floor objects. We're going to right click over here. We're going to go create two, the object and we're actually going to create a square sprite. Now you can see over here, if I create my sprite, I have this white block which is our player. For now, this is obviously a placeholder because we're going to add in sprites and art to our game later. But for now it will have to do so. I'm going to go ahead and click on that twice and name it Player. He can also do that by clicking click Rename. Right now I have my player object, but there's nothing that actually differentiates him from these three objects. In fact, they're pretty much exactly the same. They're just squares that have been scaled differently. The first thing I'm going to do is I'm going to change the size of my player. I'm going to make it 0.65 instead of one, and that's going to make him a little bit smaller. You'll see later on when we add in sprites to our game, we'll actually be able to see exactly how big to make everything, because I'm going to be using pixel art. You don't have to use pixel art. But obviously if you want to make the exact same game that I am, you will obviously be using the same sprites. I'll obviously link them linked inside every single video where we do use them, so you can use the same ones that I am. But basically for now I'm getting ahead of myself. All we have is a square and so we can choose whatever size we want. Now below this, we actually have a sprite render component as well. And you can see just like these three floor objects do, that is the only thing that's added to this object. It's basically like an empty object with a sprite with something to show the object is there? The first thing I'm going to do is I'm going to change this color over here to yellow. Just so I can see that it's different from the rest of my scene. We can actually see that. We can now see our floor is white and our player is yellow. Just to give the player a little bit of differentiation, if I click play right now, not a hell of a lot is going to be different from when we played before. In fact, it's going to look pretty much the same. Nothing's going to move. And this player is not able to interact with the environment at all, which is one of the things we need for our game. So we're going to start by adding the exact same component we did to these to let it know that this is also an object in space and also needs to be collided with. Let's add another box collider two D. Like I said last time, you can pretty much leave all of these exactly how they are. Obviously, if you want to change it, you can. But I'm not going to be doing that. So I'm going to click Control Z and move it back to how it was right. Now we have a box collider. Now you might expect that if we click Play and we move our player down to where the other blocks are, I'm not going to be able to move past it, but this is not actually the case and it's for two main reasons. One of them, which is like the sub reason, is because Unity's physics engine isn't really built for detecting collisions, like detecting movement like this, because this is not something the player would ever be able to do. I'm actually editing my scene right now and I'm saying, okay, Unity editor now detect a collision. And even though Unity is actually detecting that collision, it can't really do anything about it. Because I haven't actually followed Unity's physics laws to put my thing there so it doesn't really know what to do. That's kind of the sub reason. But the main reason why unity isn't actually able to show that we are blocking this or show that that collision is happening is because we haven't added what is called a rigid body to this player. And a rigid body is basically like a built in physics component that kind of generalizes every single aspect of classical physics that you need for an object. So it makes it able to accelerate, makes it able to fall according to gravity, it makes it able to move. Right now, Unity doesn't really have any way of moving this object, even via code or whatever. You could do it maybe by moving the transform, But there's no reliable way for Unity to actually implement physics and motion and forces to this object. To add that, we need to just add one more component, which I mentioned is the rigid body two D. This is kind of like a general component, like I said, which basically adds physics to this object. That's quite a basic way of putting it, but it is what it does. I'm going to go ahead and actually change this angular drag to zero. And I'm going to click over here on constraints, and I'm going to freeze the rotation of Z. Now that might seem like I've done a lot of things and I've just introduced it, but I'm going to explain it more. And you'll become more familiar with these objects and exactly what they do, or rather these components, as we move on in the course. So don't worry too much about every single one of these little things, but basically what this object does is it adds physics. Now the way it works is not of massive importance, especially for this course, because it's built into Unity. This is basically a very complicated script that Unity has written for us. And these are all of the variables which we can change. So we can change the gravity scale, we can change the drag, I set that to zero just because it's not of an immense importance, but you don't have to change that to zero. You can kind of keep it, it's not really going to make a difference. And then the only other thing I changed was the rotation of the Z axis. And what that's going to do is if I hadn't changed that and I put my object over there, when I click the game, it's going to fall down. And then it's actually going to rotate this way, just like it would in real life. Which is not something I want for my game. And I really don't recommend you use it for platform of games because unless you're using squares, it doesn't look very good. I'm going to be using pixel art, so it's not going to look good at all. But once you've added this rigid body component and froze the rotation on the Z axis and set the angular drag to zero if you want to. That's pretty much all the set up we need to do. And now we're going to have a object in our game which can actually obey the laws of physics. If we click Play, we can see that our object will fall down and stop the minute we land on another collider, which is exactly what we want. And we can actually go back and move this back up. And we can see that it works exactly like we'd expect it to. Obviously, we're not going to be able to throw our object or anything like that. And that's kind of for the sub reason I mentioned earlier in that this isn't actually technically Unity's physics engine at player. This is me editing my game and then being like, okay, Unity Takeover. And so Unity doesn't have information how fast I flung it or whether I've done anything like that. I've just dropped my player down to the bottom of the map. So I'm just going to move him back up. Let's move him ten minute like that. Missed it again. See what's actually happening now is the player is moving so fast that it can no longer detect collisions. Which actually brings me to another important point. If you think you're going to be having a platform with incredibly fast collisions, you're going to want to change that to continuous. And I'll basically be able to illustrate what that does. Now if I do the exact same thing I did beforehand, and I have the player fall down and then pick up speed, obviously as it accelerates fast and fast towards the ground. I'm going to wait a while, I'm going to change this to five. No, to set that to zero. You can see I was actually able to stop at this time. So that was not entirely intentional. But that's actually a good teaching moment for how unity's rigid body works. So it's really up to you whether you want to have this setting on. It is slightly more intensive to have continuous checking on, I do believe. But it is actually generally something I do like to add to my games. So in summary, we've basically just added in our Player object, we've got a sprite render right here. We've added a collider to tell Unity it's an object in space. We've got our rigid body over here as well, which we've changed the angular drag on. We've set the collision detection to continuous because of that thing that we accidentally discovered and we froze the Z rotation. And these are actually all the set up things that we're going to need to do to start making our player. Right now we've basically got a platform, a game, but you can't actually play it, you can just fall. So what we're going to get started on in the next episode is basically adding in our movement script to make our player able to jump and fall and move left and right and everything else that we'll need. So we're going to get started with coding in the next episode, but right now, you should have your scene set up pretty much exactly like mine is. 4. Lesson 3 - Adding player movement: Hey there, and welcome back to Unity. Now this is the third lesson of our course. So far, what we've added is a player object which can fall and collide with three floor objects we created before that. But we don't really have a game yet. What we actually have is an incredibly simple physics demonstration. Falls and stops there. But this is not the most interesting thing. And to make it more interesting, what we're going to add is a script which is basically going to allow the player to move and basically play our game. Because without a script we don't really have a game because we don't really have any way of influencing the outcome, which is the whole point. So to get started, we're first going to go onto this Assets folder over here. And depending on whether you've been ported files already, if you've been following along, you'll should look pretty much exactly like mine with just one scenes folder. And inside the scene we have our scene over here which is called Sample Scene. Now I'm going to go back to the Assets folder and I'm actually going to write click and go Create new folder and call it scripts. And this is where I'm going to put every single piece of code I write for this project. You don't have to follow it exactly like me. This is just how I like to order my scripts and my folder for my game, so I'm going to go double click on that. And now I'm going to get started with making my very first C Sharp script. Now if you've never coded in C Sharp before, then obviously you're going to want to watch this entire video. If you've coded C sharp and you don't need as much help, then you can go ahead and write your own movement script. But I'm going to be writing a rather simple one just to introduce the idea. And then we might change it as we go along. I'm going to write Click and I'm going to go Create C sharp script and I'm going to call it player movement. The minute I've done that, we can actually click on the script and view it in a preview mode. Over here we can see right now we've got a class which was made for us and we've got two voids which are like methods. I'll explain all of this. You don't really need to worry too much about the coding terminology, but basically just follow along. And you should become a lot more familiar with C sharp as we code more and more. But I will be explaining everything, so don't worry. Let's go ahead and double click that to open it up. I'm going to be using Visual Studio as my IDE. What an IDE is, is you can think of it like a code editor, like you'd use Word or Google Docs to edit essays. This is what you used to edit code. You can use whatever one you want, but I do recommend Visual Studio. I'm using quite an old version, but pretty much any of them are really good, especially for Unity. Immediately, open it up, it might seem a little confusing, like what are all these words and what are the different colors mean? Like I said, don't worry too much about everything so far. I'm going to explain all the important things at the top we've got. Using. Without going too much into the terminology of actually what this means, think of it like we're telling unity which parts of unity we want to use. So if we wanted to use something which was based in UI, we'd have to add a new line over here that says using Unity Engine. Basically, this is telling us, okay, this is the parts of Unity that I need. These default ones are actually going to be pretty much fine for most of our scripts we're going to write. And if we need to add a different one, I will obviously tell you as I write the script because you'll be writing along with me, so don't worry about that too much. Underneath here is our public class. Again, don't worry too much about what a class exactly is. But you can kind of think about this like a container for all of our code. All of this is coding terminology, which if you really want to, you can go and research on the Internet and kind of understand exactly what the definitions for all of it are. But I'm not going to be saying too much time on that in this course because it's really not that important to Unity development. What we're actually going to be focused on is more how to develop games. And you don't really need to be able to define these different concepts, You not just need to know how to be able to code. Obviously, the more you code, the more you will discover and the more you'll learn about them. But for now, don't worry too much about them because it can be quite intimidating to have to learn all of that kind of thing off by heart right now. And it's really not that important for us. That being said, there are a few things that need to go over. First of all, this is a comment. And a comment is basically like piece of code that isn't actually code at all. It's like a line to tell somebody who's reading the code, what is what they're denoted by these two forward slashes before, if you put it like that, you can write whatever you want and the IDE or the editor will know that. This is not code that needs to be run. It doesn't actually have to decipher. What does this statement mean? It's just a comment. This is comments that are written by Unity. For us to explain what these two different voids are, it says that start is called before the first frame, update and update is called once per frame. Now these two voids, the last thing I want to mention are like methods. You can think about methods like sections of our code that we can call at certain times. Right now we've loaded in our code. This is our massive program. This is a section of our code which we're going to call before the first frame update. This is a section of our code which we're going to call every single frame. And this is obviously all done by Unity for us when we create our own methods. Later on we're going to have to choose when to call them. But these are the two methods which we're going to basically build our entire code from. Obviously, the start method is going to run the minute this code is executed by Unity, before the first frame plays, we can write some stuff in here and say, okay, this, do this, do this, and Unity will do it. And this code over here is going to be run every single frame, every single frame. This is going to be called. If I say print a number, every single frame, it's going to print that number. And if I say print a number here, it's going to print it once before the game starts, and then it's not going to do anymore. That should be a pretty quick and maybe a little bit confusing over you, but hopefully the basic concepts do make sense. And like I said, don't worry too much about the specifics as you follow along, you will understand it more and more. And if it seems a little intimidating at first, don't worry, it'll get easier later on. But in terms of getting started with actual coding, let's first start by going over here to the top and creating what is called a variable. Now a variable is like a storage space in code, so we're going to create a variable, let's call it movement speed. And then that is a storage space where every time I want to access how fast the player must move, I'm going to look in that variable and see, okay, what is stored here. You have different types of variables. I'm just going to cover a few ones briefly and now we'll get started into actual coding. But basically there are integers which are numbers. There are strings which are like words or text. There are also characters which are single letters. And then you have booleans which are true or false. Lastly, you have floats which are basically like decimals, so don't worry about too much those either. At the moment, like I said, all of this is going to come more naturally. But I just wanted to give you kind of a basic overview of all of the basics of coding you're going to need for this lesson. To get started, we're going to create our first variable, and we're going to call it a public, which basically means that it can be accessed by anything in this entire script float. And we're going to call it player speed. Then we're going to add a semicolon at the end. This public player speed we're going to use to determine how fast our player must go. We're going to create a new one. Public float, another public float, we're going to call it jump height. Now basically what we've told the IDE or told Unity rather, is we want a public so it can be accessed by anything in the script. Don't worry about these too much either at the moment, but just copy along as I do it float, which means it's a decimal number and this is what it's called. The reason we're actually using public is so that we can access it in the Unity editors. If I go ahead and drag this script onto an object, I'll be able to see this in the Unity editor, which is why I'm using public. But just follow along for now and do exactly as I'm doing. And it should all make sense because like I said, even if it seems a little intimidating at first, it'll get a lot easier. Now, before I move on, there's a few more things I need to add at the top here. First four is going to be a reference to the components which we've added to our object. We added a rigid body which basically says, okay, obey the laws of physics, but we need to basically be able to access that rigid body in our codes. I'm going to create public rigid body two D and call it RB. This is basically going to say, okay, now I have a reference to that rigid body so I can effect it. The way we're going to create movement is we're going to be changing the velocity of my body. So I'm going to say when I click this key down, make it move this fast in this direction. To do that we obviously need a reference to the physics component of my object, which is this rigid body. Once I've done that, I've pretty much got everything that I need to start coding my very basic movement script. I'm going to add one more thing underneath it, a public bullion, which means a true or false. It's called a bull in C sharp, and we're going to call it is grounded. This is basically going to tell us are we on the ground or not? Now, the minute you've made these four variables and this reference to this component over here, we've got everything we need to start coding our game. The first thing I'm going to do is I'm going to create a new void. And this void is going to be called fixed update. Now this is actually another void that's created automatically for us by Unity. It's just like update, it's just fixed. Update isn't based on the speed of your computer. Update is called every single frame, right? Obviously, if you have a fast computer, that's going to be called a lot faster. If you have a slow computer fixed update is instead called at a very, very short interval. So, pretty much as much as update is on most computers, obviously, you have a super fast computer, might be a little slower. If you have a super slow computer, it might be a little faster. But it is a good method to put physics, logic and other things like that in your game. Because you don't want someone who has a faster computer to be able to do more in your game than someone who has a slow computer. For instance, you wouldn't want them to fall faster. We're going to be using a general form of update. It's still pretty much called every frame, you can think of it like the same thing, but it's just good convention to do that. Now we're going to start coding the actual movement for our game inside this fixed update, follow along as I do. The first thing I'm going to do is I'm going to create a new variable and I'm going to call it x. And I can actually just do that by typing float x. The difference between the variable up here in the variable up here is this variable is accessed by everything in the script. All of these places where we call code can talk about these variables. But inside one of these, if I create a variable that can only be accessed inside this. If I go into update and I try to talk about x, it's not going to know what I'm talking about, but inside fixed update it will. And that's fine for our purposes because we actually only need this float x to be inside fixed update going to go equals input, get axis raw, open parentheses, double quote, and then type the word horizontal. What this is basically going to do is it's another feature of Unity. It's basically going to allow us to simplify our movement by quite a bit because instead of saying, okay, if the player is holding this key, do this. If they're holding this key, do this. What we're saying here is creative variable called x. It's type float. And what this variable is going to be used for is storing whether the player is holding down certain keys. What this line over here, input get axis horizontal does, is it says to unity. If the minute run this code, the player is holding down either the right arrow key or the D key for SD, then put a value of one in x. If they're holding down the A key or the left arrow, put a value of negative one in. And if they're not holding down any of those keys, then put in a value of zero. So you can see basically what this is going to do is every single frame it's going to say, okay, are they holding down forward? If so, make this one. Are they holding down back? If so, make this minus one. Are they not touching anything? Okay? Make this zero. And you can imagine how this is going to be useful for our game, because this is basically going to allow us every single frame check whether the player wants us to move or whether we should keep moving or whether we should move backwards, et cetera, et cetera, et cetera. This is the first line of code for our script. And underneath this we're going to write another line of code which is going to say R B reference to our ridge body velocity. So we're going to edit basically how fast we're moving equals vector two. Now this is not massively important, it's basically a vector, two is a vector of two components. I'm saying, okay, I want my velocity, obviously velocity, I'm going to have an x velocity and y velocity. And I want this to be, I'm going to assign things to this using vector. If I assigned 1.1 it says, okay, make the x one and make the y one. If I set it 2.1 it says make the x two and the y one. This is basically, like I said, it's not super important. Think of it like a storage space. If you know what a vector is, then I'm sure it makes a lot of sense. But if you haven't encountered a vector or you haven't done a lot of physics, then just think of it like a storage space for two numbers or two values rather. Right now I'm saying, okay, I want my RB velocity is this new vector two, And I'm going to have to put in an x and a y because I obviously have x velocity horizontal and a y velocity vertical. I'm going to make my x velocity equal to x and I'm going to separate them by a comma and I'm going to make my y velocity RB velocity Y. That's basically like saying, okay, take the velocity of my rigid body and make the x velocity x and make the y velocity the y velocity, the y velocity isn't changed. If I made this RB do velocity dot x, this line would do absolutely nothing. Because it's basic saying, okay, take the velocity of the rigid body and make it what the velocity of the rigid body is, which obviously doesn't have any effect. And that's what I want for the y axis, because I don't want the player to be mid air falling. And then I click the right arrow and I just suddenly start moving in a straight line. And that's what would happen if I set this to zero, for instance, or some other number. I don't want this to change, but I do want this to change because I want to be able to influence where the player is moving left and right. This is actually pretty much the two lines of code we need to build the most rudimentary movement possible. If I go back into Unity and I go to my play object over here. Once it's finished reloading my script, I go over here to my play object and I drag this in here. Let's move it down to the bottom. And let's drag it over there. We can see I have my incredibly simple script and I'm going to drag this rigid body over here so my script knows where the rigid body is. Then I'm talking about, because I'm talking about it, but I haven't actually linked it. This is how we're going to link it in Unity. It's one of the easiest ways, and I don't actually have to change these variables because I haven't used them in my script at all. But you'll see if I go ahead and click play. Right now I fall like normal. But if I click the, all the keys, all the arrow keys as well, I can move along just like I would be able to in any other platform. Again, obviously this is not a very good movement script because I can't jump, I can't do anything. In fact, I can't even make it across this thing without falling into the abyss. If I try, I'm just going to fall. So it's not a very good movement script because I'm not moving fast enough, I can't jump. But this is the basis for my movement script. I've said, okay, depending on whether I'm holding certain keys, set this value and then assign that value to the velocity of my rigid body. So make sure I'm moving in the direction that that value should make me move. But obviously we want to make it a little more interesting. So let's start by multiplying this by player speed. And this where we're going to start using our variables. Now this is going to allow us to determine how fast the player moves based on this players speed variable. And I'm actually going to delete this start board because I'm not actually going to need it right now. I might add it in later depending on how I edit the script. But for now, it's actually all fine to have it like it is now. Now actually there's a few changes I want to make. This is kind of just to illustrate how we're going to be building our moved script. I was trying to explain how different variables work and how it works, but we want to make this slightly better. So the first thing we're going to do is going to go to the top, and we're going to create a new public float. Call it x, so we're actually going to be not referring to a variable just inside this method. We want it to be a variable that can be accessed anywhere inside the script. And then we're going to go ahead and actually move this fixed update code to the update block. And what that's going to do is basically, instead of basing this value on a certain interval, we're going to want to update this every single frame. Which is a much better way to code. You can kind of think as a general rule, you have to follow any code that is based on input or what the players doing should go under update. Any code that's based on physics or moving things based on that should go in fixed update. Because this is basically going to allow us to say, okay, if you have a faster computer, sure, you should be able to react faster. But then you're going to be able to move the same speed as someone with a slower computer because that's fair, greatly over exaggerating how much this has an effect. Because I promise you could code your entire thing and update a fixed update. You probably wouldn't be able to tell a massive difference, but it's just really good coding convention to do what I'm doing over here. That being said, we've got a few more things to add to our script just to make it a slightly better movement script. We've already multiplied by player speed, obviously. But the last thing we're going to add is a jump, so we can actually start moving. And I'm going to create a new public void, which is like I want a new block of code that I can call. At a certain time, I'm going to call it jump inside this public void. I'm going to copy this code over here. Copy it, and put it back there. And I'm going to say now when I jump, I want my RV velocity, so the velocity of my player to be another new vector two. Rb velocity x. This time we're not changing the x velocity at all. We want the x velocity to stay the same when we jump. Because obviously we don't want to jump forward or jump backward, we just want to jump up whatever the x velocity is, set it to what it was. And we also obviously don't want it to be that it has to be zero. Because then if you're moving along, you try jump, you're just going to jump in place, stay whatever speed you are moving. But we want to jump up, so we're going to set the y velocity to this value. Jump height, which we can obviously change as well. Now what this is going to do is every time we call this void, we're going to change our velocity and we're going to say, okay, move along as you were with x, but jump up as far as this value allows you to. With the y velocity, what we're actually saying is change your velocity to some value. And so that's going to cause you to shoot up, and then obviously as gravity comes, you're going to fall back to the ground. But that's what the script does. Now this actually brings us almost to the end of our script. It's incredibly simple. There's three lines of code so far, and we've actually got everything we need to be able to move and jump in Unity. If I go back here, I'm going to actually change these values right now. Let's make jump height something like ten. Let's make play a speed of five. You can see actually, if I move along and I go like this, I should be able to move and jump. But there's one thing missing. We're never actually calling this block of code. So there's no way of me telling myself, okay, I want to call this code for that, we're going to need to use another input command. Let's go down here. Let's say if which, saying as long as this condition is true, do the code below it, input dot get key down, open parentheses, keycode space or whatever you want it to be. I'm actually going to use keycode because I prefer to have jumping SD rather than space, but you can use whatever you want. Feel game. Then we're going to put a curly bracket here and visual Studio or whatever you're going to use is going to automatically fill that in. You basically want one C bracket there and one co bracket there. And this is going to tell us what code is inside this if statement, as long as this is true, as long as you're pressing the key, or as long as you just press the WK. Then run this code. And all I'm going to want to do is I'm going to call that jump void. So hopefully this all makes quite a lot of sense. I'm moving quite quickly and there are a lot of concepts here, especially if you've never coded before, which might seem a little intimidating. But basically all we've got right now is we've got this storage space, we've got our variables which are storing things like settings. Then we're setting this value based on what the player is moving. And we're saying if they're pressing the Wkey, then call this code over here. And this code is saying, okay, move in this direction. And this code over here, every single frame is saying move in this direction according to what the player is currently doing with their keyboard. So like I said, it might not seem super intuitive at the moment, but hopefully it does make a little bit of sense what we're trying to do. And if I go back into my game, I will be able to jump if RestWK But there's one more change I want to make. And I only want to be able to jump as long as I'm grounded. So let's go ahead back here and we're going to add a double ampersand and say is grounded. And that's going to say only as long as we're grounded can we actually run this code. Because I don't want to be able to jump in the middle of there. I only want to be able to jump from the ground. And we're going to add in one more condition which is going to allow us to determine whether we're grounded here. We're going to say void on collision enter two D, if collision, this is basically saying, once we collide those colliders that we added earlier in the box, colliders are going to call this void over here. As long as you collide, they're okay. We've collided call this void. This collision is storing what we collided into. We're going to say if collision do game object dot compare tag going to open princes and we're going to type ground. Then we're going to say is grounded equals true. We're going to do a very similar piece of code for exiting a collision. Copy this code exactly except set grounded to force. Now this might seem like a lot, it might seem a little confusing especially compared to the rest of the script, but it's actually very easy. This void over here, just like update and start are called by Unity, is called by Unity. Every time we collide with something, the physics engine takes care of that, then we're colliding with this thing and we're storing it in this variable collision. And underneath that what we're saying is, okay, if collision the thing we collided with or rather the collider we collided with. If the object that that's attached to has a tag ground, then I want to make sure that I've set this variable over here is grounded to true, and that's going to allow me to jump. Otherwise, if we exit a collision, if we exit from a collider, if the collider we exited from is called ground, I want to do the same thing except set it to force. The last thing we need to do before we actually go test this is go back into our game, go into our storage, select our three floor things, and we want to add in this grounded tag. Click add tag, over here, click the plus and type in ground. No, I'm going to go back to my floors and I'm going to make sure they're all set to the ground tag. These tags are basically a way if you've been able to identify certain objects or groups of objects. All of these objects are part of the floor and I want them all to be ground tag. And this allows me to write this code over here that tells me when I've hit the floor or not. That's actually everything we're going to need to make our games movement. If we go back to player, we see over here we obviously edited these last time in play mode. So let's change these in normal mode, it saves, I got to make this six, I'll make the jump height five. I'm obviously not going to want to change either of those because those are taken care of in my code. We click on Player and click, let's watch what happens. First things first, we fall down, just like we have, and we land on the ground. If I scroll down, I can see my is grounded, is true, which is exactly what I want. And if I click the WK, it goes from false to true. And I can jump. If I click the WK mid air, it doesn't work. So my jumping is actually working great. And if I move left and right, we can see it's a little fast. I want to make this movement four, go back in my game. And this should actually be everything we need for a basic movement, scripting fall. And I jump and I can obviously move around just like I need to. Now, this might look a little goofy, and obviously we're going to tweak it as we go along. But this is kind of the basic for our game. What I'm actually going to want, based on the platform I want, I want to make it a slightly faster speed, a slightly higher jump. And I'm actually going to want to change this gravity scale to two. And I might need to change these a little higher. I might need to make this eight over here. We can see what that looks like. Looks a little bit better. I know it looks a little jerky with this movement, but it's quite a retro kind of style and easy to move, but in case you actually don't want this, and I'm actually not sure I'm going to keep this in. I just added it originally because it was quite simple. There's actually a very simple fix to make this different right now. You can see it's quite a jerky thing. If you don't want that, then you're going to go ahead into our code and we're just going to remove this word raw. That's basically going to tell Unity, Okay, don't round it up to 10. Make it a more gradual thing depending on how long they've been holding the key. If we move that, we can see that in action over here a little more smooth based on how you want to move. I actually forgot to change these back, so let's go ahead and make this a 6.8 and change glarity scale two. If we can play again, we can see that we've now got slightly smoother movement and it makes it look a lot better. Now the reason I did it rule first was because I thought it was an easier way to illustrate the concept. But it is generally better to use this axis which softens the thing because it looks just a little more natural. I might change this back. We can tweak it, obviously, as we go throughout a game. Hopefully you've been following along and you've been able to create this very simple movement script and we can jump along. Now that is the end of the video. But there is one last thing I want to add, just while we've added movement, and it's an incredibly simple change, all we want to do is we're going to go out here and we want to create a new physics material. We're going to find out here two physics material, two D, we're going to call it player. And we're going to set the friction to zero. This is basically going to allow us to not get stuck to the walls. I don't know if you saw the last time, we're going to add it to our box collider. Now if we jump ahead against the wall, we're not going to stick to it. Because what happened before was if we land against the wall and we stick to it, we actually stuck there, but now we roll right back through. That is actually the end. I know this is quite a long video and there was quite a lot that was going on, but it was the very first script. So obviously it's quite a lot of new concepts at once. So hopefully you've followed along and hopefully you've been able to create this movement script just like I have. It's incredibly simple, like I said. And I'm changed the access to this now, but I might tweak it as I go along my game because I'm not sure how much I like it, but I'll see basically that is the game for now and that is everything that we need to have. So if you've been following along, you've got your movement just like it is mine. Great. And I'll see in the next video where we're going to start adding more and more concepts to make our game a more impressive platform. But if you've got just where I have for now, that's great. 5. Lesson 4 - Introducing prefabs: Hey there, and welcome back to Unity. Now in the last episode, we did quite a few things. We added our player, we added our movement script. Well, we made our player so we can actually jump around and added our first line of code, all our entire script. And then we also actually made this player material right at the end. I hope that you were able to follow it all and get to the stage that I am in my game. Now if not, and yours is looking a little different, I just recommend maybe going back and rewatching it maybe once or twice, just so you can follow along and make sure that you've got everything as I do right now. Obviously, like I said, my script is going to be attached to every single video. And pretty much every single file that I make alongside this course is going to be attached in the respective videos. So you can go ahead and download it. If yours isn't working, maybe see where your code is different than mine or what you're doing differently. And obviously using my files should make it work completely fine. So just go ahead and don't get too intimidated by the pace of things. And you could rewatch things and use the files and should be able to follow along and have everything working in no time. So don't get discouraged. Game development is hard, but if you've got everything to the point that I do now, great job. Because we've actually done quite a long, the last episode. If you write caught up to where I am, then that's great. Now, before we get started with this episode, which is going to be all about prefabs, we're first going to start by just reordering this assets folder a little bit. So let's go ahead and right click. Let's create a new folder. And I'm going to call this miscellaneous because there's always like random files in the project that you don't really need to have their own dedicated folder for, like this physics material. We're not going to be making a hell of a lot of these. I'm just going to put that in my Misk folder. And anything else that I come along in my game, I'm going to put in that Misk folder if it doesn't fit in any of the other folders. Now that being said, we are going to need to create a new folder down here as well, and we're going to call it prefabs. We're going to get into exactly what a prefab is and how we get to make them in a minute. But for now, just make the folder because you're going to want to have a storage space for your prefabs. Now, what exactly is a prefab? We've mentioned that these things we have up here are objects. Now, they're the building blocks of our game that we're going to assign logic to in the form of components. And that's going to allow us to build our game up from scratch. But we can only create these objects while we're developing in Unity at the moment. Like if I wanted to create a new enemy, I'd have to go over here and create a new object like this to the object sprite, maybe get a triangle, change the color, add logic from there. But in game development, generally, you want to be able to create objects at run time. Which means while the game is running, while the player is actually playing, you want to be able to create and destroy objects. And to do that, we're going to use prefabs. Now, if this is a little confusing at first why we need to do this, let me give you an example. Say we've got a player and he needs to be able to shoot things. When you shoot something, you actually want to create a bullet object. You want to create a new object that shoots from your gun and travels across the screen and does certain things when it hits an enemy. Now the only way, or the easiest way rather to do this is actually using prefabs. Because basically it's going to allow you to create an object at run time, your bullet, have it exist for its duration, and then destroy it. When you don't need it anymore, say when it hits an enemy or a wall, you can destroy that object. So it only exists for a limited amount of the playtime. And I'm going to explain exactly how they work, how you can create these prefabs, and how they can be used to bring objects into your games in a minute. But right now, all you kind of need to know is that prefabs are used to make objects. So how exactly do we use prefabs to make objects? Well, we start it just like we would anything else. We go over here to the hierarchy and we right click Create to the object. And I'm going to make, the first prefab I'm going to make is a spike. So the enemy has something they can fall into and die to the object sprite triangle. Just to make the game's first kind of enemy, I'm going to call this spike. Go ahead and size it down just a little bit. Let's say 0.8 on the x and y, and I'm going to change its color to red so we know it's an enemy. So now we have our first enemy. Obviously, this is nowhere near done. There's a few other things we have to add. First, the first thing I'm going to do is I'm going to change this tag, just like I did with the ground. I'm going to click Add Tag. And I'm going to make it an enemy tag. And we're not going to use this right away, but this is going to come in handy later. So make sure that you don't leave up this step for now. The next thing I'm going to do is I'm going to add a type of alida. If I search Alida, you can see I've got a whole bunch of Kaliders. But the one that fits this one best is a polygon Alider, which is obviously like four a triangle. You can see if you scroll down, there's pretty much colliders for every kind of object you could possibly have. Obviously avoid the ones which aren't two D, like a sphere collider or a box collider, or a capsule collider, because the two D ones are what we're going to be using. But this polygon collider only has a two D version, so don't worry, there's no three D triangle or pyramid collider, so you can't really go wrong. But what we've done now is we've added our polygon collider. And actually before I forget, I also want to make this a trigger now. This is not incredibly important at the moment because we're actually only going to add our enemy logic and the fact that you can die when you hit these later on. But these are just kind of steps you want to do now so that you can set up your enemy correctly. So we want to name it, we're naming. It's not that important, but it's just useful. We want to make sure we've set the tag. We want to add a collider, and we want to make it a trigger collider. So you can see now if we click play, obviously nothing is going to happen when we walk into that. But you should be able to see we are actually able to pass through, which is kind of what we want because we don't want this object to be something that can exist in space, more to be kind of like a signal that when I hit it I can take damage or something. You obviously don't want to actually not be able to move past it. Because if you're running along and you hit an object, you want to be able to pass through it and take damage, but not stop and kind of not be able to pass through. So that is all the set up we need to do for our object at the moment. But make sure that you've kind of followed along and you've added the polygon collider and changed it to the enemy tag. Now this is actually what we're going to be using to make our first prefab. So let's double click this. I'm going to take it over here. Click on the object. I'm going to drag it down into my Assets folder. And what that's going to do is it's going to create this new file and it's going to be called spike prefab acid. And you can see over here, it actually changes to blue. Now what this prefab is, you can kind of think of it like an object template. So what I'm basically doing here is I'm saying, okay, I've got this object I want to make like a template or kind of like a stamp. And so I can make copies of that object and bring them into my game. This is kind of the template for the object I'm creating. So I can then go in some code and I can say, okay, spawn in a spike. And it knows to spawn in this specific object with this specific sprite and this specific polygon and pretty much all the other qualities that I've just added right now, it knows that that is what I'm referring to when I want to spawn in a spike. So I'm going to go ahead and delete that extra one for now. And I'm actually also going to go ahead and delete this from my scene now. Don't worry, because this doesn't actually get rid of the spike. We can see it's still down here in prefabs, and if I double click it, I can edit the actual prefab. So here I'm editing the actual template for the prefab. If I drag a prefab in, it's instantiating that object or creating that object. Creating an instance of that prefab is what it's called. If I change things on this prefab here in the game, make sure to note that it doesn't actually override the prefab. It's changing this specific instance of a prefab. So I've kind of like spawned it in already. I can do whatever I want to this one. But it's not going to change the fact that when I spawn another one, it'll be exactly the same. If I want to change the actual stamp or the actual template, I have to do that in here. Because if I make this, for instance, orange, you can see now every single time I spawn in these prefabs, they are orange. Also note that this prefab, which we didn't change, is linked to the original file. The minute we make a change to it, the link changes because I've changed this color. If I go ahead and change this back to red, we can see that the green and the yellow one are going to stay green and yellow. But the ones I haven't changed are red. But other quantities of it which I haven't changed will be effective. For instance, if I make the scale 0.85 that's not 85, make it slightly bigger. We can see all of these prefabs did actually get quite bigger, but this one did not, because this one we'd already changed. It was 214-41-2616 And if I go back here and I change this back to eight, we can see it remains at 214-41-2616 Because we have basically, the minute you change a certain quality on this prefab, it's its own prefab. And so you won't get overridden by this original prefab that's denoted by this little blue line here. These are the things that I've changed in the prefab. That's just something you need to note, it's not super important. But just note if you want to change your actual prefab, you've got to do it over here. So I'm going to go ahead and actually delete all of those spikes for now. And I'm going to get started before I start making some more prefabs. Let me make one more simple one, create two the object and I'm going to make a circle. And this is going to be another enemy later on, it's going to be a spike ball. You'll see when we add in spikes and sprites and everything, but let's change this to red as well. Let's add a circle collider. And let's make sure it's got the tag enemy. Make sure that's a trigger, that is everything we need. We can also make this maybe a slight bit smaller. This is actually everything that we need to make our new prefabs. So let's drag it down again. We can see now we've got our two prefabs. I'm going to delete this. I'm actually going to rename this to spike ball. Now if we double click, we can see we've got our spike and our spike ball, they're both enemies and they're both red. And they both have colliders attached, which are triggers. So they won't be affected by space as much, But they will let the game engine know, okay, I've hit something. It's important to note that other colliders do also do that as well. It's just they also have the added functionality of also existing as object in space time which can influence physics. Let's go back to these prefabs and let's make sure that they're all pretty much set up exactly how we want them to be. Because now what we're going to do is we're going to create a new prefab, and that's going to be our map tile. The reason why we're creating these prefabs is because we're going to actually get started creating our map generation script. Right now we've got a player and we've got three blocks that he can jump from. But that's kind of it. We don't have an infinite game. We don't have anything we can move to. We just have three things, and that's kind of the entire game. So even though I have filled these with all sorts of interesting obstacles, there's only three of them. And we obviously want the game to kind of be continue on and have as many as possible. So to do that we're going to have to create a pre fab with this floor object and put whatever we want on it. And then we're going to want to write code that's going to spawn that in. Now, I'm going to get started doing just that, but before I do, let me just say a disclaimer quickly. The way we're going to do this is we're going to create a whole bunch of different floor tiles. Kind of think of them like platforms in the game, and you can make kind of as many as you want. We'll get to that when we code it later on. But basically these are going to be the full list of possible tiles the game can spawn in. If you only make one with a single spike, your game is just going to be a whole bunch of things with a whole bunch of spikes. That's it. But if we make one with a spike, one with two spikes, maybe one with three spikes, one with a spike and a spike ball, one with two spike balls. The more you add in, the more varied your game is going to get. And you'll see as we add in more enemies and more exciting things, we can make more varied platforms and make a more interesting game. But I'm getting ahead of myself. I'm just going to get started by making a basic one and showing you how I can spawn it in to make a pre fab floor. I'm going to do the exact same thing I did before. I'm going to make this slightly bigger, just I think that's about a good size for a platform. I'm going to drag it down and now we can see I've got a new prefab called floor two. I'm going to name this to floor tile one. And this is going to be my basic floor tile. If I double click on this now you can see that I can access it inside my prefab editor and I can actually customize this exactly high want. Now like I said, what this is is it's going to be the tiles which we're going to be spawning in our game right now. It's just a basic tile, there's no enemies, there's no obstacles, it's just a tile. So we're going to make it a little more interesting. I'm going to start by adding in a spike. Let me drag from my prefix up to this prefabittor. We can see now we've added in, this is what's called a child object. It's linked to the original object and if I move the original object, it moves with it. We saw that earlier when we stored all of our flaws inside the storage parent object. You can think of it like the greater object or like the folder object over here. It's called the parent object. And we're adding in a spike inside our parent object. I'm going to put one spike down there. It's pretty well centered. It doesn't matter too much about making this look too nice, because we're obviously going to add sprites and everything else later on. But this is placeholder, but I'm going to copy this, and I'm going to put another one over there. Move it down slightly. That is pretty much our first object finished and created. Obviously, we haven't created any death effect or any health system. It's not going to do much now. But if we go back to our game and we see our floor tile, we can see that it actually is linked to our object and has created exactly what we wanted when we're playing the game. We're going to write a script that's going to say, okay, put one there, and put one there, and put one there. We can see we've got a platform, a game that's starting to form. If we kick, we can move around and we can pretend like we're playing the game. We can jump over that platform and jump over this one. Obviously, we would have died there. But you get the gist. Our game will not be this hard, don't worry. But that is going to be how we're going to be using these objects to play our game and make our interesting map. So what I'm going to do with the rest of this video is just make a couple more prefabs. You don't have to follow exactly what I'm doing, you can make them pretty much how you want. I would recommend following my spike and spike ball as our enemies because we're going to add in some sprites later on. And if you want to use my sprites, I've already got those sprites created. So if you make up some other enemy, then you're going to either have to make your own sprite or have to come up with an alternative plan. But if you want to make the game exactly like I'm making it, maybe stick with these two just for now. Obviously, once you've gone further in the course, you can maybe start adding your own enemies and making your own tiles. But especially if it's your first time using Unity, follow along with these two objects as much as possible. But that being said, you can make whatever tiles you want, so you don't have to make two, you can make three. Obviously, make them all possible, because you want something in your game to be impossible. But you can get creative and make different tiles as much as you want. You can make as many tiles as you want as well. The more actually, like I said, you have the better. Because it means the game is going to be more varied. Obviously, you want to have more tiles, which you can possibly have to get started by copying this, pasting it down. And I'm going to call this floor tile two. I'm actually going to do that a whole bunch of times because I'm going to start off by making eight tiles over here. I've got eight actually make ten right now. They've got weird names and they're obviously all the same. But I'm going to edit them now. So I've got floor tile one, floor tile two. I'll make this floor tile three. This of course, floor tile four. And so on and so forth, all the way up to floor tile ten. See, now I have my ten floor tiles. Now while I'm doing this, I'm actually going to make my game even more ordered. I'm going to right click and I'm going to make a new folder. I'm going to call this one floor tiles. I'm actually going to put all of these in here, drag them in, and I'm going to double click on each one. And then when I want to edit them, obviously if I want to add enemies, have to go right out, back up to prefabs and add them in like so. But it means that all of my floor tiles are stored in here so I can keep track of them and know where they all are. So I'm going to keep my floor tile one as I had it. I think that's pretty good. My floor tile two, I'm going to make a rather simple one, it's just going to have a single spike in the middle. And then floor tile three, I'm going to have a double spike near the end. Like I said, you can do whatever you want with these. It doesn't have to be exactly what I'm doing. Let me move that down slightly, but these are the first three. I'm going to make floor tile over there, add the double spike, Then floor tile four, I'm going to start adding in something more interesting. So I'm going to take that one away and I'm going to add in a spike ball over there. I think it looks quite cool. That is for tile. Floor. Tile five. I think I'm going to have a double spike at the beginning. Then let's maybe add a spike ball over here near the end. Like I said, you can really do whatever you want with these. You can follow along if you want, but you really don't have to floor tile eight. I think I'm just going to have spike balls. Let me get rid of that. I'm going to have one spike ball over here. Maybe one down over there, so you have to jump over it. We're going to tweak the movement script as we go along the game to make sure that it's always possible because this might actually not be a possible jump in the current state of the game. Just keep in mind that you're always keeping your scripts as adjustable as possible as you can make tweaks them. Luckily with our script, we obviously did add in those variables over here. Jump height and play speeds. We can kind of tweak whatever we want about the script for now, but we might add other stuff later on. Just make sure to keep in mind that the key to good game development, at least one of them, is always making sure you're adapting your game as you go along. Don't get caught trying to stick with something which isn't working before I get back to creating more tires. I'm actually going to delete these three prefabs. And I'm also actually going to change this prefab. What I'm going to do is I'm going to do what's called unpacking a prefab, which basically tells the game, okay? I don't actually want this to be a prefab anymore. I want it to be its own object. Again, I'm going to right click prefab and I'm going to select unpacked completely. And then I'm going to go ahead and get rid of these spikes. Now I have my original object back. Basically what I've just told Unity is even though I based my entire prefab off that object, I want to make it so it's its original object. Again, I want to sever the link between that and the prefab. I still have all my prefabs, but now this is just an object. Again, it's not linked. And you can see that it went from blue to normal colored. Again, let's go back over here, make a few more floor tiles. I think it's good to have maybe another one with double. Move that down slightly, then we can have a spike ball just over it. That's going to be quite a hard ones there. That's a little similar to 45, but I think it maybe be slight different. So let's move that there. May move it, you have to, it's a little higher up, so it's quite easy I guess. Then floor tile eight. I'm just going to make rather simple. Again, this one is actually just going to be a spike ball in the middle. We'll obviously edit these as we add more things because this isn't very exciting on its own. But once we play in the game, we're going to obviously have to run past to keep up with the camera. Even something like this might be a little more interesting than it actually seems at first. But anyway, moving on to floor tile nine. I'm going to have a spipal at the beginning because I don't think I've done that yet. We have to pass under that and jump over and then floor tile ten. Let's have three spikes. Those are all my tiles for now. I've got four with spike balls, without spike balls, and I've got six with spike balls and all of them have spikes pretty much except floor tile eight. These are going to be the building blocks for our map. And I mean that quite literally because they're actually what we're going to be spawning in when we write our map generation script. Now if you follow along this lesson and you've got a set of tiles, that's all you need to do. What we've done is we've created our enemy prefabs over here. And now we've created a bunch of tile prefabs as well. We're going to get started in the next lesson is we're going to actually write a script which is going to say, okay, spawn in these prefabs randomly so we can start generating our map. And then after we've done that, we're actually going to add in a camera pan script. Or maybe we might do that first actually. So make sure that the camera is continually panning and the player has to keep up with the camera. And that's basically going to add in our game. So you have to constantly be moving to keep all of the camera and dodging these obstacles. So all of that's coming in the next video. But if you follow along everything and you've got your ten tiles, that's great and we're going to start using them in the next video. Thanks. 6. Lesson 5 - Generating our map: Hey there, and welcome back to Unity. Now, in the last video, obviously we created all of our prefabs and all of our different objects which we're going to spawn in when we start making our map. But now we need to actually write the code which is going to tell Unity to spawn in our objects. This might seem like quite a tedious and complicated task, but it's actually a lot simpler than you might think. And we're going to split it up into two parts. The first thing we're going to do is we're going to write a script that basically tells the camera to constantly pan across the screen so we have something for the player to follow. Then second of all, we're going to write a script that basically determines that we want to spawn things based on the position of the camera. In other words, when the cameras over here spawn something there, and when the cameras over there spawn something over there, we constantly have these objects that are spawned as we're moving along. Before I get to ahead of myself, let's just get started by making that camera pan script. Let's open up scripts, our folder. Let's right click go Create new C sharp script and we're going to call it camera move. Now this is actually going to be an incredibly simple script. It's going to be a two lines of code, or actually even one. Or we're going to have is we're going to first get rid of both of these voids and we're going to use fixed update because we're simply going to have physics based output, or rather physics based calculations and processes in here. And we're not going to use any input or anything for this script. All we're going to have is this void over here, which is obviously going to run every fixed interval about a frame. And we're going to create two variables. The first of them it's going to be a public ridge body two D and we're going to call it RB. You don't have to worry about coming up with different names as long as they're in different scripts, you can use the same names. Obviously, you can't name two things, R B in one script, but we're allowed to use the same R B name over here, even though we're actually talking about something else. Anyway, the second thing we're going to have is a public float, and we're going to call it camera speed. All the code we need to right over here is actually very similar to the code we wrote for the player movement. We're going to go rigid body lost his new vector two. We're going to set it to camera speed and to zero. We don't actually need to set this to zero, we could also set it to the RB do losityty, but because we generally don't want our camera to be moving up and down, it really doesn't make that much of a difference. Let's just go ahead and set that zero, it doesn't matter. You could also just set it to blosityy, because you'll see when we set up our rigid body, it's really not going to make any difference because we're basically going to make it so the camera isn't affected by gravity. I'll get to that in a minute. But this is actually all the code that we need to have a camera that is going to pan along as we make our game more and more complicated. We might fix this and maybe make the camera speed up over time. In which case we're going to have a variable which increases with distance. And then every few, um, meters, or every few hundred meters or whatever, we're going to increase the camera speed. But for now, this will do just fine. Let's head back into Unity and go to our main camera object. We're going to drag our camera movement script onto it. Now we have our rigid body and our camera speed, but we haven't actually added a rigid body to this main camera. If we try and run the script, it's going to give us an error saying, I don't know what this rigid body is. You're trying to basically refer to it by saying, oh, set us velocity to this, but I don't have anything there so I can't actually do it. We're going to need to add a rigid body to our camera and let's go add component rigid body two D and click Play. You might be thinking, well, isn't this going to cause the camera to fall? And you'd be 100% right. In fact, if we right now we're going to see that our camera is actually going to fall down. It might look like everything's going up, but the camera is actually falling down. You can see it go down there, which is really not what we want, but it's actually a very easy thing to fix. Because we're not going to be using the same type of rigid body we used for our player. Our player uses what's called a dynamic rigid body. And that's basically a Ridgid body, which is affected by forces and gravity and a whole bunch of stuff externally by Unity. There's another type of rigid body, which is called a kinematic rigid body, which is influenced only by forces. This is like the normal, automated ridgid body in a way like it does things for you. It falls in free space. It knows when to stop and it knows when to move and slide. You can obviously add more movement to that like we did over here like we made, okay. When you click this button, then move in this direction. But it obviously does a whole bunch of stuff for us as well, specifically the falling and the movement before we add any coding. Now if I go to my main camera, I don't want that for this. I want this camera to only move when I tell it to move. Specifically, like in a script, we can actually see over here, the variable R B of camera move has not been assigned, was the error which popped up over here and we got it every single frame, which is what I said would happen. To fix this, what we're going to do is we're going to change this body type to what is called a kinematic ridge. Body can see the minute we do that, all of these variables massly in a drag gravity scale, all go away instantly. Because a kinematic rigid body is not affected by gravity or anything else. It only moves when I tell it to move. And we're going to go ahead and drag that into my script. Now what I have is a rigid body which is sort of like a rigid body that is fully manual, so I have to tell it, okay, I want its velocity to be this, just like I've done over here, okay? Set the velocity to this variable camera speed. When I change this variable camera speed, it's actually going to change the velocity. You see an action over here. If I click play, it's going to load my game, and right now it's set to zero. I think I click play twice. Let's click that again. Click. Right now it's set to zero, so it doesn't move at all. But if I set this to one, we can see the camera slowly start to pan across. If I said to minus one, I'm going to move in the same direction. If I set something like five, you can see I go a lot faster. And minus ten I zoom back. You can obviously edit this to be what you want. I'm going to start off with a basic panic speed of three because I think that will be good for the start, especially while I'm developing my game like you said, you can obviously tweak all of this stuff. Now, that actually might be a little fast. I'm going to make this 1.8 that looks a lot better to me. And you can see now I can follow along with the camera. I obviously can't make that jump yet, but basically now we have a script that tells the camera, okay, move along at this speed. That's all grade and all, but we don't have a map to generate. We don't actually know what to spawn in, and we don't really know where to jump to because we can't. First thing I want to do is I'm going to move that down over there. Because I don't really want it to be an impossible map, especially if it's the first thing that you encounter when you play the game. What I'm going to do is I'm going to now start writing code, which is basically going to tell the camera or whatever object I want, but I'm going to use the camera to spawn in certain objects. The minute I reach certain length, at a certain interval, I want to spawn in an object. And the way I'm going to do this is I'm going to look at the length of my objects, go to open prefabs, and I'm going to see how far apart my objects be. I'm going to start by clearing out a few of these floor tires I had originally, not permanently, but I'm going to click three of them and I'm going to click the little icon on them. They are hidden from screen. I don't actually need to select them, it doesn't make a difference. But I've just hidden them for now. They're still there, but I don't want them to be in my screen. You can hide them or show them using a little icon. In fact, you can hide the entire scene if you want, but we don't want to do that. I just want to hide my three floor objects. What I'm going to do is I'm going to add in new objects. I want an object about there. I think I want the spaced objects to be about that big. Let's see if I've got my first object. I'm going to set it as an easier position. Let's make it negative 6.5 I'm going to make my new object 1.5 See over here. Now we've got two objects which are pretty evenly spaced out. Let's add another one over here and we'll make this 19.5 We add one more after that. Let's add in floor tile seven, and then maybe floor tile eight of that, we can make 17.5 We can make 25.5 We can see we've got negative 6.5 then we've got 1.5 then we've got 9.5 Got 17.5 and we've got 25.5 We can see we want these to be about eight units apart each, so I'm going to keep that in mind. And I'm going to say every eight units that the camera moves, I'm going to want to spawn in a new object because it means that I'll have moved about one of these things. The way I'm going to do that is I'm going to create a new script. And I'm going to call it map generation. The minute that script has been maimed, I'm going to double click to open it. This is where I'm going to actually create the logic to spawn in my different object. I'm going to first start by making a new public void. I'm going to call it spawn map piece. What this method is going to do is it is basically going to take one of the random map pieces that we designed earlier and spawn it into my game. Now the way I'm going to get a random map piece is I'm going to create a data structure known as an array. This is quite an advanced coding concept. It's actually quite a rudimentary one. But in terms of what we've covered already, it's quite a leap. So I'm not going to explain exactly how it works and all its uses. Basically, you can think about it like a list. I've got data types, which you've already talked about. Like I want to store numbers, I put them in an integer. If I want to store lots of things, whether it's a lot of numbers or a lot of words, I put them in what is called an array or a list. And the way you declare an array is you go public, you're going to type the data type which you want in your list. I actually want game objects because game objects, like we mentioned before are the boding blocks of our game. And all of those tiles which we made are actually examples of objects even though they're prefabs. So they're like object templates. They're still of the data type object. To show that it's a list and not just one game. Which I'm going to add these two square brackets afterward, which tells Unity, okay, this isn't one thing, it's a list of things. I'm going to call it map tiles. Now this is basically where I'm going to store all of my map tiles. If I go back into Unity and I go back to my main camera, I'm going to see over here, if I drag in my map generation script, let's put it above the rigid body and let's actually move the ridge body up over there. See now I have this map tiles and it's currently got nothing in it Says list is empty. But I'm going to start populating it. I'm going to put ten things in my list. So I'm going to change this number ten. I'm going to add in the ten map tiles which we created earlier. Let's go to prefabs floor tiles and just put in floor tile one floor tile two floor tile three, floor tile four, et cetera, et cetera. Until we have every single floor tile which we've just made inside this list, this is actually going to be how we're going to spawn them in randomly. Don't worry about exactly how a rays work. Like I said, like there's a few finicky things, especially if you have encoded before, like they start at index zero, this is actually element nine, even though Element. Obviously, these game object, the actual concept of variables and all that stuff might seem a little confusing, especially if you've never coded before. But just think about it like a list of objects. We've covered what objects are, the building blocks are our games, and we've got a list of object templates, which we're going to spawn in. Basically we're saying, okay, all these files we've made, put them in the data structure, which is called an array. And I'm going to pick one out of this array randomly every time I want to spawn one in and put it in my game. The next thing I need to do is I need to actually write the code to do this. Let's go back into my code over here. And I'm going to say pick a random member of my array and spawn it in. The way I'm going to do that is as follows. I'm going to say game object tile. So I've got a new local variable which is like a local storage space. It's only accessible inside this method. I don't have to put it in here, but it just is better for performance because I don't need it to be accessible anywhere else. I only need it in here, say equals map tiles. Now to access a specific element of the array, I use square bracket. So this is saying, okay, open the first one. What this code will do is it will say, okay, take the first element in map tiles, which is floor tile one, and put it in the storage space tiles. But I don't only want to be the first one, I want to be a random one. To do that I'm going to use a random, I'm going to go random do range. What this is basically going to do is, is going to allow me to pick a random number from a specified range as you can probably guess from the name going to go open parentheses. And now we need a minimum inclusive and a maximum inclusive. Now I don't exactly know why they say maximum inclusive, because random range 1-2 will actually only ever return the number one. The reason why they say inclusive I think is maybe referring to floats, but with integers it isn't actually inclusive for the top, it's only inclusive for the bottom value. Let's go over here and let's set the bottom value to zero, which is, like we said, the very first element of our array, which over here is floor tile one. But we want it to be any one of these elements. And we could just enter from element zero to element nine. We could just enter something like this. Obviously, like I said, it's non inclusive. We'd have to put ten in over there. But this is actually going to work perfectly fine for our purposes. This needs to be a square bracket, not a round bracket because we're referring to an array. And an array, you use square brackets to say what index you're referring to. Anyway, this would work perfectly fine for our purposes because you're going to pick a random number every single time. We call that from zero all the way up to nine. But the reason why we don't want to code it like this, this is what's known as hard coding, where you put in exact values instead of what is known as, I guess, dynamic or variable values. The reason why we don't want to do this is because let's say we decided to add in a whole bunch of new tires. We add them to our array. We have to go back and change this code instead of having it automatically update to include the entire length of the array, which is what we want. Instead of using ten, we're going to go map tiles dot length. Map tile dot length is actually going to give us the number ten over here, because we can see we have ten different elements over here. Map tiles has a length of ten. I think that's maybe one of the reasons why the index starts at zero because this range command is obviously not going to include this top boundary. And we're never actually going to try and access the tenth element, which would give us an error because there is no tenth element, there's only a ninth one all the way down to a zeroth one. It's a little confusing at first, but you should be able to get it the more you use arrays. And it's a convention in computer science, I guess you get used to it after a while as well. But regardless, this code over here is going to say, okay, give me any element in the entire array. It might seem a little confusing, but basically all we're doing is saying, okay, we've got this list of things and at the specific index, from the smallest index all the way up to one plus the biggest index, which will give us all the way up to the biggest index. Give me an index from there. That is going to give us now a random tile every time, which is half. What we need to do now, all we need to do is actually spawn in that tile. So we're going to say instantiate tile as game object. This line of code over here is basically what we're going to be using to spawn in our prefab. So we're saying, okay, I've got this tie over here now and I want to put it in my game. But we can see over here we get an error message that says, okay, only assignment call increment, decrement a weight. And new object expressions can be used in a statement. Which is basically like saying, we've got half a statement here, we've equals five, we haven't got the other side. So I'm saying, okay, I want to instantiate as a game object, but what do I want to do with that? We're going to have to store that in another variable. Call this game object map tile equals instantiate tile as game object. This is not incredibly like needed code. We didn't really need this variable because we could have actually just taken this and put it in there. But I'm going to lay it out like this just because it makes it a little nicer to read. First, we've got this game object tile, which is a random tile. And then we're going to instantiate this tile and we're going to call it Map tile or rather Game tile. The actual tile may well change the name to Spawned tile. We can differentiate between what we were going to spawn and once we've actually spawned it, now we're referring to the actual object created, not the prefab. So this is the prefab. The actual object that it made. And we need to add a few things. First of all, we need to change where its position is. Actually, that's all we need to add, because right now it's going to be spawning it, but we don't know where it's going to be spawning it, we want to change where its position is. We're going to do that by changing this variable, a spawned tile. Let's go spawn tiled, transformed position equals. Then we're going to take our current position of our camera. We can do that by using a lower case game object, which is saying, okay, refer to the game object which this script is currently attached to, which is going to be our camera transform position. That's basically saying, okay, set our transformed opposition of our spawn tile to exactly where the camera is. We don't really want it to be exactly where the camera is, we want to be slightly different. Let's create a new vector three. This is saying we want to store three things. We're going to have x, y, and z. Let's set the game object transform position to our current position of our camera plus some offset. And we'll create a new variable, public float offset X and add it to our players rather our cameras current position. Now this is going to do is going to say, okay, spawn in a tile and put it at wherever my camera is plus a position. So this should be good enough. But we want to, remember, we also don't really want it at the Y position of our camera, because our camera is going to have probably around a zero Y position. And we want it to be on the bottom half of the screen. We don't want to be in the middle of the screen, so we're going to create a new position for spawning in our objects, but we want to know what the boundaries of that should be. And to do that we're going to hop right back into the Unity editor. We're going to see, okay, where about should be. I'm going to look at this and I'm going to look at these y values and decide I think I want my object to be anywhere from say, -4.5 I think that's about the lowest I want it all the way, all the way up to maybe -3.5 might not seem like a lot, but it is quite a variable amount of space, especially for our small jump height. We might change that jump height later on, but I think that's good for now. Let's go ahead and set this to minus four. I can't remember exactly what it was, but I think it was around -3.9 Now we're going to use another random range statement to basically say, okay, anywhere between those two points, I'm going to use those points actually as variables. Again, public float min Y and max Y, which we're going to assign in the Unity editor, which we'll get to later. But I'm going to say, okay, I want my Y position to be anywhere from this random range, just like we used previously. And I'm going to say my all the way up to max Y. Lastly, we can just set its position to zero because we're using a two D game. Now what this is going to do is, is going to say, okay, every time we call this spawn map piece, we're going to spawn a new map piece. And we want to spawn it wherever we are in our game. Plus an offset X, which we'll figure out as we're playing the game experimentally. We're going to go figure that out now. And we want a random range from -4.5 -3.5 which we're also going to add now. Now the last thing I'm going to do before I go back to Unity is I'm going to basically allow me to test the script. I'm going to say if input get key down keycode space, then call my spawn map piece. I didn't add the code back over here. This is the same thing because it's only one line of code. You don't actually need them, but you can split them in if you want to and just make sure it's inside that block. But just for the record, having an indented line is the exact same thing. It just looks a little bit neater over here we're saying okay, every time I click the space bar, run this code. This is actually going to allow us to test our map spawning script. To make sure it works, let's go right back into Unity. Let's see, right into our main camera script. The first thing we want to do is we want to configure this offset wise. I'm going to guess it's going to be, if I go over here and I move it, I'm going to want to spawn it about there. That's about 15 hour cameras at zero. So I'm going to guess it's going to be around. But I'm obviously going to be able to configure that as I move on. I think this was 6.5 Let's go ahead and set that offset y to 15. We want our min Y to be -4.5 max y to be 3.5 Let's see if that works. I'm going to start by not moving my camera at all, just so I can see if that spawning does actually look around where I want it to be ahead I'm going to hit. You can see actually when I click my game, my three floors that I hit before are actually still here. We go back in there and go ahead and delete this floor tile. And I have it like I had it before. I'm actually going to move these a little bit. I don't. It seems like they've adjusted. I'm not entirely sure why. Interesting. Regardless, let's go ahead and click Play. And then let's see what happens if we click the Spacebar. We go back into our scene. We can see, okay, we've actually got a random thing spawning, which is great. We want, if we move it away, click a space bar again, we've got a different thing spawning. And that actually looks pretty perfect to me. If I click it a bunch of times, they've actually got variable height. So some of them are spawning slightly higher than the old ones, and we've got different things spawning, which is perfect, this is actually exactly what we want. The last thing we need to do now is we need to make sure that this is happening automatically. As long as the camera moves every eight units, we want to spawn a new one. So the way they're going to do that is going to head back right into our code. And the first thing we're going to do is we're going to get rid of this testing code because you don't want to spawn in our tiles every time we cook the space bar, we want to spawn in every time we travel a certain distance. The first thing we're going to do is we're going to create a few move variables. Let's create a public float and we'll call it Spawn Position. This is going to keep track of exactly where on the X plane we spawned our last map piece. Then let's go ahead under our start void and spawn a map piece. This is basic, going to say at the very start of the game, reber these parentheses when you're calling a specific block of code at the start of our game before you even start playing Spawn in a map piece. Because we can see if we go to Unity, we don't actually have anything over this. We want to do it the minute we spawn in. But then the last thing we're going to do to make sure that we know to spawn in a new one every time we need one, it's going to go down here to the spawn position variable and we're going to set it to our current transform position x. This is basically a shorthand way of saying game object transform position X. We actually don't need this game object thing over here because using a lower case refers to the transform attached to this game object you see over here. If we hover, it explains it for us. This is saying, okay, set our current spawn position to the transferred opposition dot X of our camera object. The minute we spawn in a map piece, keep track of where is we spawned it on the X plane. Then we're going to add in our if statement to our void plate. We'll say my current position minus my spawn position. In other words, if my displacement from where I currently am to where I last spawned my last tile is greater than eight. In other words, if I've moved eight units since I spawned a last tile, it's time to spawn a new tile. We have to write if my transferred opposition dot x minus spawn position, put parentheses around those is greater than or equal to eight. In other words, if we've either moved eight or more tiles, then we want to call in our spawn map piece. That's obviously going to reset our spawn position to my current transfer position to X. Then the next update, this will not be eight anymore. If everything is written here correctly, it should spawn in every eight piece is a new map piece, and we should see that in action. Or you go back to the game. Let's go ahead and click that, make sure that everything is configured like we need to be able to set this back to 1.8 Let's keep track of the spawn position variable as we click play. Let's go ahead and hit play. See what happens moving along, looks like our first tile did spawn in perfectly well. And actually if we look along, we can see it is spawning just like we needed to be. We go into the scene view, we can actually see these tiles getting made as we move along, just in perfect time. Over here, a new style spawn spring out exactly as we needed to the minute before it hits the screen. We've got our new tile over there, and obviously the players getting left behind a bit here. But we can actually see this is creating a pretty cool auto generating map. And this is actually going to be the heart of our platform, a game. We're obviously going to change this and add a lot of new cool things, and different objects, and different templates as we get onto our game. But this is basically going to be the template for how we're going to start making our game and how everything's going to work. Right now, we've actually created the basis for what is a pretty cool system for spawning in tiles and creating an auto generating map. Now the very last thing we need to do is we need to make sure that we actually delete the tiles that we're no longer using. If we go ahead and we hit play, we can see that we can spawn in tiles great. And they actually work perfectly. We can see over there, they get created over here, but they never actually go away. As this continues on, if I ramp up the speed, this will actually work just as well because it's based on position, not anything to do with time. So we can actually see we make more and more tiles, and it all works perfectly. But these tiles are here and they're actually clogging up my scene. And I don't really want them to be there. After a while, what I'm going to do is I'm going to add one more line of code, which I'm going to attach to the tiles. I'm going to have a little line of code on each tile which says, if I am this far away from the camera, I can destroy myself. Let's go ahead and measure what that doesn't should be. I think that the minute tiles are around here, they should probably get destroyed. This is currently at Exhibition 111.8 Let's say it's 112 and the camera is at 01:20 Let's say it's 130, let's say the minute they are 18 units behind the camera, then they can destroy themselves. And that's an incredibly easy script to write. Let's go right click, Create C sharp script, we'll call it tile clear. I'm going to add this to every single tile, Double click to open it up. And we're just going to need one variable over here, and it's actually going to be a reference to our main camera. So I'm going to create a public transform. This is actually referring to a game object, but I'm saying I only need the position and the rotation and the scale of the game object. I'm going to reference my camera in this variable, but I only want its position. I don't need anything else. Call it. Now the important thing to note is that we usually assign these transforms in the Unity editor. If we drag it onto our prefab and we say, okay, I want that camera. But the thing is because prefabs aren't actually objects in the game, they are technically files in our program, We can't really do the same thing here. I actually want to go ahead and drag the script onto every single one of my prefabs. So I can do that by going onto every single one of my prefabs and clicking Add Components, and our name, what I call it, tile clear. This tile clear script to every single one of them. Just do it quickly. I believe you can actually do it multiple times, once if you select all of them and then add tile clear, it should add to every single one of these. I think that worked. You can see every single one of them has this tile clear script now attached, which is pretty cool. But the problem is we can't actually reference this camera because like I said, this camera, it's looking for an object and we can't drag in the camera because this is a file object. You need to write some code to find that. It's quite simple. We're going to say cam equals game object. Find, call it main camera because that is what it's called. And that's going to say the minute I get into the game, the minute I start existing, find main camera, which we have right over here, and assign it to this variable. It's basically like we dragged it in just like before. It's just a different way of doing it. And I'll go ahead and go transform, because I only need the transform of that game object. Then the last bit of code that we need just to say basically destroy myself when far away is I say if my position transform dot position x minus the cameras position. In other words, cam position x. We say if I am more than 18 units behind, if my position is zero and the camera position is 18, I'm going to be negative 18 to say is less than or equal to negative 18. I could actually write this the other way around and say if the cameras position minus my position is more than 18, if the displacement is greater, this is the exact same thing. Then I'm going to say destroy game object. In other words, remove myself from the scene. This is actually all the code we're going to need to take care of that problem we're talking about before. Before I do that, there's one more thing I'm going to do over here. And it's just going to be a really simple fix. I'm going to create a new public transform. I'm going to call it tile storage underneath over here. Once I've created my spawn tile, Spawn tile transform. Set parent, which is basically saying, okay, set the parent object. We're going to use a folder just like we did in the past and we're going to set it to tile storage. That's basically just going to say, okay, the minute I make my new object, put it underneath this empty object, which I'm going to create now call it map tile storage. Let's set it to zero over here. This is going to be what we're going to put all of our objects on this. Let's go back to the main camera and drag that over here into tile storage so we have our new transform. Lastly, the last thing we're going to do is make sure that our tile spawn script works. Delete script rather. Let's go ahead and click play. And we should see everything work just as it has been. See over here, it got put into tile storage, which is great. And let's watch what happens as we move along. We've got all of our new tiles going here. This tile here does have the tile clear script. The minute it is a certain distance from the camera, it should actually delete itself and stop existing. I think it will. There you go. This actually worked really, really well. This is going to be the base of our game. We can make this camera as fast as you want. It doesn't really make a difference. We can see exactly how it's going to work. This is how the game is going to play. We're going to have all of these tiles which are ranoally being made. You can see some have duplicates, but this is going to be the gist of the game. Go ahead and play, stop. And I said this to a slight more exciting speed, like three, and I hit play again. I can get a gist of what the game is going to be like once I'm playing, as I'm moving along. And I'm always going to have to dodge certain things and play like. So this is going to be the basis of my platform game. Obviously we're going to add in sprites and make it look a lot more interesting and exciting. But this is what we're working with at the moment. I don't think it's going to be this fast because this is, um, I guess, intense, especially for a game which is going to have things like coins as well and more complicated enemies. But this is going to be the gist that is the basis for our map generation script. And I said this back to 1.8 That is basically all we're going to do in this video. We've created all of my prefabs in the last video and now we've created not only a camera pan script, but also a dynamically spawning map, which is really, really cool. This is actually the first kind of main aspect of our game which we've completed, which is really, really sick. Good job on following the video if you made it all the way through and hopefully your game is working just as well as mine is. Obviously link all of my code and my prefabs in the folder just like I have been doing this entire time. And if you need any help and need to look over them, you can go and find them over there. But hopefully your thing is working just as well as everything mine is. And it's all going pretty smoothly. And you're making some pretty good progress with your intermediate platform game. In the next video, we're actually going to get started adding sprites and you're going to see this game start to come to life and look a hell of a lot better than it does right now. Then we're going to start adding more interesting enemies and everything else after that. But for now, that is all we need to do. And we've kind of got the basis of our game running, so great job. And in the next video, we'll get started adding our sprites. Thanks. 7. Lesson 6 - Adding sprites: Hey there, and welcome back to Unity. Over the last few lessons, we've created what is pretty much the basis of a platform, a game. We've created a character who can move. We've created a map which can generate randomly. And we've got obstacles which we can dodge. And we have a camera which is continually panning, which we have to keep up with. That's pretty much everything that we need to make a basic platform, a game like we've done it already, but there are a few things missing. First of all, you can run into the obstacles and nothing happens. Second of all, the camera doesn't actually make you stay with it. You can go out and come back in. There's no penalty for that. Third and almost most importantly, the game doesn't look great. We've got a square, jumping on other rectangles and dodging triangles and circles which are yellow, white, and red. That's it. You can make a game with shapes. I've done it quite a few times in the past actually, But for this specific platform, because it's an intermediate platformer, I thought it'd be good to use sprites and I'm going to be using pixel art now all of the sprites I'm going to be making for my project are going to be linked throughout this course. You can find all of them as downloadable links as I go along and I import new files. Any file that I use throughout this entire project, you should be able to find as well. I've made a whole bunch of sprites for this game. If you want to use the same sprites that I'm using, you just have to go ahead and download them from this video's description or underneath the course, you can find a link for this video's downloads. Now like I said, you don't have to use my sprites. You can use your own sprites, or you can use squares and triangles. It doesn't really make a difference. But if you want to follow along and use the sprites I'm using, then you are going to have to obviously download those files. You can use the same ones. That being said, like I said, you don't have to use the same sprites as me. But it is important to note that sprites do in quite a few ways determine how we're going to balance our game. For instance, if we had the sprites I'm going to be using are going to be a minor, and clouds. And so I'm going to want to tweak a few things about the game. I may be going to make him jump higher. We want to make the spawn further apart just to make it look more like clouds. And those kind of tweaks we can make because we've got variables on our scripts that allow us to control that. Like we've got a jump height here and we've got a spawn distance for the forms over here. You obviously don't have to copy my exact values. But if it's your first time coding and Unity and making a game, I would recommend following along with me as I do import sprites and use the same sprites I'm using, as well as maybe the same values. Because it's going to make it a little easier to compare your game to mine. And you'd be surprised at how much tweaking little things can make a game feel different. You don't have to do exactly what I'm doing. You don't have to use the same sprites, I am. But I would recommend if you want to make the same game. I'm maybe do use the same sprites and maybe just tweak it as I do because it'll feel very much the same. Like you don't want to get stuck with a similar game. That's not really what you wanted. With all of that being said, like I said, totally your decision. But I'm going to get started using my own sprites. I'm going to go down here to the project folder, right click. I'm going to go create a folder and I'm going to call it sprites. Now there are a few ways you can put sprites into your game. Sprites are actually just files, They're visual representations of objects, is what I like to call them. We've actually got a few ready. Like we've got a square sprite there and rectangle sprites down here. Well, they're actually just stretched square sprites. But we want something slightly more interesting. We're going to need to import files into our game. There's a few ways you can do this. You can double click the sprites folder and you can go import New Asset. You can open up File Explorer and you can drag them into this window over here. Or you can actually go into File Explorer, find where your game is saved, and just copy them into this specific folder you've just created. This is not the best way to do it. I recommend you choose one of the first two. I mentioned just because the way Unity works is when you import a file, it creates another file which it needs called the metafile. For every single file you import, let's say you import something p four, it'll create something meta or something p four domtaI'm, not sure exactly what it calls it, but it basically creates a metaphile. Which without needing to go into too much detail, is how unity works with imported files. It needs it to function properly. And these metaphiles are automatically created when you import your files through Unity. But if you don't have Unity open, or even if you do, and you do it directly with File Explorer, then it's not going to make those files for you. Unity does a pretty good job of creating them automatically on launch and things like that, but just to avoid any hassle which may arise, I recommend you import your files using this important new asset window over here. Let's go into our folder. Let's go import new asset. Let's put in these four sprite assets which have made, like I said, these are all obviously linked underneath the video, so you can just import them into your game like so. There's a few things we need to do before we put them in our game. I'm going to select all of them. The first thing I'm going to do is I'm going to change this filter mode to Point No Filter, because this is a setting you want for Pixelate and you can actually obviously have to click Save before I show you. But you can also click Apply over here. Now you've got Point No Filter, and you click Apply to add that. The reason for that is because this filter mode actually blurs the sprite slightly. And if you use pixel, it doesn't look very good. I'll show you that if I drag the sprite into my game and I scroll down so I can see the sprite there, you can see all the pixels. If I choose bilinear filter and click Apply, you can see it makes it very blurred, which is not what I want. I want to choose Point no filter so that I have the entire sprite clear. Then second thing I'm going to do is I'm going to change this pixels per unit because I don't want sprite to be that small. I want it to be maybe ten. And actually, the lower this number is, the bigger the sprite is going to be. I think that's quite a good setting for me for now ten pixels per unit. And I'm obviously going to want to change that to all of them out here, make sure all these pixels per unit are set to ten. And the filter mode is 0.0 Filter and click Apply. The way I could actually see that sprite is by dragging it directly into my game. And what this does is it creates an object for my sprite with a sprite render. So it's actually the same as going right click, new object chooses a triangle. It's the exact same thing, it's just this uses a triangle and this obviously sets whatever sprite I've dragged in as the default sprite. But I'm going to delete these because I don't want actually want to make any new objects. I want to assign these files directly to the sprite renderers I already have, which are the square and the stretch square and the triangle and the circle. That's a lot of terminology I'm throwing at you and it might be a little bit confusing to think about everything in game development context. But just know that at the moment all we've done is we've imported these four files which we're going to use to add a bit of lifestyle game. And we've currently got sprite renderers, which are rendering kind of default sprites. We're going to replace those with these sprites which we've created. So make sure you get the settings as I do. And then we're going to first start with the player. Let's go to the player and we've got a sprite quality over here, which is where we're going to drag in our sprite. Let's drag in minor one. We see instantly, it looks a little bit sickly. And that's because we've got the color still set to yellow. Let's set that to white, I'd say. That's actually a pretty good size for my player. I want it to be a rather small player in the middle of the screen, I think that's actually good. But there are a few things I need to change. And this is what I meant when I said that sprites affect your game quite a bit. Obviously, all the colliders and the jump heights and every other variable or tweak you have to make, your game is centered around how big the sprites are or rather what the sprites look like. If you are using my sprites, which I do recommend that you do, it will be a lot easier to follow along exactly what I'm doing than if you use your own. But that being said, you can use your own if you know what you're doing, because you just have to make similar tweaks for your game. Anyway, that being said, let me first change this Box Glider to make sure that it fits my sprite. And you might think that this is actually a pretty good kind of fit for my sprite, but I'm actually going to make it a little bit smaller. And the reason for that is if we're playing a game and you have something like a bullet or a projectile hit this very top of your screen over here. So let's say something goes and it hits you like there. That's not actually hitting the sprite, but it would hit the collider. And so the enemy, you rather the player would take damage, which can be quite frustrating if you're playing a game. So generally, it's a good idea to put this sprite render sort of as low as you can over here, so you obviously don't fall through the ground. But then we want to make it a little bit smaller, so we want to make it something like this. Now if you get hit here, technically you won't die. But if you get hit over there, anywhere inside this block, which is the main player, we can actually even make it a little bit smaller, like over there. Then you're going to take damage or maybe even die and have to start the game over. But basically, it just makes it a little bit more fun for the player to play a game where he's not constantly being penalized for being hit at the top right pixel of the character. Follow that along. Obviously, whatever player you've got to make sure that he or she fits inside the bounds of the box clider, but not exactly that you have blank spaces. I think that's pretty good. For now. I've changed my box Clider. I don't need to change anything else. The ridge body isn't affected by sprites. The player movement should be fine. It's about the same size and I've changed my sprites. If we go ahead and hit Play, you can see now I actually have a minor character and I can move them around and jump. Obviously doesn't have any animation, so it looks a little bit goofy. But this is actually the start of adding in sprite style game. And you can see that actually makes a pretty considerable improvement to how our game looks. I mean, obviously, like I said, it looks dumb now. But if you kind of just took a freeze frame over there and looked at it, even though it doesn't really fit with the art style, It looks a lot nicer when you have actual things in your game than squares. A lot of the time, like I said, squares can be cool. I've made lots of games with just shapes. But in this kind of instance, for this kind of game, it makes it look a little more professional to have actual sprites. So let's not stop there. Let's actually go ahead and add all of the other sprites we need to our other objects. There's a few changes we're going to need to make here. The first thing is because we're going to be using clouds as the platforms, we obviously need them all to be the same size because we've only got one cloud sprites. They all need to be that big. That isn't actually an issue for all of our tiles over here, because they all are the same size. But these three ones at the beginning are different sizes. So we're going to have to change those a little bit. I'll get to that. But let's just start by going over here into my sprites folder and dragging in this cloud. Now we can see already it makes it look a little bit weird. We've got an incredibly long and flat cloud, and I'm going to fix that by setting the scale back to one. We have the default size for our cloud. I'm going to do that with the other two floor objects as well. I'm actually not going to choose three because two are more than big enough for my game. I am going to tweak this a little bit as I get further along in my game, but for now, that is fine as a starting point for my game. The last thing I need to do is obviously change the colliders. Because that is not the collide. I want, I want it to be something more like this. Let's drag it up a little bit. Over there and down across. Like I said, you obviously don't want the collider to be necessarily like this because then they can stand on nothing, but you also don't want it to be here As they are halfway through the cloud. I'd say a good balance would be somewhere around there. You can still get a little bit behind the clouds, but you can still see yourself, maybe move it a bit up, obviously down. It matters less because you're probably not going to be jumping them from below. But that should be good. You don't want to really do this kind of thing with project, with clouds as much. Because you wouldn't really want to fall off if there is cloud there. But you can do it a little bit, maybe something like that. Like I said, this doesn't have to be perfectly exact, but you will get a feel for it as you play your game and be able to tweak it. These are obviously your colliders. I'm actually going to delete this flaw and just kind of copy this one along because I don't feel like resizing that again. And they should all have the same sort of size collider. If I go ahead and hit play now we can see how that looks. Jump in and I can fall onto this cloud and I can move along it. And I mean, it looks pretty. Okay. The one problem is the player is kind of continually in front of the cloud. And that's actually not what I want. I'd rather have the player be behind the cloud. To do that, I'm actually going to use a variable inside this Sprite renderer script, and it's called order in layer. I'm going to set clouds to be order in layer six. I'm going to set my player to be order in layer five. Now we can see when we go ahead and play the game, we should be able to see the player actually fall behind the clouds just a little bit more what I wanted. And I think that looks a little bit better in terms of gameplay design. Now, we obviously have just added these sprites in for the first two platforms. We haven't added any of the floor tiles over here. There are still the default rectangle, so we're going to need to fix that. Let's start by going back into sprites and dragging that cloud right back in, setting the scale back to one. And now it's going to be a little bit tricky because we're going to have to change this exactly like we've been trying to do the whole time. We first have to change the Box glider, and then we're going to have to adjust every single one of these child objects so that they are the correct size for the sprite. This unfortunately is going to be quite a lot of work because we now have to remake all of our sprites that or rather all of our tiles which we've already made in terms of the new sprites. If we were to go into every single one, we have to edit the Box glider, we have to add new things, we have to change it all. It's a bit confusing and it's quite a lot of work. There's actually an easy way around it. It might seem a little car intuitive, but what we're going to do is we're actually going to back space that we have exactly like we had before. Set it just like it was normally before we added in that sprite. And then we're going to create ten new prefabs, and we're going to use these as reference points to make our new prefabs with our sprites. Then we're just going to delete them afterward. This might sound like a lot more work, but it's actually considerably easier in the long run to do it this way than what we did before. The first thing we're going to do is we're going to change the spike and spike ball prefabs because that's actually the first step. We have to remember that these prefabs inside our prefabs are actually prefabs themselves. So we have to change these. Let's get started by changing the spike to the spikes sprite. See that actually doesn't look that bad. We have to change the scale back to one. It's very important that you use the same scale when you're using pixel art. Because you can't have one pixel be smaller than the size of the other, it looks really bad. Make sure all of your scales are set to one. I actually need to remember to do that with the player as well. Before I forget, I might have to change the size of the sprites per pixel unit, which we set originally over here, this pixels per unit. But make sure you set everything to the scale one, otherwise it's not going to look great. We've got our clouds at one and our player at one. That's good. Let's go back to our pre fads and let's show our spike is at one, and we need our spike ball to be at one as well. Anyway, let's go back here. Let's start by making the color normal color, which is white. So we're not going to change it in any way. And then I'm actually going to remove this polygon collider, and I'm going to add in a simple box collider. And you might think that it makes more sense to add in maybe three polygon colliders, but trust me, this is incredibly overcomplicated for what we're adding here. It just needs to be a kind of basic collider mistake that a lot of new Unity developers make, is they try and make their colliders as accurate as possible as adding maybe a line here, a line here, line here. It's really not a good use of your time. And you can make something like this and it will get the job done perfectly well. It actually makes the game a little more enjoyable to play because you don't want to die if you hit, like I said, the tiny little top of a spike right there and the player won't even notice when they're playing the game. Just you can use box glides for a lot of stuff, Obviously we're going to use a circle here. But for this, a box glider will do more than fine. Anyway, let's open up the spike ball and do the same here. Go to sprites and drag in the spike ball sprite, change it to white so we have the normal color. And then we can actually just increase the size of the circ lide a little bit. Instead of using this edit collider, I'm going to use this radius set to 0.6 I think that's actually quite good already because like I said, you don't want to die if you hit the end. But this is the majority of the sprite, so that's fine. Yeah, that skid right now, we've got our prefabs for our sprites actually done. We've changed the sprite and we've edited the colliders and we made sure it's set to scale one. Now if we go back into our floor tiles, we'll be able to see them add it to a game. But they might not look that great. Like for instance, this one's in the cloud and they're a little bit bigger than they were before. Something like this is merging them together, Obviously they're a lot lower down. So it makes that jump a little bit harder because they're also wider. Like I said, all of these prefabs are actually a little bit ruined now in a way. But we're going to do what I said before and actually just use a whole bunch of new prefabs because I think it is actually going to make it easier in the long run. You can either way is going to probably take about the same amount of time because we could just change every single one of these sprites, add the box Clyde, add to them, but then we have to move all of these up to adjust for the new size. You God, have to change pretty much everything we've already added. And it's really, in my opinion, not that much faster or even faster at all than just making new prefabs. So let's go ahead and drag down a new floor. So we have a new prefab. And let's start just by unpacking this prefab. It's no longer linked. We've just created a reference, now we've got our new prefab. Let's call it floor tile, one A. I was going to copy this ten times. We've got floor tile one A, we're going to have floor tile two A floor tile three A floor tile four A, et cetera, until we have all ten floor tiles with a copy of themselves made. Once you've done that, you can pretty much just get started remaking all of your old prefabs as new ones. I'm going to skip ahead because it's quite a tedious process and you don't really need to see me editing mind. But basically with the new sprites, just make a whole bunch of new prefabs based on the old ones you had. And make sure that once you've finished your prefabs, they have all of the attributes that the old ones did. So your tile, clear script and your box slide and all of that stuff. Make sure that that's all on the prefabs. And once you've done that, then you're good to go. Once you've finished making all your prefabs, that should actually be everything as we needed done, but there's a few more changes we need to make. First of all, we need to delete all of our old tiles over here because we don't need them anymore. We've got our new tiles with all of our sprites. We've got floor tile one A, all the way through to ten A. The other thing we do need to change though is we need to go over here to this main camera. We can see our map tiles are all now missing. Because what we've done is an array over here that says, okay, use this map tile, but the map tile is not there anymore. It says, I don't know where the file is. We need to replace them all with these new tiles we've created over here because they are actually new objects that we've made or rather new files that we've made. That is actually everything we need to do to create our new sprite based game. Let's go ahead and hit play. And we can see now we have clouds and a minor jumping on clouds. We have our new sprites spawning in just like we wanted them to. We've got our sprite over here, which has two clouds, and we've got a spike there. The one problem, however, is that you'll notice that the sprites are actually way too close to each other and the jump pit isn't high enough. These are all tweaks we need to make. We had to test our game to see them, but the clouds are actually spawning on top of each other. That's not good. This isn't actually exactly what we want. Let's go ahead and actually fix this a little bit. First thing, luckily, is that we've actually created all of our scripts pretty much dynamically. We've got this offset variable over here, which denotes how far the clouds should be away from each other before we spawn a new one, we look at this one, it's negative 5.55 this one is 4.2 These are technically less than 15 apart, but when we actually start adding in our script, it doesn't work exactly like that. What we're trying to change is how frequently they are, not how much they spawn. We go back into the script over here which generates our map. We can actually, we've hard coded this value over here to eight and it's not actually a variable we've used. Let's fix that. Let's go back here and let's call it spawn frequency. Let's make sure we set that to the variable over here. Obviously, offset is actually how far away it spawns in front of the camera. Sorry, I forgot about that. That's why those didn't add up. But how far they spawn away from each other is this new variable which we actually had hard coded in and we fixed it. Now let's go back to the main camera and let's change that to something like 12. And let's see if that looks a little bit better. Offset is currently 15. Let's see if we spawn in the first one over there and the second one. Okay. 12 is a little high. Let's set it to something like ten. See if that works. Ten looks quite promising. I think that could be good. Yeah. All right. I'm going to actually make it 11 just because I do want to change a few more things about this. The second thing I actually want to do, stop this. I want to change this to 11. Second thing, I don't like the fact that the clouds are spawning right at the bottom of the map, so let me change this minimum Y to minus four. I'm actually going to make the maximum Y something like two. It's a little bit easier to move the clouds up and down. Then I obviously need to change my players jump height to something more like ten, or maybe even 12, so that they're able to jump properly over to the new clouds. Let's see, with all these tweaks, we've now got a slightly different feeling game. The player can jump a lot higher. Maybe 12 is a bit high, but I can fix that obviously. Let's make it maybe ten and go back and see how it looks. Now with the jump height of ten, I'd say that looks a lot better. The gravity scale might be a little lower. Storks floating towards the ground, but this actually looks like a pretty decent figure for my game. I can make that jump, just maybe I have to change that a little bit as well. I might make the jump height slightly higher, but then the gravity scale as well. But it looks like all of these are actually possible with this new variable that I have decided that's actually pretty good. And we can see now we've made a slightly more good looking game. Everything's a little bit cleaner and it all looks a lot nicer. The one thing I'm going to change before I end this video, I know it's been quite a long one, is I'm going to make all the sprites ever so slightly smaller. I'm going to make one, make them quite a bit smaller game. Let's maybe said to 12. Yeah, I'd say 12 is quite good, like I said. Because now I've decided to make my sprites a little bit smaller. I'm going to have to obviously tweak all of my colliders and maybe the spawn frequency of the cloud so that they're still the same distance apart. But because of the way we've coded our scripts, this is actually quite easy to do. And I do recommend you keep adapting your game as you develop it. It's a very normal aspect of game development to change your game as you're making it. And this might seem annoying to constantly be making changes to your game and having to go and fix things. But trust me, it's a lot better than the alternative of having a game, which you're not particularly happy with because you didn't want to change anything. So make sure you're constantly adapting your game so that it reflects exactly what you want. I want my game to have a little bit smaller sprites. I'm going to have to adjust all of my tiles, my prefabs as well as the colliders on my enemy. Maybe on pretty much all my sprites actually on my player as well. And then I'm just going to have to maybe tweak the map generation script how frequently they've sport, because I want them to be the same kind of distance apart. So I'm going to have to make that a slightly smaller value as well. But once I've done all of that, it shouldn't take too long and I'll have a game, which I'm probably going to be a lot more happy with because it reflects kind of what I have in mind. Cool. And then the last thing is to just test. We might have to change these variables one more time before we end the video, but let me see. Because I kind of wanted to be jumping from cloud to cloud. Oh, I forgot to adjust the box glider of the player. Let's do that quickly. And the actual cloud itself, I think should be fine, but let me just make sure it should be good for the player. Let's see the clouds. Just adjust those as well. Should be fine. I'm going to copy this component, so I have to do the same thing over here and paste its values. It's like copy paste should be good. I'm going to do the same thing with all of the prefabs just to make sure I don't have to redo those. Let me go ahead and paste component values for all of these. Now I know it seems like we've done a bunch of stuff and then changed it, and then done again and changed it. It's actually not a bad thing. It means that you're following specific game that you've got in mind. And the fact that you're tweaking things and changing it means it's a little bit more like an actual organism rather than this static thing. And that is what a game should be as you're developing it. But anyway, let's see if that is actually pre suited with what I want. I've got high jumps, I've got from cloud to cloud. This is actually looking a lot better, in my opinion. I think that's actually quite good. This is actually great. We've got pretty much everything I try to save the scene in play mode, which you're not allowed to do. We've got pretty much everything I actually wanted at this point in the game. You've got clouds you can jump to, you've got obstacles in them. This is actually pretty cool. Obviously it doesn't look great because the player is not animated and spike balls. Now the spikes are moving or anything. We're going to get started animation in the next video. But hopefully if you followed along, you've got a slightly better looking game. Even though we just added sprites and we didn't actually change much else you can see, obviously we had to tweak a lot of the parts of our game because we added the sprites in, you can add sprites from the get go. But I think a lot of developers prefer to build it with templates first and then just adjust things as they go because it makes it easier. You don't have to do all the art before you start. But this is actually all we want to get done today. And I think it's safe to say our game looks a lot better now than it did at the start of the video. We're going to see in the next video, after we've added in animation, how the game really starts actually coming to life. And we're going to make a few more tweaks with the player to make him face the other way when he's turning left and right. Which will improve how the game looks a lot. But for now I think it looks a lot better than when we started. And hopefully you've been able to follow along and add in either these or your own sprites to the game. Thanks. 8. Lesson 7 - Animating our characters: Here and welcome back to Unity. In the last episode, we added all of our sprites into our games. We've got a minor for our player. We've got a whole bunch of clouds for the platforms. And we've got spiky balls and spikes in the clouds for the things we have to dodge the obstacles. Obviously, we had to spend quite a lot of time last episode tweaking things and moving them around so they're all in the correct position. I had to do it a little bit as well afterward just to make sure they're all actually exactly where they should be. But that's going to be subjective to you. You obviously know where the right position is for your game and for your project as well. Even though even if you're following along with me, it's not going to look exactly like mine. You're going to have them in the exact same position. So as long as it all looks good and it's all in the right position for your game, then that's great we can get moving on to animation. Because if we play the game right now, we can see even though all the sprites and everything looks good, it looks all right now as a freeze frame. But the minute we start moving around, the fact that the player isn't moving at all and kind of just sliding along and he's pretty lifeless. Actually, it makes the game look a little bit kind of cheap or rushed, and we obviously don't want our game to look cheap or rushed, but we want to look a little bit more like an actual game that you would see on Steam or in arcade, or wherever. So to do that, we're going to actually have to add in animation to our game. And the way we're going to animate, I'm going to show you, it's a decently complicated process if you get quite into it. Because obviously there are entire jobs built around animation for games in those massive games that you see like Treble Studios. It's very different from what we're going to be doing today, but in Unity, even though it's quite a complicated process, it actually provides quite an easy way to do it. And I'm going to be walking you through it and you're going to find that you're probably going to get it quite quickly. Before I get ahead of myself too much, Let's just introduce what we're going to be doing. We're going to be animating just the player for now. Obviously, as we get on further in the game, there might be other things we have to animate. And we might animate new things as we add them. But for now, let's just get started animating the player because that is the most important part. To start, let's go into assets and create a new folder called Animation. This is where we're going to store all of our animation files. Now just like how sprites are files, our code is files. Even our scenes and our prefabs are actually files as well. Animations that we create are going to be files too. And it's important for some terminology here. An animation or an animation clip is like a looping video of a specific thing. Like a running animation. Or a jumping animation. That's going to be a looping video, you can call it, but it's a looping changing of sprites. So it's going to have a moving a certain way. That is going to be what one of the animations is called. Then the way we're going to animate in Unity is we're going to store those animation files because they're saved as files inside this folder. Then we're going to create a new object called the controller is going to tell Unity which one to use at what point, and that's where we put in our logic. But before I get ahead of myself too much, let's just get started with the actual animations. Now, in terms of the actual sprites we're going to be using, I've obviously made a few more sprites for the animations. We're going to be doing what is called sprite based animation, where you have a whole bunch of different sprites. Like you have a running sprite where maybe this leg is lifted up and then one down, and then one to the side, and then one down again. And I've obviously made those sprites already. They will of course be linked by this video. Basically, all our animation is going to do is tell Unity which of those sprites to switch to at what time. It's actually quite easy. There's another type of animation where you basically take the entire object you've created here and you make all of these little parts of the body sub object. The one arm would be an object, the one leg would be an object. Basically tell Unity, okay, rotate this at this time, then move it back at this time. And that's quite a bit more complicated than what we're going to be doing today. It is obviously a much better way to animate for more complicated things. Like if you're not creating a Pixelart game, for instance. That is pretty much how you're going to have to animate actually. Because you can't create a different sprite for every single frame that you want it to be. But for Pilar, just like they used to in the olden days, we're going to use sprite based animation. And it actually looks a lot better for pilot in my opinion. You can never really get it exactly like you want it without using this for Pix L, That's what we're going to be doing. Now, obviously, once you've downloaded all of those sprite files, I'm going to port the same ones. These are going to be the sprites we need for our running animation. And they're sprites minus two through six. Now I've actually just put them in the wrong place. Let me cut those and put them in sprites. Because they are sprites, there are animations. But obviously when you do import it right into the sprite folder and we need to make the two change we did last time, set this to 12 and set this to point. No filter. We can see now they are exactly the same as all my other sprites. If I go here to minor, we can see there's absolutely no difference between these two except the name. If I go to my player, I can actually drag them in as sprites. I'll say, okay, I want the player to be a running sprite. And we can see now he's just stuck there. But we always don't want our player to always be in that running sprite. We want it to change from one sprite to another. And to do that we're going to need a new component called an animator, as we've searched up already, but we have to add this animator. This animator basically allows unity to say, okay, this is something which has an animation controller, or this is something which has animations. It's going to be swapping between. I explain all the terminology as we get to it, but this component over here is basically just a reference to the fact that we are animating it. The reference to the fact that it has a controller. Now to add a controller, which is the key thing we need here, let's go window animation, and then animation again. And that's going to open up the second window over here. Window animation. Animation. Or you can click control six and you open up this animation window and it's going to say, to begin animated player, create an animation clip which is like running or jumping. That's the actual clip we were talking about. This keeps track of what object we've currently select. If we select main camera, it says. Creates an animator and an animation clip. Obviously it only said create an animation clip because we've already got an animator for player. But I think if you click create here, it's just going to create that animator object for you automatically. It's just good to kind of create yourself so you can be aware that it's a part of the process. Anyway, to create an animation clip, we just click the spot over here. We want to go into assets animation, because that's where I'm going to be storing my clips and I'm going to call it player run. Now I've created what is called a clip, and we can see a lot of this has now actually been filled in. We've now got what is called a controller. If we close this and go back into our animation, we've got two files. We've got this player run, which is my new clip. But I've also got this new object over here which is called an animator controller rather. This is the heart of the animator. This is going to be what is telling it which animation to do, at what point. If we double click on this, we can actually see this new window open up over here. And this is my controller, this is my player animator. This over here is my animation clip. To give a brief summary step back a little bit, this is a component we just added. This basically just says, okay, this object is something which has a controller. This controller is what I'm looking at over here. This is saying, okay, which animation do I want to be in, at what point? And this animation is this clip over here, which is the specific things. I'm going to have a running one, I'm going to have a jumping one, I'm going to have an idle one. And then my controller is going to say, okay, be in this one when I'm doing this, Be in this one when I'm doing this, be in this one. When I'm doing this, you can think of the player run. Or the animations as like looping videos, running, jumping, falling, et cetera. You can think of this player kind of like the thing that's telling Unity, okay, which video to play, at what time? And then this animator controller basically just says to the object, okay, I've got this player controller attached. Use it kind of thing. So this is a lot less important. But it's based just saying, okay, this is something which has a controller and you have to use the controller. Obviously it's important. If I disabled it wouldn't work. But this controller is actually a file inside my game. So I need to create a link to this controller and this specific object, which is what Unity has done for me here. But anyway, don't get too worried about what every single one of these things mean, just follow along as I'm doing, obviously We've just created an animator and then we've got window animation animation. And we've created a new file for my player called player run. And that created a controller for us automatically. So let's get started animating player runs. Let's zoom into my player. And I'm going to click this Record button, which basically says I am currently recording things. My animation. In the first part of my animation, I want to be on this sprite over here. I'm going to choose minus two over here. This is the very first sprite I want. The reason I have this record button down is that it basically says whatever changes they're making editor now are actually part of the animation. If I move it over here that it's going to change my position as part of the animation. But I actually don't want that. I just want it to be the sprite. I'm going to change my sprite to minus two, Move a quarter of a second. Obviously 60 is a second in this view over here. And if I click Play, I can't see anything yet because I haven't done anything. But I'll show you later. I'm going to change to minus three. I want that actually to be at 15. Then at 30 I want to choose minus four. Then at 45 I want to choose minus five. I've got the four sprites which you're going to make up my running animation. You can see coming together there. I actually want to add in one more thing over here. It doesn't really matter what I add in, but as long as I have something here, I'm going to make it back to minus two. As long as I have something there, the unity knows that this animation is exactly 1 second long. This frame actually only lasts for one frame, and then it goes back to there. I don't have this here, even though it's not technically part of the running animation. Unity is going to skip over this or rather run it for one frame and then go right back to that one. I don't want that, let me make sure I have something here. If I click play, we can actually see that kind of coming together and it looks okay. It looks pretty cool. In my opinion, I'm not the greatest animator, but this is going to be our running animation for our game. We can always tweak the speed and things like that inside this actual controller. If we're over here, click on the animation, We can change the playback speed when we're in the game, but for now it's like a basic animation. I'd say it looks pretty good for running. Let's go ahead and create two more animations. Player Idol. This is actually going to be an incredibly simple thing. We're just going to make sure that Unity knows we want to be on this sprite, so it's not really an animation, it's just like a sprite setting. But we're going to be using it to tell Unity. Okay, make sure you're in that sprite. So our animation is just one single sprite. We're going to do the exact same thing for jump, Play a jump, and we're going to choose sprite minus six, which is our jumping animation. See over here now it's out jumping. If either we're going to be like that, if we're running, we're going to be doing that. So now we have all of our animations completed and fixed. Now what's left to do is build the logic to tell it which one to do at what point. And then the last we need to do is just adding a little bit of code which is going to be crucial for defining that logic. To create that logic, we're going to go to these parameters here. And these are like conditions we want to set. So we want to have a condition to know whether we're running or not, obviously, because we need to know whether to play the running animations. Let's call it is running. Let's create another billion we're going to call it is grounded because we want to know whether we're jumping or not or rather whether we're on the ground over here. If we actually look at these, these are two billions. They can either be true or false. What I'm going to do now is I'm going to create logic which basically defines these three animations as playing at certain times based on which of these is true and which are false. So to do that, I'm going to go over here to any state. This is actually very, very useful in terms of the animator. And it's basically saying, okay, no matter what animation is playing, because these are what are called state nodes. And they're like saying, okay, as long as I'm in the player run animation, I'm in this player run state and I can be in player idle state. I can be in player jump state. We're creating a very basic state machine. But this any state node basically allows us to say, okay, no matter what state I'm in, go from there to this. And the way we're going to go from there to this, or rather between these different animations, is using transitions. If I go ahead and I read over here, I can go make transition, okay? Transition from that to that. And inside this transition is where I set my logic. Let's say I want to, as long as I'm not running, is running is false. I want to go to idle. As long as I am not grounded, I want to go from idle to jump. And as long as I am grounded I want to go from jump to run. This might look good like we've got a pretty basic rudimentary kind of structure here. But this is actually very flawed because we don't have any way, first of all, to go from run to jump. As long as we're running and we're jumping, we can only ever go to idle. If we're running and we don't stop running and we jump, we're not going to move, we're going to stay in my running animation. On top of that, if I'm jumping and I actually am still, when I land, I'm still going to go back to running and then I'm going to transition to idle because I have this thing over here. But it's a very kind of flawed machine because I don't even have states defining for everything. If I want to make this actually complete, I'd have to make a transition there, a transition over there, as well as a transition over there. And then it would be slightly more complete. But all of this is quite a complicated way of doing it. And I'm not going to be using this. I want to delete these. Instead I'm going to use this any state mode, which is going to make this process a lot easier. First of all, I'm going to go from any state, I'm going to say make transition just like it did last time, right click and click. Make transition to go to idle. And I say, as long as I am not running, as long as I am grounded, I want to be idle because that means I'm standing still on the ground over here. I want to say as long as I am grounded, in other words I'm not in the air and I am running, then I want to be running over here. I want to say any time I'm not grounded, I want to be jumping. Because my jump animation is actually more like a fall in animation. You can see over here if we go into the game and we click animation, you select the player, we look at our jumping animation, we play it, it actually is like a falling animation. It obviously works for jumping or falling, but it's going to look quite good when we use it because it's going to play whenever we jump or even if we just fall off something, which is exactly what we want. Now this is actually pretty much almost everything we need to do for our logic machine. But there's a few more tweaks. First of all, let's set this as the default we right click go set as layer default state. It doesn't really make that much of a difference, but it just feels like the idle animation should be a default one rather than the running one. It automatically set to running because it's the first one we made. But it doesn't really make a difference, it's completely fine. Second thing we want to do is we want to set this transition duration fall of them to zero. Because I find that with Pixi Lad it looks a lot better if it's zero. Sometimes you can tweak with a little bit because you might want to be 0.1 0.2 I prefer to set to zero, but I might actually change that as well. I'll see, just for now, I'm going to set to zero and make sure all my conditions are right. As long as I'm not running and I am grounded, I want to be idle up. As long as I'm grounded and running, I going to be running. Yep. And anytime I'm not grounded I want to be jumping. Perfect. So this is actually pretty much everything we need to actually do. If I click play right now you can see I have my player and he's going to stay in the jumping animation because I was not grounded. And he's actually, if we just look at it over here, we've currently got a player and he's jumping. But based on what I choose, let's say I set grounded true. Now I'm actually going to be idle. You can see I'm staying there. If I set running true, I should be in my running state, which I believe I am. Looks like that's all working. Everything should be working fine over here. In fact, it looks like our transitions are pretty much good. But we obviously don't want to have to be clicking this based on what we want when we're actually playing the game. We want to be able to say, okay, when I'm doing this specific thing, set these, do a thing when I'm running, set this to running, rather than have me come and click there. And we're going to use code to do that. Let's go over here to my code scripts. And I'm going to open up player move. We're going to use the exact same script we used to denote when I'm moving to basically show whether I am going to be playing certain animations. And I'm going to first of all, create a reference to that animator, call it Anum. Even though I'm referring to the animator, I'm conferring to the animator controller. It says interface to control the Mec Anum animation system. But yeah, I'm basically referring to the controller. I'm going to be referring to these parameters we've just defined. I'm going to go over here, back to my script and I'm going to say underneath these collision things because this is when we basically change, this is ground variable. You can see I've atually already got a variable here that tells me whether they're on the ground. I actually need to make sure it's basically aligned with my animator parameter. So you access the animators parameter, we're going anambool, open parentheses and you say the name of the bool, My b is grounded. Then I'm going to set it to my grounded variable. I'm actually only going to do this over here, and over here, I could do this every frame if I wanted. The reason I'm only doing it here is because these are actually the only two points in my entire script where I changed the ground variable. And there's nowhere else where it could possibly change. So this is the only time I need to update my animator and say, okay, if I've collided with something it's true. And then make sure my animator sets it to true. If I leave something it's false. And make sure my animator knows that I have to set to false. And this is actually just the basis for what we need for our is grounded system. If we were to play the game now it should actually work pretty much fine. Whenever we land we're going to have is grounded, this set to true and then it's going to play the right animation whether it's idle or jump. But we still don't have any way of controlling my is running animation. So we're going to add one line of code over here. And that section, to be very simple, we just going to anim. Set bool, just like last time. We want to set the is running bulow where we're going to determine whether we're running or not is using this x float. Now remember this x float is changed based on what keys they're pressing down. As long as they're pressing down a or D, or the back or forward arrows, it's going to basically say, okay, set x to a number that allows us to say, as long as x is a number we're running. But as long as x is not a number, we're not running. And we don't have to worry about whether we're running in mid air or not. Because if we remember, our animation controller doesn't actually factor in whether we're running or not in mid air. All we need for running is the fact that we're grounded and running. And as long as we're not grounded, even if we're running, it's still going to play the right animation. We should need to worry about setting this is running variable based on whether we're moving or not. We're going to do that. We're going to type is running, set it to x is not equal to zero. That's going to say when x is equal to zero, this is going to be false because this says x is not equal to zero. As long as x is not zero, this is going to be true. It's going to say, okay, set running to this statement. This statement is actually returning a Boolean true or false. When x is zero, it returns false. And when x is not zero, it returns true. We're saying okay, as long as x is not zero. In other words, as long as we're moving set is running to true. When x is zero, set is running to false. This is actually going to be all the code we need to perfectly set up our animator. If we go back into Unity, go into our scene, make sure that we have a reference to that animator we just created over here, drag it in, just like that. We hit play. We should actually see all of the animations come to life perfectly well. We can see we fall, we land, and we have our running animation. Oh, it doesn't look like it's working. It looks like it's just the first frame which is quite interesting. So we have something we need to sort out there, but for now, this actually does seem like everything else is working fine. We should have to sort out why is our running animation only playing the first frame? And it's this over here can transition to self. It's actually something I forgot to mention, this can transition just self state. You have to actually remember to not use if you're using this any state controller. I forgot about that. But what's going to happen is with these two animations, we didn't notice it because these animations aren't actually really animations. They're kind of just single kind of frames we were continually transitioning to them. But we didn't notice a difference because they're just one frame. But we could see with player run, we were only transitioning to the beginning of the animation. If we uncheck that, it's going to not allow us to continually basically be refreshing this. We're saying only move to it once and don't keep moving to it. You can stay in it as long as you're not moving to the other one. As long as we unchecked this, it's actually going to fix everything and it's going to make it so that it doesn't continually keep refreshing its transition to this thing. It just transitions once. And then when it trines to transition to other places, it does. But it doesn't need to continue going towards itself, which is good. And if minute we've made that fix, that should actually be everything that we need to do to have a working animation system. Now we can see we run like normal, just like we wanted. Obviously we don't turn around yet, which is the last thing I'm going to add before we close up this video. But we do run and jump, just like we wanted. First I'm going to do is I'm just going to make this a little bit faster because I think one is a little slow. And hopefully that should be everything we need to make our game look a little more lifelike. Yeah, we can see it now. It looks quite good now actually we've got everything running, and we've got a jump. And everything is actually looking a lot better than it was before. But there is one thing we need to change, and that is the fact that the player is always facing forward. And that's actually a very easy change. All we're going to do is we're going to go over here, down to this fixed update statement. And we're going to say if RB, velocity x is less than zero. In other words, if we're moving backwards, then set the players transform his rotation. We're going to write Quaternion Euler. Just a fancy way of saying angles. Don't worry too much about it. We're going to set it to our x zero, our Y to 180, and our X00. If we go into our game, we can actually see what that's going to do. Open up my platform game here, go to player. We can see we have them set zero. If I set a y to 180, it's going to flip my player around, which is exactly what I want. And then as long as I have set to zero, it's not. And that's going to update all of our animations just like that for us. Because we're actually rotating the object itself, which is actually quite useful. We're just going to add one more line of code over here that says else if R vlocity x is greater than zero, in other words, if we're moving forward, then we want to be having a normal rotation. This is obviously, like I said, going to take care of all the animation actually for us, it should be everything done automatically. If I hit play, we can see now this new code is going to allow us to face backwards, which is actually going to look a lot better in our game, Hopefully now you can see everything coming to life, and our game looks a lot better than it did previously. And we have all of my animations and everything working pretty seamlessly. That's pretty cool. Hopefully you've been able to follow along and you've got a pretty similar looking game and it looks a lot better than it did originally. And you kind of get in a feel for how we're going to be making the rest of this game. But as long as for now, if you've got everything working just like I do, that's awesome. And I hope that you've been able to follow along what we've been doing, and you've been able to animate your own player in the same way that I have. In the next video, we're going to be adding in enemies and a whole bunch of new interesting enemies. And we're going to be making a bunch of more tires with those enemies just to make our game a little more varied. And then from then on we'll get started with all the last things you have to do, which is obviously hit detection, and audio and sound, everything else after that. As well as some final touches just to make it look better. And also a game loop of course. But right now we've got the very building blocks of our game kind of completed. And we've added in sprites to make it look a lot better. So that's everything for this video. And in the next video, like I said, we're going to add some more interesting enemies. But for now, if you've got everything working like I do, that's great. And we're going to get started with some new development next video. Thanks. 9. Lesson 8 - Adding more interesting enemies: Hey there, and welcome back to Unity. Now in this episode, we're going to be adding a few more interesting enemies to our game. Because right now we've just got spikes and spiky balls. Even though these are somewhat varied in all the tires we have, they're not the most interesting enemy types and they're actually just obstacles. We're going to add two new enemy types, and I've obviously built spikes for these already. One of them is going to be a patrolling enemy, and the other one is going to be like a timed enemies. Every now and again it's dangerous, but then it turns off and then it's not dangerous. And to start, we're first going to import all the sprites ball needs. I'm going to right click Import New Acid. And these are actually all of the new sprites which we need for our enemy. So we've got four robot sprites, two sprites for this shocking enemy, and then one extra sprite for our spike ball. The reason we got this extra spike ball sprite is because we're actually going to be animating our spike ball a little bit. And that's actually what I'm going to start with first, and to make sure all of these are set to the right settings obviously. And actually do this just by selecting every single sprite. It's going to overwrite those, but it's fine as long as they're all the same. 12 point filter and hit Apply and everything we now know is the same. And that's also how you can actually check that you've got all your sprites the same. As long as these are filled in, you're good. We're going to go into prefabs. We're going to create a couple of new prefabs. I'm going to open this one up and I'm actually just going to copy these across so I keep the tags the same. This one is going to be our robot, and this one is going to be like a battery. Before I do that, I'm actually going to first fix my spike ball by animate and I'm going to go window animation, animation. All of that extra stuff we did in terms of phases and states and all that stuff, that is animation. And it's quite simple, but we can have even simpler animation if we just have one animation. If we want a continual kind of animation that is playing the entire time, which is what I want with a spike ball, all I have to do is go create, go into my assets, go animation, and call it spike ball. Then every half a second I'm going to want to change to the second spike ball sprite, which is the one I have over there. Copy this across and go there. You can see that in action here. This is going to be our spikeball animation. It just makes the game look a little more interesting. That's actually all we need to do, because if we open up our animated, we can go into animation. We can open up our spike ball. See, I've got one state. Sure. But I don't need any parameters or transit or anything because this is the only state I ever want to be in if I go back, as long as I'm a spike ball obviously, which that object is. As long as I go back into my game and I can see the minute I get a spike ball, see that animation is actually running perfectly and it makes the game look a lot nicer. I might have to move these a little bit because they're still looking quite close. Everything is still rather big, but it is actually looking pretty good for now. And the spit balls are animating just like we need them to. That's the time of animation we're going to have for the rest of our enemies as well. Let's go back over here to our robot and let's get started, first of all by animating this one. I'm going to delete the circle collider and I'm going to change this to robot sprite. Then exactly the same thing is before. It's going to make an animator for me, I'm going to go to Assets animation. Call it robot animation. Then I'm, I think I have four different robot sprites. And they're just going to be the wheel turning. And the eyes slightly changing color. There we are. We can see that in action over here, the wheel is obviously going to turn. And the eyes, and if you can see it, they slightly change color and go back. That's going to be all the animation we need for our robot. Now we've got our robot sorted out. Let's do the exact same thing with our last one, which is going to be our battery. And this one is going to be a little more complicated. Let's first start by going. I've caught shocker in the files, I'm not sure why, But this is going to be the start for our battery. We've got this battery over here. The way this animation is going to work, it's going to be slightly differently. I'm do, the reason I say it for last is quite specific. We're still only going to have one animation, but it's going to be an animation with a little bit of logic to it in a different way that we had before. Let's name it battery dot. We basically not want to want to animate it. Let's say a good while, let's say 3 seconds. We don't want anything to happen for the first 3 seconds, we just want to stay on this sprite we're currently set to shocker one, we're staying over there. Then the minute 3 seconds are up four. The next 2 seconds we want to be having the shock animation, which I've got sprites over here. Just make sure that is as 3 seconds. For the next 2 seconds we're going to be doing that, and then we're going to return back to our normal thing. We don't actually need to put it afterward because it's going to do it for us. But then for the next half a second over here, minute 3 seconds are up, which we can use these little things to skip to the next thing. One frame later, we want to change to this new animation of here, which is shock er, two. And we can see if there we start changing the animation. And there from 1 second or rather one frame after 3 seconds all way up to 20 frames after. We're going to want to go in that one, we're going to want to change it and then go back to this one at 40 and then change it again. We can see that's going to look like this. I think we should have it one more time. Switch up. I think that is the frame we want. That's the wrong, sorry, I've copied the same one twice. Let me put it there. Then over here we are going to want to end the animation. So it's going to be still for 3 seconds and then it's going to have that active, and then it's going to stop again. And then 3 seconds later it's going to move. And that is going to be the gist of our sprite over here. And that's actually also going to be how the enemy works. And we have to add a little bit of logic to this animation, because we've finally got this working fine. But we need to have something that tells the game when it's in this state and when it's not. We're going to use over here what's called events. So let's make sure we go exactly one frame after 3 seconds. Let's add an event over here. And also right at the end of our animation over here. Or rather actually I'm going to put it at the start of the new one, just so we have it over here right at the start of our frame to have one more event over here. And I'm going to explain how these work, but basically there are ways of accessing the code attached to this battery to say, okay, yeah, this is now has to be active and this is what you have to do at this point. I'm going to get started with adding my colliders. Now explain how we're going to get this battery one to work, but it's actually going to be quite simple. Let's start by adding the collider to this. Actually, let's add a box collider. These are all of the parts which we want to be the minute the shocking thing is active. You don't want to be able to touch any of this, this entire bit over here, as well as this over here, which is going to be the actual battery itself. Perfect. I'm just going to make sure I set both of these two triggers. Obviously, if this was an enemy on its own like this, it would be completely impossible to dodge because there's no way you cannot touch any of this thing. But that's where the events are going to come in handy. We're only going to have these box gliders active for that period because they're both triggers, so we're obviously going to be walk through it anyway. But for that period they're going to be active and then when that period is over, they're not going to be active again. Actually, let's code that quickly. Let's create a new script. We'll call it battery script. We're going to load it in. And we'll also have to create a script for another enemy as well, the robot, which I'll get to in a minute. But let's first make this battery script. And we're just actually going to have two simple voids. Going to have a public void, call it battery off. I'm going to create another one underneath and call it battery on. We're going to create a reference to our two box gliders. Public box, slide two D, we're going to have box one and call it box two. All these boys are going to say is when battery is box one enabled equals false, box two enabled equals false, Then we're going to do the exact same thing with battery on except set them to true. What is going to say is that the minute I call this void over here, battery on enable both of these box gliders. But the minute I call this void over here battery disable them. We're actually going to start with them disabled as well. This is going to say that the minute this object spawns in, it doesn't have anything active. But the minute that shocking animation is playing, we want this to be active and this to be active. And because it's an enemy tag, then we're going to code in logically says, okay, you have to take damage. But then when that's over, we want this to be off again. We're going to go back into our animation over here. We're going back to our event over here. And we just actually get to choose a function to call here, but it has to be a function of a script that's attached. So we're going to drag on our battery script. Let's move right to the bottom and put it over there. And we can see over here we have our battery script right there. We've got battery script here, which is written down there, and we've got our actual script. I found that sometimes when you're adding in things with names like battery script or something script, it might give you an error that says, oh, we can't find the script. Make sure the class exists. And it might be because you've named your script or reserved word. For instance, I want to try to call my one script camera. And I kept get an error and I don't know what it is. It's because you can't actually use the word camera. The way you solve this is just actually by changing this word over here and this word over here. And that's how you rename your script. If I was worried about this one, because I have had some errors in past, I thought I'd just mentioned it. I'll call it battery. Then it's going to give me an error here because now it doesn't actually know what battery is or it actually doesn't, but it should. Then I'm going to over here to battery as well, and I'm going to rename it to battery. And make sure you rename both of those. Make sure you rename the name of the file and the actual name of the class inside the file. And then you should have problem solved. If you encounter any issues the entire time we're developing, that is how you fix them. But anyway, that should be everything we need. And let's add our box gliders right there. Let's go back to our animation, which we've got open over here. And let's go to our event and choose this event battery methods. And then we choose battery off for the beginning. Only over here do we choose battery on, battery on there, and battery off over there. That should actually work perfectly fine. We've now created a prefab with our script over here. As long as this animation is playing, the minute it reaches this point here, it's going to call this void and it's going to activate these colliders. And you won't see it here, but you'll see it when we're actually playing the game. Then you can see it actually should work perfectly fine, which is really, really cool. Let's go back out and let's go back to our prefabs. We've still got one more prefab here, which are robot prefab, which we haven't finished yet. Let's add a box collider two D. Let's resize it just a little bit over here. Keep in mind this is not actually going to be where he can fall, et cetera. It's going to be where the hit box is. Let's make it a little bit smaller than. Usual, just like we have the whole time but not too small because we do want it to be able to hit, especially with this little red things. Let's actually move this out a bit and down. That should be good for now. Let's make sure we set it to trigger. Just make sure all of the other ones are also set to triggers just in case we've forgotten anything they are in fact, which is cool, we've got our animators on these two and we've just got our animator over here. We've got our three animated enemies, as well as our Spike, which is the only one which we haven't animated. That is actually pretty much everything we need to do except for adding in some logic for our robot patrolling, because this is a patrolling enemy. Before we do that, let's create a few more tires quickly just to show against these new enemies. I'm not going to make too many, but you can obviously add quite a few more. And just for the sake of time, I'll add a little more in between this and the next video. But Right. I'm just going to make three just to showcase these new enemies. And they're going to be very boring. They're all going to have either just one robot or robot, and the shocker thing. So this one over here, I'm actually just going to use a single one of these batteries. Put it over there. Now obviously my battery enemy is quite hard to see. If I were to put it like I normally would like something like that, then you won't really be able to see the wire, which makes it quite hard. So I'm going to put this in front, I'm going to say order in layer to six or rather seven. And I'm going to make it so that it is in front of everything else on the cloud. Does look a little bit weird, but we can tweak that as we go. Just makes it so it's a little easier to see. Let's move it up. I think that should be fine. Obviously, like I said, we can tweak it as we go along, but for now, that should be pretty good as an enemy in the game. That's our floor tile 11, I believe. Let's make sure we go to floor tile 12. And let's just add in a single robot right over there. Should have been moving down a bit because we can obviously see without that, let's make sure he's always riding on the ground. Yeah, that should be good. Then last of all, we are going to have let's say one robot and a spike. Just to show you can obviously use multiple per thing. That should be everything we need to do. Now, the last thing we need to actually do is just code in our logic for the robot patrolling to and from. We're going to use quite an easy thing here. We're just going to have a variable on here which sets the limits. Patrol two there and patrol two there. And then we're just going to have some code that says, okay, as long as I'm moving, as long as I'm lean this way, as long as less than this, move that way. And I'll show you exactly how to write the code. But before we do that, we do actually need to add a rigid body, our robot, so he can move. But we want to make sure we set it to a kinematic rigid body so that he doesn't fall through the cloud. Because he doesn't have an actual collider attached to him, he just moves along according to code. Then let's go to Scripts and let's quickly write our very simple robot script. Call it robot move. Let's go ahead and double click that to open it. Then all we need to do, like I said, is we need to set, first of all, let's make a float called speed to how fast he goes. Then we're going to have two floats. We'll call it min x and max x, which are basically going to be the two positions where he can go from. Then we're just going to have inside our fixed, update it over here. We're going to code in our rigid body. We're going to go public, Richard, body two, D, call it R B. Then we're going to say RB, velocity equals vector three, vector two. We're going to want to set our velocity over here to some x values. Let's create one more variable, call it X. Then we want our RV Y velocity two B zero always because we're not going to be moving up and down with a robot. Then the last thing we need to do is over here in this update frame. We need to say if transform position x is less than our minimum x value. In other words, if we passed our minimum x value, then we need to do two things. First of all, we need to make sure we're facing the right way and we're going to rotate the robot just like we did the player trans stop rotation is quaternion.u0. 0.0 Then the second thing we're going to do is we're going to set our x to our positive value for speed. Then otherwise we're going to write an L s course and we're going to say if transform dot position x is greater than our maximum x. In other words, if we're not smaller than our minimum x, but we're not greater than our maximum x because we don't want to be too big either. Too far, right? In other words, we're going to copy this exact thing over here and change this value there to 180 and this to negative speed. What this code is going to do is going to say, every single frame check, I'm not below this minimum limit. If I am, then turn me around. If I'm greater than this maximum limit, in other words, if I'm not greater than the minimum limit, that's great. But this implies that I'm bigger than the minimum limits. I could be moving to the right. If I'm bigger than the certain other limit, then turn me the other way. This actually should be all the code we need to write our robot logic. Let's go to the robot. Let's add in the script over here. Robot move. Let's make sure we assign the rigid body over there. I want to pick a starting speed of something like five, then this minimum X, Y, I'm actually going to choose based on the tile for this first tile. I think I want my minimum x to be -2.9 Let's go here. It's at minimum x -2.9 I'm assuming my maximum x is going to be pretty close to 2.9. Yeah, I'm going to make it 2.8 Actually here my maximum x is 2.8 You can see over here, this is in bold because these are values I'm editing for this specific example of the template, the specific instance. But that's actually fine, that's actually what you want. This x variable is obviously going to be dependent on speeds. We'll see that change as we go. But last thing I can do to see these robots in action, I'm actually going to quickly change this map tower script. I'm going to make it only have two elements in it so I can test them. I'm first going to put in my one with the robot over here. Tow, I'm actually going to put both of the Rob and now, because that's the only way I've tested, Just to make sure that it does work, I'm going to hit play. See if I run into any errors. There might be something which might happen where they are, that's what I thought might happen. So the roads actually currently flying off the clouds and it's because we referred to a specific position over here when we wrote the code. And we put it in this prefab, we see we've got these values over here that say, okay, as long as you're not less than this and less than this, but what we're forgetting is that this is actually a child object of this bigger parent object. So that's choosing a point in space, not a point reference to this cloud. To fix that, all we need to do, we need to change this to transform local position dot x. Change this to transform local position do x. Then I actually noticed that I've swapped these around. So this should be 180, this should be zero because this is where we're moving forward, and this is where we're moving backward. Then the last thing that we want to do is we want to go over here and we actually want to add in our start void back. We want to start by setting x equal to speed because this x variable denotes whether we're moving and it only gets assigned if we exceed one of the boundaries. We want to set it at the beginning as well. All of those changes we've just made have made sense. Don't worry too much about the local positions. But basically it wasn't working because we were referring to global positions when we actually wanted local positions. And we've just added this tweak. So we start by moving as well, and we've made sure we turn the right way, because that was actually an issue we had. Um, so let's go ahead and go back into our game, and let's see if this works now. Hopefully it should all be good. You can see over here we have a robot. Annie's walking towards the end. Annie actually turns around, which is perfect. If I can catch up, I don't know if I'm going to be able to make it. So let's just start again. We should be able to see our game now with our animations And everything can run along and we can run into these robots, and obviously we're going to have to try and dodge them. But that is kind of cool. It's a great new enemy to have in our games. And they're kind of patrolling alongside. Obviously, they're not going to look like this because they're all kind of in sync now, which makes it a lot harder. But as we add in like different tiles and things and set different positions, that's all going to be good. Let's go ahead and open this new one. And it's actually going to be slightly different. I'm going to want this one to stop about there, which is -1.17 I'm going to set the maximum y to 2.72 0.8. Other than that, that should all be good. The last thing we need to test is this battery tile over here. So let's go back into our game and let's make sure that we add in the battery tile, 11 A and see if it works perfectly fine. We're going to test is we're actually just going to pause the game and look at the tags to make sure that everything is working as needed. So we've currently got a robot to start, a robot after that. Hopefully, we're going to have a battery soon. It looks like we have a battery, so currently the shock mechanic does look like it's working. But we're going to have to do a more thorough test. We're going to pause it now because now is when the colliders should be active. We're going to go over here to this floor tire. We're going to go to the battery. And let's go to see. Okay, both colliders are active. Which is exactly what we want because now the enemy thing is it. Let's pause it and wait till it's stopped. And we can see both are deactivated. So that is actually everything that we need now completed for our new enemies. Like I said, obviously you can make a whole bunch of new tires. I've just made a few now, but I will make a few more for the next video so that we have a slightly more varied game. You can make as many as you want, especially with these new enemies we've added now should have a whole bunch of extra things you can make. And we might run into one or two bugs with these new enemies as we move in. Because they are brand new additions to our games, we're going to see how we have to tweak it alongside. But hopefully it is in a pretty stable state the moment. I haven't found anything that makes it not work. And so hopefully everything is good at the moment and your game is running just as well as minus. We're going to get started in the later videos on adding in hit detection as well as an actual health system. So we have a game where you can actually lose and restart. And then we're actually just going to have to add in all of the additional things like post processing and fixing up the sky and all of those things to make the game look a little better than it does now. But hopefully you've got the basis for a pretty cool platform, a game written in Unity. So far, we've currently got 12 or 13 different tiles. And I'm going to add a few more now, like I said, And this should allow you to make a pretty varied and cool platform again. So a good job on making it through this video was quite a hard one, especially quite a few new concepts. And we've got a patrolling enemy and an enemy which is only active at certain times. But hopefully you were able to follow along. And I'll see you in the next video where we're going to get started with adding in Hit Detection. Thanks. 10. Lesson 9 - Introducing hit detection: Hey there, and welcome back to Unity. Now, in the last episode, we added a whole bunch of new enemies, as well as animating a few enemies we already had added to the game. And then basically made a whole bunch of a few new tiles to test these out and make sure they all work perfectly. I told you that if you want to add more tiles, you can. And like I said, I did make a few more tiles in between the last video and this one. I've now got full tile, 13 A, and then haven't actually named them yet, but 141-516-1718 19.20 So the first thing we need to do is actually fix our spawning strip so it's spawns from everything again. Because the last thing we changed was we were just testing the new ones, but now we want to be all of them again. And like I said, I've got 20 now. So let's quickly add all of those to this list. Once we've added everything to this map tiles list, we should be able to hit play and see our entire game with all of the new tiles added in. I've made a few, like one with two robots, one with two of these battery things. Obviously, you'd have to jump there. This would be very hard. We might have to tweak the length of this animation because it is quite regular. Or I might have to change the actual block itself. But currently this is looking pretty good so far. In my opinion, we've got this 12 robots as well. Yeah, they're obviously quite hard to dodge, but this is going to be the basis for the blocks we're going to have in my game. What I need to now actually add is a hit detection system. Because currently this is all well and good. But you can't die. You can't even lose the game. In fact, even if you jump off the entire map, you can't lose. What I'm going to get started with in this video is getting hit detection working. And then the next video, we're going to get started with a health system and we're going to make a health system and an ability to actually die. But this episode, all we're going to get done is the hit detection, which is actually quite simple. So all we need to do is we need to make a new script. I'm going to call it Player Health. Let's open it up. Actually, all we're going to add here is a void to make sure that we know when we're taking damage. We're going to get started with all the other health stuff later on. Right now, all we need is a public void, take damage. We're going to do what's called a parameter, which is like a value you can pass into a void. Now like I said, a void is a method, It's a block of code that you can call. This parameter is a value you can put into this block. When you call it, I'm going to say into damage. Then every time I call this block of code, I can choose how much damage I want to do. In other words, I can choose what I want this value to be. I'm going to get rid of that. I'm just going to write print player. Then I'm going to put my variable damage damage full stop. Add a space over there and I'm going to make sure this says two string, so it's the correct type of variable. Now this is using a few things we haven't actually covered. Like I said, parameters and two string methods, but it's not that important. Basically, like I said, a method is something which you can call at a certain time and the code inside it will run all this integer over here is saying when I call this, I also get to choose in a value. So I can now choose different things, can do different amounts of damage. Like maybe a robot can do two damage, but a spike only does one. Then all I do when I call this is I say I print out to the screen. I say this player took and then I give the amount of damage I took. So I wrote damage. And because it's an integer, I have to change it to a string. If I want to use it in a print statement, then I say damage. Now actually all I need to do is need to create a new void. I'm going to call it a void on trigger two D and it's actually very similar to this on collision void we've used before except it's just four colliders which have set to trigger which is all the ones we've used on our enemies. We're going to say if collision game object dot compare tag, just like we did before. This time if it's a tag type enemy, then what we want to do is we want to now access how much damage we need to do. To do that, we're going to need to write another script. Let's go over here and let's create a new script, call it enemy info. Inside the script, we're going to create a bunch of variables. This is like a stats column for the enemy. So we're going to create public T, then we're going to call it player damages. We're going to add the script to every single one of our enemies. And then every time we collide with an enemy, we're going to go and look at that script with the particular enemy you've collided with. And that's where we're going to get our damage variable from. This might seem a little confusing, but just bear with me. If we have collided with something that is an enemy, we'll say collision dot game object dot get component. In other words, get a component attached to what we just collided with. Collision is the collider we just collided with. If the game object that that's attached to, in other words our enemy is an enemy, then go and get another script attached to this enemy, which is called enemy info. Parentheses after that. After this and then we go player damage. We can now access the variable explicitly. This is basically, this statement isn't actually doing anything, but it's saying get player damage from whatever we've collided with. Now all we need to do is we need to put this as our parameter damage. So we're going to write to take damage open block and we're going to put this code inside here. Like I said, even though this is only technically two lines of code, it might seem a little confusing, but it's actually not that bad. All we're doing is we've defined this code up here that says, okay, when I call this I want to play took this much damage. Obviously, we're going to flesh this out later on. But right now all it does is it says, okay, a player took damage, but how much damage we take is determined by this void over here on trigger enter two D. We're saying every time we enter a trigger collider, if that collider is attached to an enemy, then call this take damage void. In other words, run this code and set the amount of damage I want to take to the amount of damage that is stored in this enemy info column, which we are going to assign when we add this to every single one of our enemies. Let's go back out. Go into our prefabs. Over here is where all my enemies are stored. And I'm going to add in enemy info to every single one of these. Right enemy info. Let's have the battery do to damage. I think the robot should only do one damage. Spike I think should also only do one damage. And then I'm going to have the spike ball do one damage as well. It's just the battery actually. Or maybe let's have a spike ball do two damage. Just make things a little more interesting. Now, every single one of these things has this script attached which is going to store how much damage it does. Last thing we're going to do is we want to make sure they're all set to tag enemy. It looks like they are. Now all we need to do is need to go back to our player. Let's add in this new script we just here called Player Health. Put it underneath the player movement. We don't actually need to assign anything here because we don't have any variables over here. We've just got a void that says take damage. We've got an event. Whenever we collide with the collider, take that much damage. Now, what should happen if we go ahead and clear that console and click Play? We can see nothing is printed now, but as we run along, let's go and interact with that Spipal and see what happens. And we can see there, we have player took two damage. I do it again, it runs again Here, player took one damage. Here player took one damage. And let's try and do that. Player took two damage, two damage, because both player took two damage, player took one damage, one damage, one damage. Perfect. This is actually working really, really well. Now, the last thing I do want to add just so the next video isn't too long, is an invincibility time. This is actually also quite easy to make because this is the script we're going to be using for all our player health. I'm just going to start fleshing it out now, but basically all we need to do is we need to, let's get our void update back. So every single frame. And then let's have a float up here. Call it Max invincibility time. Then we're going to have another float which is going to be called invincibility time. All we're going to do is inside this void update, we're going to say if invincibility time is greater than zero, then we're going to decrease the invincibility time by the amount of time that has passed since the last frame, time delta time. What's going to do is it's going to say every single frame if this value is not zero, in other words, if it's five minus however much time has passed since the last frame. So in other words, basically count down. Well, this is actually just going to work as a time, but we're going to say if it's greater than five, then count down back to zero. And then all we're going to do is underneath this take damage void. We're going to add in another if statement condition up top here. We're going to say if we have collided with enemy and our invincibility time is less than or equal to zero. In other words, if we're not currently in a time when we're invincible. Let's add some more parentheses around there then, and only then take damage. The last thing I'm actually going to do is I'm just going to remove this word Enter and change it to a word stay. The reason why we can do this now is that this trigger event over here is actually called once per frame for every collided to you that is touching. In other words, if I were to collide with something and I were to stay there, I will continually damage every single frame. But because we've added in this invincibility time, we can now write the code like this and set a time that we cannot take damage. Because the reason I didn't do this originally was because we would have seen 100,000 messages every time we touch something. Because it's going to run every frame. But because now we're only taking damage every time that we can. In other words, only every set interval which we're going to set over here, we can't take damage all the time. I can now write this code like this. And this is actually a lot better because it means that if we stay on a spikes or something like that, we're going to continually take damage as long as we're on the spikes. And that's actually what we want. Before we actually go back to my game, there's one last thing I need to do. I need to make sure that I always set my invincibility time over here equal to my maximum invincibility time as long as I've just taken damage. The minute I take damage, reset that kind of time. Basically, that is pretty much all the code we should need to write to have a basic system for taking damage. Let's go back into Unity. Let's set my maximum, my time to 1.5 seconds. Let's see this in action. If I go ahead and hit play, can run along. And we're going to actually watch these two variables. So we can see if it's working. Watch this one. Every one a 2 seconds, I'm going to take damage. You can see over there, player took one damage, play took one damage, play took one damage provided. I'm staying on these colliders, I actually continually take damage every single time I'm on one, which is exactly what I want. Now there's one more change I want to make as long as I'm busy doing things in my game. And it is going to be adding in a hit detection animation. We're actually going to go ahead to my player and we could animate it so that whenever they take damage, there is a certain effect that plays, et cetera, et cetera. And we write that in the animation window over here. That's going to make things quite complicated because we already got all of these animations over here and adding in a hurt animation. Then we need hurt while idle, hurt while running, et cetera. Instead, we're going to use a simple effect, which is going to be a red block that goes like that. When I take damage and then changes back. I'm going to flash red momentarily. And then I'm going to stop. The way we're actually going to do that is entirely using codes. We're going to go over here in my player health script, we're going to write what is called a co routine. So we're going to write numerator, take damage. This is going to allow us to program in like timers actually wait for this amount of seconds. I'm going to write the following. I'm going to say at the top here, I'm going to have a public reference to my Sprite Renderer, call it Sprite. I'm going to say inside my take damage void. Don't get confused about this. This is basically, just think about it like a void. But I can use commands that allow me to wait for a certain amount of seconds. That's not exactly what it is, but that's just what we're going to be using it for. Just think of it like a void with an extra ability, obviously. Don't use this instead of voids. Only use it in the way that I'm using it now, but don't worry about it too much. You're going to say yield return weight for seconds. Then we're going to enter a certain amount of seconds. I'm going to use invariable to decide that's what I'm going to say. Public float color change time. This color change time variable is what we are going to use to determine how long we should wait for before changing colors. First I'm going to go sprite color equals color white. Then I'm going to go ahead and wait for however long my color change time is. Then I'm going to change from, I'm actually going to put red at the top of here. I originally go red, wait for amount of seconds, then I go white. And that is actually pretty much everything that we're going to need to do. We're going to set the sprite color to red the minute we want to, and then when we're done taking damage, we're going to set it back to white. And obviously this is every single time we take damage, we're going to call this co routine. Now two things. First of all, this is actually named the same as voids. I'm going to call it take damage effect instead it's slightly better name. And second of all we're going to have to invoke this every time I'm going to underneath this and write start co routine again. Don't worry about this thing too much. It's really not that important and I don't actually want to spend too much time going into it. But basically just think about it like a void which allows us to wait for a certain amount of time. Then we're going to call this specific void over here which allows us to take damage. And this means every time we take damage, we're going to change to red. And then for however long we want to be red, we're going to keep it. And then we're going to go back to white. This is pretty much everything that we need to do to make ourselves have a hit indicator. Let's go ahead back to Unity. Go right back to play. Let's set the color change time to 0.2 seconds. Now if everything works as it should, we should be able to run along just like we normally have been. Just like normal when we take damage, we should change to red. We haven't assigned sprite, let's make sure we do that. Drag this down over here. Assign the sprite variable to the sprite thing. Let's try that again, running along, if we take damage, we flash red, which is exactly what we want. And that's actually pretty good in my opinion. You can clearly see when you take damage and you can see, obviously, if you stay inside it, you take continual damage. That's pretty much good. The only last thing is how long we're invincible four and we're going to write another co routine for that as well. Let's just go down here and take enumerator call it invincibility time. We're going to say while in other words, do this until this thing is no longer true. Invincibility time is greater than zero. In other words, while we're currently invincible. Let's go ahead and flash in and out of the screen. We're going to do the same thing we do with color. Let's go sprite color equals new color. We're going to set this new color to be pretty much exactly how we have white, except with a slightly less evident alpha. It's going to be somewhat transparent. Set this to 111, which is the maximum value, and then we'll set alpha. Let's use a variable for this as well. Public float transparency. Let's go ahead and copy that in and put it over there. This is actually pretty much exactly what we want. While this invisibility time is holding true, going to change to in, we're going to change to slightly transparent. And then we're going to write a new yield return to wait for seconds. I'm going to use another variable over here. I'm going to call this one invincibility delay. In other words, how long we want the time between flashes to be. Let's write invincibility delay over there. And then let's go ahead and set our thing back over here, normal 1111. I'm actually going to repeat this process a fair few times. In other words, we're going to change the transparent color, change back to normal color, and then wait for another amount of seconds. After doing that, we become transparent. We wait, we become normal, we wait. And then if we're still invincible, we become transparent again. Wait, this is going to repeat on and on, until this is no longer true and then it's going to stop. It's important to note that because we've, the way we've written this code, it's never going to stop when you're transparent. Because it's only going to check if invincibility time is greater than zero at the end of this code, it's not going to be able to stop in the middle of the code. It's going to run at once and then say, okay, do I need to do it again? You have to worry about being stuck half transparent. Now, before we go back to Unity, we have to actually do one thing. We have to make sure we actually call this cotine. Otherwise it's never going to take its effect and we won't be able to see it. Let's go to the top here. Remember to write in Start Corotine Invincibility Time, just like this. This is actually going to allow us to call the corotine. Make sure to put a semicolon at the end. Now if we go back into Unity, we can make sure to edit these values in our player. Let's make this invincibility delay 0.2 seconds. Let's make my transparency 0.5 has to be a value 0-1 Keep that in mind. Now this should actually be everything that we need to have a properly working invincibility effect. Let's see if it works. If I load up my game, obviously we had the red damage effect working. But let's test if this one does as well. You can see it actually works perfectly fine. It's just we seem to have lost our damage effect. And the reason for that is because we're actually overriding our color. Let's go back here and just quickly make a small fix. We're not going to want to change it. What we're happening is we're changing it to red. But this code over here is making it white again. Instead of saying, okay, change it to white, I'm going to say change it to whatever it was before. Sprite dot color. Sprite color. Sprite dot cool dog. And for red, green, and blue C, that should work a lot better. Now, we're no longer going to be changing any of the actual aspects of the color except its alpha channel, which is exactly what we want. Let's go back here and see if this works a little better. And I think it should make sure to watch that intervinsibility time variable. If we take damage, we can see it actually works perfectly fine. As long as we're counting down at spirit time, we flash and the minute we stop, stop, which gives us a pretty good indication of our game and the damage system working, which is great. That's pretty much everything we need to get done in this video. Obviously, now we can see we can actually take damage and all we need to get started with now is our health system, um, which should help us make this game a lot more fun and actually, well, more like a game than it is right now. So I hope your game is working just as well as minus at the moment. Obviously, need to tweak this and make sure that everything is working just like minus before you continue onto the next video where we're going to get started with our health system. Thanks. 11. Lesson 10 - Adding player health: Hey there, and welcome back to Unity. Now in the last episode, we added in Hit Detection, which allowed our player to show when he has taken damage and also how long he's invincible for before he can take damage. Again, we can see all of that in action over here with the taking damage and the flashing while you can see where you've just stopped taking damage and you're now invincible. And then when it wears off as well, that's all well and good, but we still don't have a system that actually shows, okay, how much health do I have and how long until I actually die? And it's game over because the player doesn't have infinite health. It wouldn't be a very interesting game if you could never die. What we need to add in this episode is a health system to show, okay, the player has this much health left, and when the player reaches this health then he dies. And to do that, we're actually just going to use the exact same script we've been using all along, this player health script. So let's go into scripts and double click player health to open it up. In visual studio, we should be able to see everything that we coded last time. Right over here. Perfect. Now all we're going to do is add in a public int, call it Max health. This is something which you don't really have to add to a variable because what this is going to say is how much health we should have at a maximum. In other words, like how much health do I want when I'm full health? And you might think, oh, that's a good thing to have as a variable. But because I've already made the sprites and everything, I know how much max health I'm going to have. It's going to be six, but you can add this in if you want to. It's just good program practice too regardless. But we're going to leave it in there and also add in a new public into current health which is going to be called, he actually call it current health. Cool. Then all we're going to do is we're going to go over here to my take damage void over here. And I'm going to say current health minus equals. In other words, current health is equal to current health minus. And then we're going to say damage, in other words, decrease current health by the amount of damage. I'm actually going to remove this print statement over here which says how much damage I took because that was just for testing. Then all I need to do over here is I need to have another void underneath this which I'm going to call check dead. I'm going to call this void the minute I take damage, before I even do any of the effects or invincibility time or anything like that. I'm going to say if my health current health is less than or equal to zero, then I'm dead. I need to invoke another void. I'm going to write underneath here, death. Let's go ahead and add that in there. Damage void where I decrease my current health by the amount of damage I took. I have my check dead void where I say, okay, if my current health is less equal zero, call this. And I have my death void over here which says okay, now once I'm dead, what I want to do, so I'm going to actually get started, program in this. And then I'm going to add in a final thing to the top here that says, okay, set my current health to the max health at the beginning. Actually, I'll just do that now. Let's go ahead and say void start current health is equal to max health. In other words, everything is all well and good. We're starting again and we've got my current health to the maximum health. Then underneath in my death void, we're going to say okay, what do I want to happen when I die? Well the first thing I want is In't want the player to be able to move anymore. The way I'm going to do that is I'm actually going to access the game object that this is currently attached to, which is the player. I'm going to go Game object and then I'm going to find another script on this. In other words, the Get movement script. I'm going to go Player do get component Player movement. I'm going to say enabled equals force. In other words, I'm going to stop that script from being currently enabled. I'm going to say okay, it's gone. What this is going to do is, is basically going to allow me to disable the movement as long as Glary is dead. I also don't want my rigid body to have any gravity affect me. I don't want to fall anymore. I'm going to say do get component rigid body two D gravity scale. I'm going to set that equal to zero. In other words I don't want to fall, I'm staying in the middle of the air and I currently can't move. Then there's a few more things I want to do. I want to actually disable the animator which is on my component, on my object right now. Now I can't change animation. Then last of all, I want to change my sprite to a specific death sprite, which I'm going to put over here. I'm going to say public sprite, call it dead. I'm going to say get component Sprite Renderer Sprite equals and then dead. These four lines of code over here are basically going to say, okay, the minute I die, disable my movement scripts. Now I can't move anymore because it's game over, right? I also don't want to be able to fall, so set my gravity go zero. I'm just suspend in the middle of the air, not moving right. I'm actually going to add one more thing before I do that is I'm going to say game object, get component rigid body two D velocity is equal to vector 20. In other words, stop me midair because the way this works currently, if I were to die and then I did all of this stuff, I would continue to move along the screen, which I don't want. So first I want to make it so I can't move. I want to stop myself midair and disable my gravity. So I'm standing in the middle of the screen. And rather just there in the middle of the screen, I want to disable my animator. So I don't longer have any of the things, okay, if I'm grounded or not, whether I'm falling, I'm just disabling this outright. And then I'm going to set my component of Sprite Renderer, the thing that tells me what sprites currently display to this special sprite over here, which I'm going to add as well. This is pretty much all the code we should need to create a health system. I'm going to say at the start of the game, set my health to the max health. And then every time I take damage minus it from it, and the minute I am dead, then call this Spoid over here, which basically makes it pretty clear that I've died. Let's open up Unity, Go into Player. Let's see which of these we have to add. Let's set my maximum health to six and we need to add in this dead sprites. I'm going to go into sprites, right click and right import a new asset and it's minus seven. It should be linked underneath this video just like all the other ones were. I'm going to update these while I'm actually added. I'm also going to import these heart sprites which we're going to use for our health system in a little bit. Let's go ahead and make those also 12 and Point No Filter and Perfect. We're going to check it like we did last time, make sure those both fill in. Perfect. Let's scroll down here and let's make sure we have my minus sprites set to this minus seven. Let's see if this all works just like we intended. We've got our last sprite added, everything else. Let's if we go to my player, we can see right now I have current health of six and max health of six. Now my health is at four because I just took damage, Health is now at three. And if I take two damage from this, health will be at one. Now what should happen if I run into the sprite? I should stop Miller and change into a tombstone, which is perfect. I still have the deaf effect which I need to fix. But you can see, obviously we haven't disabled all, the scripts are not fully dead, but this tombstone does seem to be working. I have a tombstone over here, and that's all pretty cool. There's a few more tweaks I want to make to this before I start adding in my heart system. The first one, I think the tombstone should be slightly higher up in the air than whenever you died. Let's start by saying over here where all of the rest of this code is. Let's also go ahead and say transform position equals new vector three. Transform position x, transformed opposition dot y transferred opposition. Obviously, this statement doesn't do anything yet. I'm just saying transformed opposition equals transformed opposition. But then we're going to go to the top here and we're going to add in y offset for when we die. Let's copy that down there, and then let's add that over here. And I think something like two or three will make this look a lot better. Then after we've done that, the last thing we want to do is add a new variable, call it is dead. And this is going to allow us to keep track of when we are actually alive and not over here at the start of the game. We want to set is dead equal to false, because we're not over here when we die. We want to set is dead equal to true. The reason we're going to do this is we're going to actually take care of all of those things we were doing previously where it was still taking damage and invisibility time was still taking effect all of that stuff. And the place we're going to put this in is we're actually going to move this script over here. Let's go ahead and look at my check debt script over here and say if current health is less than equal to zero death. And then underneath this, before we call the other stuff, we'll say if not is dead, in other words if I'm still alive, then you can do all this other stuff. Then you can set the start time, you can invoke the damage things. But if we've just died, we don't really want that to happen. We could actually also put this as an L statement. You could say else, in other words, if my current health is not there, which I'm going to do just to make procincts slightly better, but it really doesn't make a difference. In fact, this dead variable is not actually 100% needed over here because we could just write else and then not use it at all. But I think it's still a good thing to have just to keep track of whether the player is alive or not. Let's go back to player and let's my Y offset something like two and see if all of these changes are going to work. Let's go click play and see if I continually take damage. That's two, that's four, that's five. On the sixth one, we can see over there, two might be a little high, let's set it to maybe one. But it actually did work pretty much perfectly. We've got everything working fine. If we die in front of something like a spike, we'll go in front of the spike, but we won't continue to take damage or have damage shown. Let's let the robot kill us. Almost. That's four. Therefore, if we die here, there we go. We should see over there, we've got our death effect over there. And we also want the camera to stop. But we're going to add that right now. Let's go over here to my camera. Let's go to find where it is over here. Camera speed under the camera move script, underneath this dead void over here. I'm going to say game object dot find. In other words, get in the scene, my main camera, find it. Then we say get component, find on that my camera move script going to set my speed, camera speed equal to zero. This is actually everything that we need. Now the minute I die, I should have my camera speed set to zero and everything should work perfectly fine. Let's go back into my game. I'm going to want to adjust my y offset actually to something like 0.5 Think one was still a little high. Let's see if this all works just like we anticipated running along. The sake of testing, I actually just going to set my health to one, Have to continue to test this out. Let's set current health. You go to one and see if we run into that spike. We can see we do in fact die and the camera stops, which is great. It's exactly what we want. That is pretty much everything that we need to do in terms of showing that we're dying. But we still need a way for the player to see how much health they have remaining. To get started with that, we need to get started with our user interface. Let's right click and go Create. I' going to want to create an image. You can see it makes this massive canvas and this is actually much bigger than that. There's our game down there. This might look a little bit confusing it. This is a screen space overlay. I much prefer to use the screen space camera mode. And you can drag your camera right in there and then you can see your UI in front of your game. There's not a massive amount of difference, it's just a thing of preference. But I generally do prefer to use the screen space, camera mode. I think there are some distinct advantages, but I've never really researched them extensively because I've never had a problem with the camera mode. Let's go ahead and use camera inside this image over here. Let's first rename our canvas to UI. This canvas is like a building block for all of the UI components. And this event system allows us to have buttons working. All of these are going to be created automatically when you create a new image, just like the animator was created when you created, or rather the controller was created when you created an animation. Leave them all. Don't delete them. Leave the event system where it is, and leave the UI canvas as it is. Obviously without the canvas, none of these images are actually going to work and they're not going to show up. If we move it out of the canvas, we can see it no longer gets rendered on our screen. Let's just leave that all as it is. Change this to heart, then let's go ahead and drag in our heart. For the source image, we're going to click Set Native Size so we can see exactly how it works. It seems to only be rendering a specific portion of my heart sprite. I think the reason for that, if we look at these arrows over here, we can see that there are three things that pop up as opposed to everything else only has one. For some reason, Unity automatically thinks it's being clever and tries to separate these into three different sprites when I actually only want them to be one. I'm going to select all of these, Make sure I set the sprite mode to single head apply. Then if I go back over here and try and drag in my sprite, everything works much better. I didn't actually realize that would be an issue, but just make sure you do do that, especially if using my sprites. Now I think a lot of them are actually set to multiple by default. But it's not even an issue. Like for instance, this minor is multiple, but it's only one. In fact, I think every single one of my other sprites are actually one, even though they're all set to multiple. So it doesn't really make too much difference. You can leave those there, just make sure this one is set to single, because otherwise Unity, we'll try and split it up into different sprites for you. That's obviously not what want for my game. Now let's go ahead back to my heart over here. We now need a click set native size to make sure they are fitting with everything else. Then we need, now obviously scale these down so they're the same proportion. Let's go ahead and drag that until the pixels are the same size. You can see there they are not yet. Let's drag it a little bit more. We're actually almost there. Let's just go slightly larger until it fits in. It doesn't have to be exact, but the closer you get it, the better your game is going to look like. It doesn't really make a difference at this point. I think that's pretty much exact. That should be good. It's going to look completely fine like this. But let's move that to the top of the screen. Now we can see those hearts are going to be there while I'm playing the game, which is perfect. That's exactly, actually what I want. Now we need to do is we need to link these hearts to the code over here which basically sets my health. The way I'm going to do that is I'm going to go ahead into my health script over here, which is under script, I'm going to click Player Health. I remember right at the beginning of the course, I mentioned these three things at the top. If you need to use different things in Unity like you have to add in a line. And that's what we're going to do here. We're going to say using Unity engine user interface. That's just so we can talk about things like images. We're going to go over here underneath all of this, going to create a public sprite array, in other words, a list of sprites, and we'll call it hearts. We want this hearts to be from zero all the way up to five. Because there's going to be six different types of heart spend on how much health you have, neath this. We're going to create a reference to my image and this wouldn't show up, but we haven't typed UIs To make sure you have it at the top there, we're going to call it heart icon. Now over here we have our hearts icon, and we have our hearts. Let me change that to heart's icon. These two things are going to be able to show the player how much health they have remaining. Let's go over here to my void over here where I take damage. And I want to make sure that I set my damage or rather my new kind sprite over here to whatever the heart's icon is. I'm actually going to put it over here with all of my other things because I don't want to really bother with updating them. If I'm dead, I can just set it to the default one, which is the lowest one, obviously. And I'm actually going to do that as well. But before I get too ahead of myself, let me just focus on changing it over here. I'm going to say obviously on a scale 0-6 I want to set my hearts icon sprite equals hearts open brackets. And then we're going to have the remaining health, current health minus one, because obviously in a ray starts at zero, If we're on one health, you want the first image. This is actually pretty much all the actual code we need. The last thing I want to do is underneath my depoid over here, I'm going to write the bottom, make sure I set my thing to zero. Actually, it just occurred to me that we will also need to show different hearts if we have absolutely zero health. So let's actually set that to current health because that is the correct one. For one health we want to be on. The second thing, current health over here and zero over there. Let's go back into unity Now, the last thing we need to do is we need to, first of all, create a reference to that Heart Cycon, which we're just going to drag in right there. And second of all, we actually need seven elements in this array because there's six different hearts, Health you can have, and then one with zero. Let's go back to sprites and drag in all of these. We've got hearts, seven heart, six hearts, five hearts, 432.1 That should actually be pretty much everything we need to do to get this system to work. If we go ahead and hit play, we can see we have three hearts. And then depending on how much damage we take, those hearts should go down. So we start, we take one. You can see over there we show it has half a heart, then another half. And then the more damage we take, obviously, the more lower health we get until we go all the way to zero hearts and then we turn into this little tombstone. That's everything we need to do to build our health system. Our game is actually working pretty much perfectly now. We can even die and we can lose. Obviously, there's a few final touches we still have to make. We have to add in a game loop. We have to improve the visuals and obviously all the audio things, but this is actually turning out to be a decent amount of our game already done for us. It might not look like it's done yet, but we've actually got a lot of the basic mechanics out the way. And what's kind of left after this is a lot more kind of additions and like funner stuff. We've built most of the building blocks. I hope you've been following along and that you've been able to get a hard system working just like I have, as well as the health and all the damage indicators. In the next episode, we're going to start adding in currency. We're going to add in diamonds, and every single cloud is going to have a pretty low chance of spawning in a diamond. We're going to get started in the next episode, but hopefully you've been able following so far and that your game is in shaping up. Thanks. 12. Lesson 11 - Introducing gems: Hey, welcome back to Unity. Now we've already added in our players health system. And pretty much everything else so far that a platform game would need. Except for a scoring mechanic or like coins or gems or something you can pick up to show that you're progressing through the game. That's what we're going to add in this episode and we're going to be using diamonds. Now's start, let's import our diamond sprite because I've already made that. Import diamond dong, which is obviously linked in this folder of the video. Then go set this pictures unit to whateverthing else is and set the filter mode to point. Now we have a diamond which we can obviously collect in our game, which is pretty cool. Now this diamond, just like the hearts have added an outline around it just to make it a little clearer that there are hearts and scoring mechanic, I might remove this later on in the game, but for now I think it does a pretty good job of just outlining that it is different from everything else. I'm actually also going to want to set this to be a higher order and layer than the rest of the game, so that it doesn't get hidden amongst the clouds. But I'll get to all of that in a minute. Let me just first start by dragging it into the screen like I just did. And that's basically a shorthand way of creating an object with a sprite renderer. With this particular sprite, I'm going to waste no time in making this into a prefab called diamond. Then I'm going to delete this one I have over here and open up my diamond prefab. Now this diamond prefab we're actually going to use, obviously, to code in a lot of the logic we want for my diamond. And before I get started with actually writing code, we have to basically decide how the system is going to work. The system that I've settled on doing is having every single cloud have a certain probability, we can make it one in 31 in four, whatever we want of spawning a diamond when the player lands on the cloud. And when you jump at a cloud, there's a chance that the cloud is going to shoot up a diamond out of around a position and you're going to have to catch that diamond before it lands. I think I'll start with it just shooting directly up so you can see it. But the diamonds are not going to be part of the cloud. They're going to jump up and then fall through. So you have to be able to grab it by either in the mid air or as it's falling back down. But it's not going to stay there for long, It's going to jump up and then fall back down. So we obviously don't want to have a normal box glider, We want to have a trigger. So let's get started. I'm going to add a circle glider. Actually, not a box glider just because I could add a polygon as well. But in this instance, having like a circle isn't the worst thing in the world because you want to be a little more forgiving with power ups than you do with hit boxes. Because no one's going to be annoyed that they collected something. Obviously, don't make it ridiculous. And I'm going to set the offset to zero, right? Let me keep that at 0.1 0.05 Let's make it three. There we go. Like I said, no one's going to be annoyed that they collected something like this, but you obviously don't want to make it ridiculous, just make it about that size. And I'd say that's probably good. Then make sure to set it as a trigger and we're going to have to create a new tag. We're going to call it diamond. Now before we get, let's obviously assign that there before I forget, before we get started with adding in all of the logic for how the scoring and keeping track of diamonds and having like diamonds per run, all of that thing is going to work. Let's first just get done with the logic of actually spawning the diamonds when we want them to spawn, and then we can add all the other stuff later. To do that, we're going to have to go into my Clouds and let's go back into my prefabs over here. And I'm going to want to add to every single one of these prefabs a script that says, okay, you have in this many chances of spawning in a diamond. Let's get started with that script over here. I'm going to create a C sharp script. I'm going to call it diamond spawn. I'm going to double click to open that up in visual studio. Where I want the script to work is. I want to say that whenever a player jumps on me, that's when the one in three chance is calculated of whether I want to spawn in a diamond. But that's a little confusing because it's quite hard to differentiate. Okay. Is this the first time the players jumped to me? Because I obvious don't want the player to be able to jump as many times he wants and eventually spawn in a diamond. I want it to be decided before he's even jumped on it, whether it's going to spawn a diamond or not. I'm going to use a bit of a strange method of coding here, but it's actually one of the best ways, in my opinion, to do this. I'm going to get started under my original void. I'm going to say let an integer x equal a random range. Keep in mind, we decided range was inclusive in the minimum, but not at the maximum. I think if you use floats it's inclusive, but with integers it isn't. And we're going to set over here public integer and we're going to have the chance, this is the one in how many chances? I'm going to go from one to my chance variable plus one. In other words, if I do 1.2 it'll go 1-3 which is either going to give me a one or two. Then I'm going to say if x is equal to chance, because that's probably the best way of coding it, Obviously, if we are equal to the maximum number, for instance, if this is three, it's going to pick 1-3 And if it's equal to three, we know that there's always that many chances of getting it. Pretty much anything actually works. You could say chance minus one or even 001, but this is a good way of knowing that it will be in the range. Let's add round brackets around that if statement. And then inside this code over here, this is where we're going to say what happens if we're at this chance. Now actually this is not what we want, we want to say if we're not in this chance, if I get anything other than the number which I want to get, I'm going to want to destroy or delete this actual script attached to my code. I'm going to say gameobject, Get component. In other words, find on my game object something called diamond spawn which is this current script. And then delete it. This might seem a little confusing, but basically what I'm doing is I'm going, okay, start the game. Pick a random number from one to let's say three. And if you've got anything other than three, then destroy the script. What this is going to do is going to mean, on average, only one in every three of these actual scripts is going to remain on my game object. When I have the game, that is how many clouds are going to spawns? There's one in three chance of this script surviving. And then I'm going to write some code undneath this that says, okay, if I interact with the player, then spawn in the diamond. And then also actually going to delete the script as well because they don't want to spawn in more diamonds after I've spawned one. Before I get to ahead of myself, let's create some more variables, public gameobject, diamond, and I'm actually going to create a reference to a rigid body as well. Then I'm going to go ahead into my update void. I delete it, I'm going to replace it with a void on collision enter two D. I'm going to say if collision game object dot compare tag is a player. In other words if I've just collided with the player. And this code is obviously only going to be checked if I've hit that 13 chance. If I collide with the player I want to spawn my thing. I'm going to say game object D is instantiate diamond as game object. I'm going to set the position of my new game object deed of transformed opposition equal to my current position on the cloud which is going to be transform position. I might actually not launch this to spawn exactly in the same position as the clouds. I'm going to create a new vector. Three, go transformed opposition, do x, transformed opposition y plus an offset which I'm going to choose over now. And then transformed opsitionI'm create a new float, call it offset. And that's going to allow me to choose where above the clouds I want to spawn. The last I'm going to do is I'm actually going to set RB, which is my reference to a rigid body equal to D, which is my newly created diamond. Do get component rigid body two D. I'm going to add a rigid body to my diamond and that's how I'm going to make it jump up in the air. I'm going to go Rb, velocity is new vector two, set it to zero and I'm going to set, I'm going to create a new float up here which is going to be my diamond launch speed. So I'm just going to call it launch. This going to denote pretty much how high in the air the diamond is going to fall up. Then I'm going to actually create a separate script on top of my diamond which is going to say if I go live with the player, do this, otherwise I'm going to want to delete myself the minute I reach this level of kind of y position. Because the way it's going to work is every time I land on a cloud, it's going to shoot up a diamond. Then it's going to fall. If the player doesn't hit it, we don't want to be falling forever. That's going to take a lot of kind of calculations and computing power away from the game, even though it's not even happening on screen. So let's go ahead and leave this for now. Basically what we're doing is we're saying as long as we still exist, by the time the player lands on us, then spawn in a diamond. Set its position to slightly above us and shoot it up into the sky. So before we actually chest, if this works, there's a few things we need to do. First, we'll need to make sure that the player is tag player. So let's go ahead and tag him as player, which we hadn't actually done before. The second thing we need to do is we need to go into my prefab. And I need to go and make sure to add the script to every single one of these. Let's go ahead and type in my script poetry we've just done here. Let's set the chance to 1.3 For now, let's go to prefabs and set our diamond as the prefab rigid bodies is going to be assigned when we spawn in. And then let's set the offset to something like 0.5 and the launch to something like five for now. We can obviously tweak that later on, but just make sure it is obviously editing every single one of those prefabs which mine was. And we can obviously change those as need be. But the last thing we need to do right now, this is actually going to work pretty well. We're going to spawn in our diamond. And it's all going to work except for the rigid body because we don't have a rigid body attached to our diamond just yet. Let's fix that by adding in a rigid body two D. That is pretty much actually everything that we need to do. I'm going to freeze the rotation Z, even though it doesn't really make a difference. I'm going to make sure that the collider is a trigger, which is what I wanted. This is actually everything that we need to do when we're creating our script. We've got this script up here which is going to say, okay, spawn in our diamond. It should be that every one in three clouds is going to spawn a diamond. Let's test if this works. Let's hit play and see as we run along. We've got a spawning cloud. Let's see if it kept a script. The script is not on this. I guess that one wasn't the one in three. Let's see if there's one after this. That one also doesn't have it on. That one clearly obviously got destroyed. My God, that's hard. You can see over there, that was the one in three chance we can see the diamond spawned in. Now the problem is we haven't actually destroyed the script, so this is going to happen every single time. But I think it looks pretty cool. It actually works quite well, and we have a diamond spawning in. I want to make a few tweaks. First of all, I want to change that launch speed to something like 6.8 just so we have a bit of a better spawning chance now. It's going to be a little easier to catch that diamond as it goes up. I'm actually going to make it something more like eight, in fact, and just see if that's a little ridiculous, but it might work quite well. Let me just test that obviously. And then obviously in my player as well, I actually want to make his speed a little bit lower and make the jump height a bit higher. I actually might even increase the gravity scale just a little bit. These are just kind of tweaks I'm making. So I'm changing my gravity scale, going to make it 2.5 I'm going to make the jump height 12, and I'm going to make the speed five. And let's see how that game plays because it's feeling a little bit kind of floating at the moment. That is actually a lot better than I was expecting. This is a lot better and a lot more like what I want you see now. It's a lot easier to catch those diamonds. Obviously, they are still spawning infinitely, But this should be good for now. So let's quickly make that tweet that we need to make. The minute we spawn a, a diamond, we obviously want to delete our script because we don't want to spawn in multiple. So let's just copy that over. And then all we need to do after that is actually add a script to the diamond itself that says if I collide with the player, then increase this variable on the player. And I'm going to have a new script over here. I'm going to have two new scripts. One of them is going to be addited to the player, which is going to keep track of how many diamonds the player has. And one of them is going to be added to the diamonds that keeps track when the player collides with the diamond. Let's go ahead and create a C sharp script, call it player diamonds. This is actually not really going to be much of a script, it's just going to be an integer, which going to say public int diamonds. We're actually also going to have a public int high score diamonds. There's going to be the diamond, the current run and there's going to be our high school. We'll get to that later, but these are the only ones we need for now. Then all we're going to do after that is we're going to create a new script as well. Here I'm going to create a shop script and call it diamond on the script. All I'm going to have is a single event void on trigger enter two D, if collision game object compare tag player, then we go collision the thing I collided with on that find a component called player diamonds. Let's go ahead and actually put curly brackets here so we can put this entire thing inside the statement and find a variable on that called diamonds and incremented by one. In other words, if I collide with the player increases diamonds by one. And then we need to actually delete the instance of this prefab. So let's go ahead destroy game object, which is basically going to delete this current diamond. Then the last thing we're going to do is add in a condition if we collide with the bottom of the map, we actually also want to do that exact same thing, destroy myself and not increment it this time. To do that, we're actually going to add in a collider to the bottom of the main camera, because that is where the game play is going to happen. And we're going to add in an edge collider two D, We're going to go and see it over there. This is what's going to be used to basically track of whether we have hit the end of the map or not. I'm going to move the offset of the Y down to about there. We can have a little bit under the screen, doesn't really make a difference. Then let's set the points to negative five, or rather negative ten, maybe even. Actually, we want to be greater than the screen. Let's say negative 12.12 Now this is going to be a trigger collider as well. Then we're just going to have a little line of code inside here that says else if collision game object dot compare tag. If I hit the main camera, then I still want to delete the instance of this prefab. This should actually work pretty well if we collide with the player. We want to delete the game object but also add it to the player's inventory. If we collide with the main camera, we also just want to cease existing. Let's see if this works. I'm first going to try not adding a diamond at all. Before I actually test that, I have to obviously add in my player diamond script, which I forgot to do, and keep track of how many diamonds we have. I actually also forgot to add the diamond script to the diamond. Let's go here and add in the diamond script. And I think that's everything. Because the diamond spawn we've already added. Let's hit play and test exactly if this does work or not. We're going to have to test to see if diamonds spawn or no diamonds have spawned yet. We're going to have to keep up with the camera, obviously, to see if we're going to miss one there. Diamond did spawn. It looks like it says tag main camera is not defined. Oh, we spelt it wrong. That's a very easy fix. Let's just go ahead and remove that space and test it again, because we're currently getting errors that say, okay, I don't know what main camera is, but that's just main camera. One word. Let's try that again. It should work now. Nope, this game is worryingly hard, but I get there in a minute. Obviously, the tweaking of the game generally comes from how hard you make these ofscles that you've created. I'm going to cheat a bit and put my health back up to Max because I'm about to die. Let's set current health to six. It's one of the cool things about developing the game. This is also impossible, which I need to fix as is. There we go. There we have a diamond, and it looks like it did spawn, which is great. Let's set my health back to ten this time. We're going to get some errors because we're not actually meant to have health above ten. But it's fine. It's not going to break the game. I'm going to try to collect a diamond and it looked like it worked perfectly well. I collect a diamond. If we go to my player, we can see I have diamonds as one. Pretty much everything actually worked really, really well. Now all we need to do is adding a counter so we can know how many diamonds we've collected. Let's go into my UI over here at the top, underneath hearts, we're going to want to create a new image. I'm just going to copy this for now and move it slightly down. I'm going to want this image to be a diamond. I'm going to set set native size. I'm going to want to just obviously need to scale it down, just like I did with the other one, to make sure that the pixels are the same size, it's a little bit bigger. See, that looks about good to me. Obviously, like I said, doesn't have to be perfectly exact, but it does have to be quite accurate. If you want a game to look good, then all we need to do, actually, is we need to move this. Instead of having directly under, I'm going to have this on the other side, like so. Now I'm going to have the score on the left of it, which might look a little weird to some people, but you can choose whatever you want to do. I actually might change that later on, but for now I think it'll work quite well. Let's move that down, it's in line, then we're actually going to call this diamond. Then all we need to do is we need to go into my UI and create another object UI, call it a text, and you have to create a text mesh pro. You're going to get this pop up. Just click Import, and it's going to import all of the files it needs for this specific package. You don't really need the examples in extras, so I'm not going to import that. Then I'm going to take my new textbox and I'm going to put it as a child object of this diamond. I'm going to drag it underneath it, just like we did right at the beginning of the game with storage. I'm going to adjust the position X to be something like -100 position Y to be zero. It's in the middle. I'm just going to adjust the rest of this box as I see fit. I think that's probably good. Move it up and down then. I'm just going to make sure I have the right sense here. I want it to be right aligned. I think that the pin enabled, I'm going to keep ph now because I can't actually imagine any instance where you'd use up the entire thing. You'd have to collect a lot of diamonds. But just to be safe, I'm going to move it that way and I'm actually going to set wrapin disabled. It doesn't do that. There we go, much better. It will now extend as far as possible, above across. Then I'm going to want to have to choose how much of this I obviously want to display. Let's test in a default value of 540 that does not look very good. You're going to have to obviously choose a different font and everything else. Let's see, we have a drop shadow font. Doesn't look great. An outline font might look okay. You can't really see it as there aren't an amazing amount of fonts available for you just built into Unity, which is why I've actually included another font which is the same font I'm going to be using, which I found on the Internet. You can find a whole bunch of fonts for free on various sites. Make sure they have the correct license. But if you can find one of those fonts, then you can find a font which should fit your game style pretty well. I'm going to use that one. Let's go ahead into miscellaneous and click Important New Asset. Here it is, Bloopf. We have a font size here. I wouldn't mess with these too much. We can try them out once we've added the font in, but just leave them as they are. Now to use an extra font, we actually can't use this text mesh prose. We're going to have to delete this and create a new one UI. We're just going to want a normal text. I have to go under Legacy and click Text. Let's name this counter. Then I'm going to drag exactly like I did last time. I'm going to set the horizontal overflow to overflow. And I'm going to set it right aligned. Move it this way. I want it to be centered in the middle. I want it to be font bloop, you see there. It looks all right. It's very blurred though. And the way we fix that, we're actually going to size the font size up, going to move the thing as large as it could possibly be. You can make it a maximum of 300. And I find that this is generally what you have to do to get pixel to render right then you just got to drop the scale all the way down. Let's scale that down. Let's click these and scale in proportion all the way down to what we want. I think we need a little bit smaller than that. Actually, let's try a 0.12 That might be fine. Let's try to change the color to what we actually want it to be, which is white. It is center aligned, but it doesn't look like it's in the center. So I'm going to set it to bottom aligned. And let's try 150. That looks okay. I might not be your favorite font, but it's the one I'm going to be using for the purpose of this demonstration. You can obviously find a different font online if you want to, but I think for now it actually works pretty well. Let's make it a little bit darker, so it's not bright white, But that should work as our basic font for keeping track of how many gems we have. Now we obviously just need to write the code that says, okay, display the right number here. And that's all going to be done inside our player diamond script over here. We're going to create a reference to Eyes in Unity. We're going to go public void update text. And inside it, above that, actually we're going to create a reference to our counter. We're going to say counter text equals diamonds, Two string. In other words, set the text variable, which is what we're writing in this little box over here. When we clicked on that, what this little box has inside of it that set that to whatever my current diamonds value is as a string, it's stored as an integer. We have to convert it to text format. Before we can do that, we're going to obviously call this update text void every single time we increment text. Let's go collision get component diamonds, update text. This should actually work pretty well. All we need to do is go back into Unity and make sure that we have assigned these two variables as well. Let's go to the counter over here and drag it in. Let's start it with a value of zero, so we don't start with some random amount of diamonds and see if that actually works. If we click play now got our diamonds counter on the right. We've got our hearts on the left. Let's see if we can collect and make this game easier. Let's see if we can collect diamonds. I actually might even increase the jump height a little bit more. I'm going to make it from 12, I'm going to make it 14. Let's see if that works a little better. It might be a bit high. Let's keep it at 12, but maybe increase the speed a little bit. Let's make the speed six. I know it was originally six, but I think it actually worked a little better. Yeah, that's slightly easier to traverse. That should be good. We obviously just have to wait for a dim spawn to see if we can test out our diamond collection. I don't think I would have gotten that one anyway. No, no diamond over there. There's one. There we go. And you can see it works really, really well. We have one diamond now and we collected it, and hopefully it's there we go. There's two diamonds. That's pretty much the basis for our diamond collection system. Obviously, we're going to get started with the ending finishing touches of our game. But we've got all the basics down before we can build it. We have to add in postprocessing, make it look a lot better, audio and music, and everything else. And we also have to add in savings so we can make sure we save how many diamonds we have. But I think we've gotten pretty far so far and we've actually done a decent amount of the game if you've followed along and your game is actually like mine is right now, a good job because you've pretty much a platform game already. Like everything else we're going to add now is going to make it a lot better. But these are all of the basics. We've got enemies, we've got a health system, and we've got me mechanics, and we've also got a count of how many diamonds you collect. Everything is pretty much working exactly as we needed to. In the next video, we're going to add in a game loop so we can continually play the game without having to click and click to restart. But once we've done that, you'll have pretty much finished the game, all of its basic components, by no means finish the game. Because you'll still have to add in the music and all the other postprocessing things to make it look better. But you'll finish the basis of the game is what I should say. Anyway, that's all in the next video. And if you follow along so far, great job. Thanks. 13. Lesson 12 - Creating a game loop: Hey there, and welcome back to Unity. There's one more thing we need to add to get this game to be pretty much all the basics of a game we should be able to play. And that's a game loop. In other words, we can keep playing the game for as long as we want, because right now, if we jump off the map or we die, if something happens, that's it. We don't really have anything else happen. And we can't even actually die that way. That's the first thing we need to fix. But we obviously can't continue to play the game, which is the problem first. Let's add in the mechanic that says if we touch the back of the screen or if we fall into the bottom, then we die. Let's start by actually moving this up a little bit over here to make it pretty much just right the bottom of the screen. Obviously, if you touch that, you're not going to be able to get back up in the way you can fly back. That's fine. Let's actually add another edge collider this time. We're going to add it to the sides of the screens. I'm going to click Edit Collider. And I'm going to drag the one over there. I think that that is actually a little too close. I'm going to drag it just behind that screen. And the second one I'm going to drag down here. And then I'm just going to adjust these so that exact same distance I'm going to make it -10.8 for both. I'm going to make the y element five and negative five. That should actually be pretty much everything we need. All we need to do now is we need to add in a script onto my main camera, onto my player, which says if I touch the main camera I have to die as well. Let's go back into scripts. Open up player health over here under my trigger stay three D thing I'm going to say if I collide with an enemy and invisibility time is this, then do this. Otherwise, if it's non enemy, if I collide with the main camera, in other words the boundaries of the map, then it doesn't matter how much invisibility time left. Anything else like that, I need to instantly die. I'm instead of calling the take damage void, just going to do a certain amount of damage and check if I'm dead and if I'm dead, then call the death void. Otherwise, call there is dead void. I'm just going to straight up call the death void myself and say, okay, then I need to obviously die and the game needs to stop. This is actually pretty much all the code we need to make sure that is an added feature. Now there's one more thing we need to actually remember to do. I forgot to make these both triggers, which or rather this one a trigger, that bottom ones trigger, but this one should be as well. Let's hit play a test if this works. If we're running along and we jump up to the wall, we instantly die. We can see we actually flew up there. Which highlights something else I thought might be an issue because I remember seeing it once or twice, but I wasn't actually sure why the tombstone moved up higher than it should. This actually makes it a lot clearer. What's happening is that because this is a trigger stay event, we're calling the death void multiple times. I'm going to have to actually make sure that we only call the death void as long as we're not dead. If my current health is great and zero, I'm not dead. In other words, I can't die twice. I can only die once. Because what's happening here is every single time we die, it's doing all of this stuff again. And it's like moving me up ever so slightly, which actually explains why sometimes I died, it looked like I moved up as well. I'm glad that we got that out the way I was wondering what it was. We have to add this and not is dead clause over here which says, okay, only kill me if I'm not already dead. Need to add the exact same thing over here is dead. Let's just make sure that that is both here and here. In other words, we can't call the death clause if we've already called the death clause once before. Those are the only two places in the entire script where I called death clause. Everything should be good. Let's go back and see if it works now. It should do a jump there. You can see I die instantly, which is perfectly what I want. And it should also work. If I fall off the bottom of the map, I should die as well, which is great. That's everything sorted out as I needed to. Now obviously, I need to add in my game loop, because right now I just die and there's no way of playing the game again. I'm going to add in a bit of code here that's going to say when I die, stop for a minute, then it's going to fade to black. And then it's going to fade out of black, having spawned in a new kind of scene. And the way I'm actually going to do that, I'm actually going to reset the scene itself. So instead of trying to reset everything back to how it was, instead of trying okay re enable all of these scripts and put in back way, I'm just going to reload the scene, which is effectively the same as clicking this button again, going like this and then going okay, do it again kind of thing. Which is actually going to work really, really well for me because I will have a faded out black screen. I should be able to load it again and then do it. And it's actually going to be good as well because I won't have to code in any of the extra stuff to set it back to the state which I want to be, which is this one. So I'm going to create a new to D object. I'm going to create a square, and I'm going to call it curtain because it's not actually a curtain. It's going to act like a curtain. Going to make it bigger than my entire game about that big. Let me turn down this alpha so I can see where it is. Say that's about good. And obviously with a zero offset, then I'm going to turn up the Alpa. I'm going to make it completely black. I'm going to make it order and layer 100 so it's in front of absolutely everything. This curtain. I'm not going to have existing for the vast majority of the game. But then the minute I wanted to, I'm going to spawn it in and it's going to fade into black, and then it's going to exist. Then the minute I start I'm going to want to fade from black to clear and then disable itself. I'm going to do all of this using animations. First I'm going to create a new script. I'm going to call it Curtain Script. Before I actually code. At this time, I'm going to add it to my curtain objects. I'm going to go here and I'm going to add curtain script to my curtain object. Like so. Then once I've done that, I'm going to open up curtain script and I'm going to create a new public void. Call it deactivate. That's just going to say game object set active, false. In other words, stop existing. We're going to have to enable this object again from another script. Which is actually going to be fine for our purposes because on this death script we're going to re enable the object and we're going to call a specific void. We're saying okay, fade to black, not fade from black. But right now we need this void over here which says, okay, stop existing. I'm going to use this in the animation to say, okay, yeah, that's all good. Then I'm going to have a new void over here and call it fade two. Inside this void is going to be where all of my animation code is. I'm going to go public animator, pull it an I'm going to say an set bool fade out and I'm going to set it to truth. What this is going to do is going to have a bull in which allows me to control, okay, I need to fade out now and then I'm going to do the rest using those events in the animator. But I need one more void and it's going to be the void to reload the scene. And the way we're going to code this, we're going to go to the top of here and we're going to go using Unity Engine, Scene Manager, or Scene management rather, this code is going to say scene manager, load scene, open parentheses, scene manager, get active scene name. What this is going to do is going to basically load whatever the name of the active scene I have, which is my only scene. If I go back into Unity, I've got Sable scene. Let's rename this because that's not the greatest name. I'm just going to call it main scene because it's the only scene we're going to be using for this game. We're going to be building everything inside it. And we're going to have this code over here which says, okay, when this void is called, which is going to be called by the animation use in an event, disable myself. Then when this code is called over here, fade two, which is going to be called by the player health script. I'm going to set my fade out to true and I'm going to fade out. And then the minute this code, which is also going to be called by the animation, I'm going to reload the scene entirely and it's going to start me exactly where I want to be. Let's go back into Unity and create a new animation. Sure, we're going to need two. The first animation is going to be called Curtain Fade In. And we obviously want to fade from full black to nothing. And we're going to add a buffer here. It's going to mess with animation, but let's just set that to zero over there. And then make sure that we've got the set 20 as well. Now I have a fade in and then it stays here. And the reason I'm adding this in iscause I'm going to add a event over here. Sometimes you add an event right at the end of a frame. It gives you some issues because it doesn't actually exist at this frame for very long. If it doesn't technically call the event, sometimes it goes to the beginning without calling in, then it's going to repeat twice just to save all of that, I'm going to give it plenty of time to call this event. And trust me, a third of a second is more than enough. I'm going to go curtain script, and I'm going to say deactivate. Once I've faded in, it's going to deactivate itself. Let's just make sure that if we open up curtain, that is the default thing, because that's the thing I want to happen first. The minute I start the game, it's going to do this. Then I'm going to create a new script. Call it curtain fade out. This script, or rather this animation, sorry, is only going to be called as long as a parameter of type fade out is true. I think that's what we called it if we go back here. Yeah, we called it fade out. Only when fade out is true. We're not going to be using any state here because this is the world's simplest state machine. But we're going to set X time off, we're going to set transition duration to zero. We're going to set the conditions to be. Fade out is equal to true, then as long as fader is true, we're going to call this fade out animation. That's going to say, okay, from nothing, we're going to want to fade out to black. Then what we're doing over here after this, after we fade out to black, we then want to call a new event. We're going to do the exact same thing here. We're going to add a buffer over here at 1 second. We're going to call that new event which is going to be reload scene. Now this is pretty much everything we need to do because right now we've got all of the code to fade out the minute we start or fade in rather the minute we start the scene and fade out. But we still need something to call these scripts. In other words, the minute we die after waiting like maybe one or 2 seconds, we want to call this script. Let's go into my player health script over here. Let's first of all create a new I numerator. Call it reload, Delay. It's going to be very simple. We're just going to say yield, return, wait for seconds, and we're going to wait for 2 seconds. Then we're going to want to do two things. First of all, we're going to want to activate that game object Curtain. Let's create a reference to it. Let's go public game object, call it curtain. We're going to go curtain set active. In other words, activate curtain again. Then we're going to want to call this fade to void. Immediately we're going to go curtain, get component, curtain, script, fade two. I think that's what the void is called. Yeah, fade two. In other words, when we die, wait for 2 seconds. Set curtain active and make him fade out. Or make it fade out. All we need to do over here at the bottom of death is call this reload delay void. I think that should be everything we need to work, obviously. Let's check it because there's often bugs when we're doing this. But let's make sure that everything is as we need it. We obviously only changed this curtain script over here. And look, we haven't activated the animator, But other than that, I think everything should be fine. Oh, we almost forgot to actually assign the curtains. Let's go here to play our health and make sure we've assigned curtain properly. Let's see if this works. If we had play can see in just like we want to, which is great if we die. Let's try there. We wait for 2 seconds, which might be a little long. Then we can see curtain doesn't seem like it's actually being activated. Might have some issue over here. Let's just go back and look at our code. How long we wait for 2 seconds and we set curtain active a true. Let's make sure this reload delay is being called by setting a print statement over here. This is how you got to test this. Thing's not how you have to do, this is how I like to do it. Let's try again. And we can see that the print statement clearly isn't working. So this corotine is not being called. And it's because we didn't write start corotine. See, it's a finicky thing. Sometimes I forgot at that time. But let's write Start Corotine, reload delay, and hopefully everything should work. Now let's go back into my game. So click play and see if we work. When we die, we fall down. There we go. Now we got to wait 2 seconds. Let's get to fade out, and we're going to fade back into the game. This is actually working pretty well. The last thing is obviously the fade in isn't really having effect because it's only doing it on the specific location of the screen, which is not what we want at all to be exactly where the main camera is. Just going to write one more tiny little bit of code. First of all, we're going to make the curtain a little bit bigger because the camera starts by moving. That's actually going to change when we add in our starting hub. But for now, let's just make it slightly larger just to be on the safe side. Let's up this scale by a little bit, just so we don't fade out of it already. Then last of all, we're going to go here where we're going to say transform do position is equal to game object Find in our scene, find a main camera. The position of that main camera is where I want to be. Let's see if that works. It should work perfectly fine. We now hit the play button. We can see we have a perfect fade in animation working seamlessly if we die going to wait for 2 seconds, which might be a little long, but I'll see it doesn't look like it's working. I think what the issue is, it might be changing the Z position. It's finicky. Things like this most of the time. Let's go game object dot find main camera position. And then let's go ahead and make sure that we actually change that position to zero on the z axis, and that might actually solve our problem. Let's see if it does. There we go. It's always weird, things like that. The main camera is slightly behind the scene, that's why it gave us a bit of a glitchy look. But that be everything that we need to do. We've made sure the position is the same. Now we can play the game infinitely. We have what is called a game loop, which is really, really cool, because that's the basis we need for our game. We've made everything we need now, except all of the extra things like audio and music and all of that. Let's just go ahead and delete that testing script we put over here which was the printing of the one. We've obviously changed the position now that it resets the zero position. But everything else should be fine. We've actually now not only a game, this fading in animation to make the game look slightly more, I guess, professional. So that is the basis of this episode, completed as well as the basis of our game. Pretty much done, which is pretty cool. In the next video, we're going to get started with saving, so that we can save how many diamonds we actually keep. And we have a high school, which is continuing even after we quit the game, so we don't lose our progress every time. But that is pretty much everything for this video. And if you followed along and everything is working just like mine is, that's great. And hopefully your game loop is working just like this. And you've managed to build pretty much the entire basis of a platform, a game. Congratulations for making it this far. And if everything is working out just like mine is, that's great. Thanks. 14. Lesson 13 - Saving our game: Hey there, and welcome back to Unity. Now this is probably going to be the shortest episode of the entire course because all we're going to add in this episode is saving. That might seem like it's quite complicated. In fact, if we use certain methods of saving, this would be a lot more difficult than what we're going to do. But we're going to be using the most simple and basic way Unity allows you to save in its game engine, which is called Player Prefs. Now just as a disclaimer, if you do plan on releasing this game and maybe especially if it's like a multiplayer game or something like that. I mean, I don't exactly know how you're going to jump from this platform to a multiplayer game. But you know, if you use this as a springboard to start game development and you plan on releasing a proper, commercially viable release, then you are probably going to have to choose to save your games a different way. Because the way I'm going to save my games is by saving specific files on the computer. And I'm kind of just saving them in not the most encrypted or sort of, I guess hard to crack way. So if I saved my entire game like this, it wouldn't take someone a lot of difficulty to go and edit those files and give themselves a whole bunch of extra abilities or coins. Now this is not the massiveest issue because, I mean, if someone really wants to do that for a single player game, they sort of can. And not that many people who play video games end up tampering with the files anyway. But if you're planning on making something like a multiplayer game, this is obviously an incredibly bad thing to have. Because you can't have some players able to give themselves a whole bunch of things and other players not Anyway, With that disclaimer out of the way, saving for most basic indie platforms is going to be pretty much fine, in my opinion. Some people might disagree, but it is quite easy to tamper with. But that's not really an issue for indie games like this, because the enjoyment is determined by the player, and if they want to mess it up, they can. But I guess that's true of any game in general. Let's get started with the saving script because it's not going to take very long at all. All we need to do is we need to go over here to our diamond script over here. Not a diamond script. I'll play a diamond script over here. I'm going to double click on this. And we're going to have a new void. Going to call it public void. Save diamonds inside this block wing around if statement to say if diamonds is greater than high school diamonds. In other words if we've gotten our high school, then we want to go player prefs set in diamonds, we want to set it to diamonds. This short line of code over here is basically just going to say, okay, take whatever I want to put in, which is my diamonds variable, and put it in this integer in Playerprefs called diamonds, which is basically saying save it in a file. If I want to get that later on I can go Playerprefs, get in diamonds. I'm actually going to do that right at the top of here in my start void. I'm going to say void start. And I'm going to say high school diamonds is equal to Playerprefs get into diamonds. This actually is only going to work after we've played the game at least once, because until then we're not going to have any value in here. So let's just add a quick if statement if player prefs has key diamonds, in other words, if we've already saved something inside this diamonds thing, then get it out. This code is obviously not going to run the first time we play the game. High schol diamonds is going to be set to zero. We can actually set that value over there as a default value, which is good programming convention as well. Because Unity sets these values all by default to zero because we've assigned them in the air. But if you're using a different engine or different programming language, it might not. So let's just go ahead and do that. And then let's say a start void. If we have something saved in diamonds, then bring it out and put it in high school diamonds. Then the saved diamonds void here. If our current score is better than that, then we want to replace it. All we're going to do underneath this is we're going to click Player prefs, Save. Let's go ahead and put all of this inside the statement. That is going to be pretty much all the code that we need to save our game and have things working in between sessions. All we need to do now is obviously call this void. Let's go back to player health. The minute we die, this is going to be attached to our player as well. Let's go Game object dot get Component Player diamonds, save diamonds. Let's test this out. If we go back into our game, we click on my player. We can see all of our default values are going to be over here. Let's click Play. Let's see if we've got diamonds zero and high school diamonds is zero. And that's not going to change. We're not going to have any error because we've used that has key thing. Let's see if we can try and get a diamond. It doesn't look like any luck so far. The minute we get one, I'm going to test out this code one. I've got one diamond, now current diamonds is set to one. I'm going to die. Let's see if it works. Currently, we're going to reset it. Now, let's just pause it quickly and if we go back to my player, we should be able to see that we do in fact have high school diamonds set to one. The next time I die, I'm not going to have higher than one diamond. So I'm going to restart my game play again. Let's see if everything works just like we anticipated it would. We still have high school diamonds set to one, and that actually works no matter how many times you play the game, no matter how many times you close it or whatever. The saving system is going to work because we're now saving the value in our game into a separate file. That is everything we need to do to get saving to work in my game. I'm obviously going to add in starting hub later on where I can show the high score of the player as well as the title and everything else. But for now we can know that everything is working just as it should. That is really the very last mechanical we need to add to our game. After this, we're going to improve the visuals and we're going to add in the starting hub and all the other extra stuff, audio and visual improvements. But for now, this is kind of the last step in making our game. And we have done everything so far. A great job if you followed along to the point where I am. Now obviously we do need to make some tweaks with these still because some of them are impossible. And maybe do a little bit of debugging to make sure our game looks a bit smoother. But so far everything is actually working pretty much how you would expect it to. And we don't seem to have any massive issues at the moment. So our game is in a pretty good state and we've all the basic mechanics, like I said, if you've been able to follow along and your game is like mine at the moment, great job. Because that's actually a pretty impressive game to have made, especially if you haven't made Unity games in the past before. Great job on following this video wrap until the end. Make sure you are up to date with this video before you watch the next one, because then we're going to be adding in the last touch to the game. And you want to get to this point before you move on. But hopefully everything works in your computer just like it does in mine. In the next video, we'll get started with adding in our visual improvements. Thanks. 15. Lesson 14 - Improving visuals: Hey there, and welcome back to Unity. Now I mentioned in the last video that we've pretty much finished all the basics of our game. And I know I've said that quite a few times, but it's actually pretty much completely true. Now we've done everything that you need for a basic platform. Again, we've got random infinite map generation. We've got a game loops, you can die and restart. We've got a score system with saving, and we've got a whole bunch of enemies and varied obscles and everything else. And obviously, like I said, you can die and respawn and everything gets saved. And it's all pretty much working just like we needed to. But there's a few things we haven't added. First of all, one of them is a starting hub, which we'll get to a little bit later in the course, so you don't have to instantly jump right back to the game. You can relax for a little bit. Second of all, we don't have any way of showing your high scores, even though it's saved, it's not actually there. Which we're going to get you in the starting hub as well. But most importantly, the game still doesn't look very good. If I go ahead and disable this curtain, if you could, exactly like me, you can just disable this whenever you need to because all it's going to do is disable the fade in animation. We actually do disable this and then re enable it via code later on. The fade out is still going to work, but if you want to see things in your game without having to disable this and move it around, then just disable it for now. I'm going to do that, The game doesn't look great. We've got this massive, big, dark blue background. We don't have any things in the background going on. We still don't really have any effects for when we die or collect coins. We just get them all changed sprite immediately. We're going to change all of that in this video and get started with a visual upgrade to the game. But before I get started with that, I just thought I would mention that I have changed a few of these floor tiles in between this and the last video. Now this is of no importance whatsoever because I'm almost certain you don't have the exact same floor tiles that I do. But a few of my floor tiles were impossible to get through. I just thought I would mention, if anyone notices, they look slightly different, I have moved a few things around. Like for instance, I moved this up slightly and this down, I think this one used to be impossible, so I moved this up as well. And this one I moved down. They're pretty much exactly the same as they were just with some slight alterations. But like I said, this isn't important at all. I just thought I'd mentioned it in case anyone is confused and they notice a difference. But regardless, we're going to get started updating the visuals of this project. Let's go into sprites and go important new assets just like we always do. These ten sprite assets over here will obviously always be linked underneath the video and they are under this one as well. Let's go ahead and select all ten new sprites we just collected over there. And then let's just set all these settings to single 12 and point no filter. Obviously if your pixels per unit are different then use your own value. But you should set this to point of using pixel art. And I'm just going to set the single for good measure because we ran to some issues with the heart, but it's not a massive deal. Anyway, let's get started by dragging this background into our game. We've never actually created an object like this before, but it just automatically creates a sprite object with this current sprite enabled. I think we did do it once and I'm just going to be doing it again because it's the easiest way to create a sprite. Then all I'm going to do is I'm going to drag this underneath my main camera like this, and I'm going to make sure that it is now a child object of the main camera and I'm going to zero its position. This is actually going to allow me to do is have this always be moving with the main camera. If I move the main camera like this, you can see the background moves with the main camera. You can imagine as we're playing the game, it's going to look something like that. This is always going to be in the background, which is pretty much exactly what we want for a background object like this. So let's just go ahead and make sure it is a child object just like this, and we've set its position to zero. Then if we go ahead and hit play, we can actually see the difference this makes already to our game. We've now got a much better looking game. We don't have these kind of random blue things in the background. Now we have a kind of actually looking all right. Game. But there are a few issues. First of all, our hearts are gone. I seem to randomly take damage on this thing. And it doesn't look like there are any enemies at all. But I'm still taking damage except these ones for some reason. The reason for this is actually to do with the order and layer of our sprites. Most of my sprites are set at order and layer zero because that's the default and that doesn't cause any issues. But now that we've added a background which also has order and layer zero, it just randomly gets priority over those sprites so we can't see anything. Let's set this to something like negative five. It doesn't matter what you set it, as long as it's less than the rest of your game. Let's also go ahead and actually reset my main camera because I didn't actually realize. But I did move it slightly to the left, so that's why that first cloud was a little off. Now if we had play, we should be able to see of these issues have been resolved, we have our hearts and our little counterback, and we've now got normal spawning things with diamonds. And we can see this makes the game look a lot better already. We've kind of had a massive improvement, but we don't really have anything else in the background. We kind of just got this sky and we have these clouds spawning, which are the foreground and the game. But we don't have any interesting things in the background. And I've created these background clouds as well as this eagle, which are both going to be pretty interesting to have flying through our game, but we haven't added them yet. To do that, we need to write a script. Before I write my script though, I'm going to make a pre fab for all of these. Because if you've guessed it, we're going to be spawning these pretty much exactly like we spawn the rest of our map, just they're going to be in the background so they're not going to be actually important, they're just going to be sprites that move through to bring in my clouds. I'm going to do exactly like I did with the background. Just drag them in there, like see all of them on screen now, they look pretty cool. I might have to actually change this overt, slightly less. So you can see that they're not part of the game and they're part of the background. But I'll worry about that in a minute. First, let me just make my prefabs. I'm going to go to prefabs and I call, I'm going to actually keep them named as background cloud 12.3 I think it sums them up pretty well. Now I'm going to delete these objects from my scene. Now I have my three prefabs with my background clouds over here. Before I get started with anything else, I'm actually going to add in a rigid body which might seem a little confusing, but it's going to do with how I want my clouds to move through the air. I'm going to be using rigid bodies to move the clouds through the sky. Let's go ahead and have three rigid body two D's on these. Select all of them and actually make sure they're all set to kinematic as well. Now that I've got I have to do this manually. It's a bit of a shame. There we go. I must have missed that one. All right, so now I have three kinematic rigid bodies added to my clouds. And that's actually all I need for them. But the ego is a little more complicated because obviously the eagle has an animation. Instead of animating this like we've done, I'm going to show you a trick. If you select four sprites and drag them in, Unity actually creates an animation for you already, like automatically, because this is the only animation we want to have. It's actually going to work perfectly. I'm going to name this eagle an actually we that created for us. We've got this eagle, one sprite over here, we've got an eagle controller. And if we go to open up the animator, we can see we've already got this eagle animation, which if we double click on it or rather open it up like so, we can see that we have an ego animation, which is going to change from all four of my sprites. If I go to my eagle and I click Play, we should be able to see that working pretty much perfectly, which is great. That's actually pretty much everything I was going to have to do, but done for me, I don't think that that flapping is necessarily the best speeds. I'm going to go ahead and change this to a playback speed of 0.5 and then if I hit play, I'll be able to see this in the action. And let me see if I decide, I think that's a lot better for an eagle. But pretty much what we did here, you cannot do it manually. We went to an animation and we created a new animation clip, added an animator component. And obviously, when we created our clip, that created a controller for us, and then we made our clip the default animation. But obviously Unity kind of did that all for us. If you'd like to do it manually, you can also do that. Just follow the exact same process we had done before. But if you want to create an object quickly and an animation and you only need one animation, or you want to have something like this where it's an animation, it's always going to be playing. That is quite an easy way to do it. And then you can just change the playback speed, something that you like. That's my Eagle Done. Let me go ahead and drag that into prefabs as well. I'm going to rename this to Eagle rather than Eagle One. Then all I'm going to do is open up that and I'm going to go back to my scene and add a rigid body just like I did for the other ones except make this one Kinematic. Now what I'm going to do is I'm going to write some short scripts. I'm basically going to have one script which is going to spawn in an eagle, and another script which is going to spawn in the clouds. And I'm going to have them travel across the speed, at random speeds across the screen. At random speeds, um, from a specified range. And then the minute they reach a certain thing on the other side, they're going to deactivate. Now, I'm not going to use any kind of boundary on the right side of the screen. I'm not going to say put a boundary over here and say, okay, if the eagle hits this. Because I don't want the player to be able to run into boundaries and die on that side of the screen. I think it only needs to be on the left. You should be able to go ahead of the game. I'm going to need to code in manually. I need to say once this position is passed a certain position, then you need to call it a day. I'm actually going to do that in a bit of a sort of slight handed way, but it's going to work a lot better. I'm going to have a boundary object over here, and I'm going to move it like so. And then all I'm going to do is, instead of trying to constantly calculate, okay, where am I reference to the main camera? How far is my actual position and my relative position? I'm going to say the minute I'm past this boundary object, I'm actually going to put it on the other side because things are going to be spawning in from both sides. So let me move it one over there and one over there. Let's say the minute I'm past one of these boundary objects, then I can call it a day and that's everything done. The E is going to be flying from right to left and the clouds going to be going from left to right. So I just need to make sure I keep track of which one is which. But that's going to work pretty much well. I'll call this one boundary left. I'll call this one over here, Boundary right. These are going to allow me to keep track of what is where. I'm going to change this to -11.5 and make this 111.5 Then the minute I have my object past this point, I'm going to have a spawn. I'm actually going to move this a little bit like this way because the clouds are quite big and I don't want them to spawn off screen rather on screen. Let's make that 14. The eagles are pretty small, so I think 12 should be good here. That's pretty much everything we need to do to set up our scene. Now we just need to write the script for this spawning. I'm going to stop the Eagles, let's create a C sharp script and call it eagle spawn. Let's double click it to open it up. Now all we need to do is write some code that says, okay, every random interval spawn in a new eagle. Let's create a, let's call it float. We'll call this minimum Y and maximum Y, and this is going to be where we want to spawn on the Y axis. Then we're going to create another public float, call it min time and maximum time. That's how long we want to wait between eagles. Then all we're going to need to do is create a reference to my Eagle prefab public game object Eagle. Then before I get started, I'm going to delete this void update and create a new routine. I numerator, call it spawn delay. Then inside this, all I'm going to do is I'm going to say yield, return new weight for seconds from minimum time all the way up to maximum time. I'm going to wait for a random number inside there. I actually forgot my random dot range. Let me write random range from minimum time all the way up to maximum time. It's going to pick a random umber inside that interval and then wait for that long minute that's done. I want to create a new void. Call it spawn eagle. Let's go back up here and call my spawn eagle void. So the minute we've done that, now we just need to code this actual thing over here which is going to determine what to do when we want to spawn an eagle. The first thing, just like I've done before, is I'm going to say game object for eagle equals instantiate Eagle as game object. In other words, create an instance of this prefab in my game. Now I want my S position to be behind the main camera. And this script is actually going to be attached to the main camera. Let me say transformed opposition equals new vector three. Let me create an offset variable up here, just like we've done the entire time. Let's go my transformed opposition. Do the camera plus this offset, and it's going to be a negative value. Becaus I want to be behind. Then I'm going to want to pick a random number inside my minimum Y and maximum Y. Let's go to random range between min Y and May. Then I'm just going to set my Z to zero because it's a two D game, doesn't really make a difference. Then all I actually need to do now is create another script which is going to attach to the Eagle. And I'm going to say, okay, travel for this long. And then the minute I'm behind this boundary, then delete. I'm going to write the same script for the Eagle and the Cloud. I'm going to call it sky object. That's going to make it slightly more complicated to do, but it's going to be a slightly better way to code it as well. Let's double the up inside the script. We're going to want a public transform. We're going to call it boundary. This thing we're going to be watching out for. We're going to have a public boolean and we're going to call it traveling right because obviously the eagle is going to be traveling right. The clouds going to be traveling left. So we're going to use to determine which way we're going. Then underneath this, the last thing we need is a reference to a rigid body. I'm obviously just going to drag that in when I have my objects created inside my game. I'm going to put it on the prefabs. The last thing I want is a public float called velocity. All I'm going to do inside fixed update is I'm going to say every single frame, make sure that my velocity of my rigid body is equal to a new vector two and whatever my velocity should be, as well as zero because I don't want them to be moving up and down. Now I'm going to every frame, make sure I'm traveling in that way. Then underneath every single frame as well. I'm going to say if traveling right then, I know that I have to be behind the boundary. If I'm ahead of the boundary, I want to make sure to destroy this instantiation of the objects. I'm going to say if traveling right. And then inside this I'm going to say if transform position x is greater than boundary position x, then I want to make sure to destroy this instance of my game object. In other words, delete whatever object this is attached to. If I'm not traveling right, means I'm traveling left. So let me copy this exact code. Just say if my traveling position x is less than my boundary, then I want to destroy this instance of the game object. This is actually all the code we need to make sure that our objects are going to travel at the right way. But we obviously need to assign values to this, because right now this has absolutely no value for boundary or traveling right or velocity. It only has a rigid body value. Let's go back into eagle spawn and create a few new variables. Public float, min speed as well as max speed and that's how we're going to choose the speed of our eagles. We're going to go get component and we're going to find the sky object script on top of our Eagle. We're going to say velocity is equal to random range between our minimum speed and our maximum speed. Now we have this velocity checked off and we obviously already have the ridge body which is going to drag that in. Now we need is this traveling right variable. And we know for an eagle that's going to be true. Let's go ahead and copy this entire line of code to lead up to here and just say traveling right is equal to true because es are going to be moving from left to right. The last of all, we need this boundary and we're going to create a reference to the boundary for eagles up here transform, call it Eagle bound. Then let's copy the code again. And underneath here just say dart boundary is equal to Eagle bound. We're actually going to call this rotine from the start of our game the minute we start our game starts spawning. In this behavior, wait for a number of seconds and then start spawning in an eagle, which is pretty much all we need to do. All we need now is to actually assign all of these things in the editor and test if it works. I think it should. The only last thing we need to add underneath all of this Is obviously call the corotine again, so that we can say whether we want to spawn another eagle. This is obviously going to continue playing even after the player is dead. But that's fine. You can have clouds passing and eagles flying by after the player is dead. It's not too much of an issue. And obviously, the player is only dead for like 2 seconds anyway. So it doesn't really make a difference. But this is all the code we need. We're starting our cotine at the beginning. We're saying, okay, wait for a number of seconds. Then spawning this eagle, set his position to behind us and then a random y position and then make sure his velocity is this random number. The fact that he's traveling right is true and set this boundary to this thing. And then inside the Eagle, we've assigned all these values over here and every single frame, we're making sure we're traveling at the right velocity and checking we are not past where we should be. Let's open up Unity, Go back into our prefabs and we're going to add this object sky object script to our Eagle. The only thing we're going to sign is the rigid body. Everything else is going to be done for us. Actually, just for the sake of being efficient, we're going to add it to the clouds as well. For now, just so we don't have to do it later, let's go sky object over here to this cloud sky object over here to this cloud and sky object over here to this cloud. And make sure we drag in our rigid bodies. You don't have to do this right now, but I'm just going to then let's go to main camera and let's add a new components. And we're going to add in my eagle spawner over here. I'm going to set the minimum y to be negative 0.6 and then the maximum y to be, let's say 2.5 negative 0.6 and 2.5 Let's go ahead and assign that over here, negative 0.62 0.5 I'd say I want the minimum time between eagles to be at least 10 seconds and the maximum time to be somewhere around 14. I'm going to assign this eagle over here. I think the offset. Let's just test it. But it should probably be a, I'd say maybe negative 12. If we look at the main camera at position zero, the player is currently negative 12. That's about where I want the Eagles to spawn. Let's set that as well. Go on here and set off set to negative 12, then minimum speed. I'm just going to start at three and set the maximum speed to four. Keep in mind the camera is moving at currently 1.8 It will be faster than the camera, but it might not be that much faster, which is good. Actually, let's set it to 2.5 and 3.5 Then last of all, eagle bound, we are going to set to be this right hand boundary over here. Let's see if all of this actually works. If I hit the play button, make sure we haven't forgotten anything or run to any bugs. Let's see, over here, we've currently playing the game. The minute we spawn it, we should have this eagle, which show up behind us. So let's see if we watch over there. Oh, that was a diamond. Whoops. We'll be at least 10 seconds before we see one. Ah, there's one right there. We've got an eagle. That does look a little bit like an enemy. I won't lie. So we're going to have to make it a little bit higher just because I don't know if that should be exactly where it is. I'm going to actually set the boundary bit up and I'm also going to make sure that the time is a little bit different because we don't really want that many eagles. Let's make a few adjustments. Let's set the minimum y to be one, the maximum y to be three. Let's at the minimum time to be 10 seconds and the maximum time to be something like 20 seconds. Then let's make the minimum speed, maximum. I think those are both good. Let's just maybe make the eagle slightly more transparent so he doesn't look like he's so much a part of the game. Let's make this 180. This might be a weird design choice, but trust me, it's going to make it look a little bit more distinguishable, that he's not really part of the game. We can obviously tweak that as need be, but let's just test how that works for now. Obviously we have to wait for a bit for the thing to spawn, but it should be coming out. There's an eagle right there. And there we have it. You can see it looks like it's misted out by the clouds. But that looks quite cool in my opinion. Obviously, we need to add in a few more clouds and it's going to make it look a lot better. But for now, I think the Eagles are a success. Did not mean to do that. We can see we've got quite a few of them. We might even have to make that time a little bit longer. But let's just change that quickly. I want to actually make this 30 seconds and ten, and then I'm going to maybe them a little bit faster as well so they can fly past. But that is pretty much all the eagles spawning script we need so far. Now we have to get started on the clouds. The cloud script is actually going to be so similar to the Eagle script. I'm going to copy this entire thing and I'm going to create a new script, call it cloud spawn. I'm actually going to paste the entire thing. Now there's a few things I have to keep in mind. First of all, it's going to give me a whole bunch of errors because I've got the same class over here without explaining too much what a class is. Basically, this is how unity tells or rather sharp tells unity. Which kind of identity of code. This is the fact that they've got the same name now is an issue. Let's go ahead and change that to cloud spawn. It has to be the exact same name as you've got over here. And that should actually get rid of every single one of our errors. Now you can use all the same variable names, none of that section issue, but we obviously have to change a few of them. Let's go ahead first and change this to spawn cloud, then we're going to have to update that as well. Then let's change this to cloud to cloud bound. It might look like we could have done this in one script and we honestly could have. I thought that it'd be better to do two just because we're going to make a few differences and alterations. And it's going to make it a little bit easier to understand if we have two different scripts, rather than trying to group it into one and spawn eagles and clouds simultaneously. Yeah, we could have done this in one script, but I'm just going to use two. For the sake of efficiency or rather simplicity, I can keep this minimum Y and maximum Y because I still need that. I obviously still want my time. I have my game object cloud. I want my offset just like it was. It's obviously going to be a positive value now. And I have my minimum and maximum speed which are going to be different and my transform, pretty much everything else actually we can keep the same. We've got the spawn delay. We're going to instantiate a cloud. We're spawning at a position, we're saying it to a random speed. We're going to set traveling right to faults over here, and we make sure that we have the right boundary. That should be pretty much everything we need for our clouds. Let's go back into my game. Go to my main camera. I'm now going to add in this cloud spawn script underneath it. And obviously you can see it looks very similar to the Eagle script because it's pretty much the same script. We can pretty much go ahead and use the exact same thing, but we've got a bit of a problem. We've only got one object here for a cloud because we only had one eagle. But for the clouds we need to pick from a random of three. That's actually quite easy to do. All we need to do is make this into an array. Then instead of saying instantiate cloud as object, we'll say instantiate open square brackets, random range from zero to the length of cloud. So we'll go cloud dot length, and then close bracket. Close square bracket. And that should be everything we need to do now, We're basically just picking a random thing from this array. Instead, let's go back into Unity. If we scroll down, we can see now we have a cloud array, which is what we need. Let's drag in all three of our objects over here. Let's set the minimum Y to be zero and the maximum Y to be three. So you can have cloud spawning. I'm actually going to make this minimum Y negative two and the maximum Y three, I'm going to set the minimum time to 2 seconds and the maximum time to 4 seconds. I'm going to set the minimum speed to negative one and the maximum speed to be zero. The negative 0.5 the offset, I'm going to make 12 because it's tell the other way. That should be pretty much everything we need so far obviously. Just make sure we have our boundary on the left. Almost click the wrong one, boundary on the left as our cloud bound. Let's go down and check that. Let's see if this works. If we hit play now we should be able to see cloud spawning in from the right pretty soon after we start playing the game. Let's go ahead and see if it's working. And there we have a cloud that is spawning. But this is quite obviously looks like a part of the game. That's a bit of an issue for us because we obviously want it. We can also see them spawning in, which is also a bit of an issue. We clearly have to make that offset slightly more, and we have to make them slightly more transparent. Let's make the offset something more like 20. Then let's go ahead to every single cloud and maybe make the alpha something like 180 instead of 255. This might be a little drastic, but we'll can adjust it as we go. I think it should be fine for now. Let's go back into my game, and I think the clouds can move a little faster past the player as well. Let's go back to main camera and make the minimum speed negative one. And the maximum speed is negative 0.5 They are actually moving always. Now let's see if that looks a little bit better. As we're spawning in the game, we should be able to see cloud spawning in right then it's coming in from the side there we have a cloud which actually makes the game look a lot nicer, obviously. Now there's a bit of a delay at the beginning where we don't have any cloud to make simplicity a little bit easier. I'm just going to drag in a few from the start of the game, just like this, and make the game look a little more alive from the beginning. Obviously, I'm going to have to set these velocity values on their own because these are special cases, they're not media assigned. Forming I'm going to make the velocity negative 0.5 I'm also going to change those and I'm going to make sure I set the boundary to the one on the left. Then let me go ahead, I'm actually going to set the velocity to zero just for now. They only get destroyed once we move past them. Let's go ahead and see if that looks a little better. Maybe this very specific one can have a velocity of negative 0.2 and this one can be negative 0.1 Just to give it a little bit of uniqueness, if we go ahead and hit play now we can actually see both our Clouds and our Eagles are now in our game. And it makes it look, in my opinion, a lot better. There is still this little weird gap over here. So I'm going to add in maybe one more cloud over there just to make it look a little better. But I think that's actually a pretty cool start to our projects visual updates. And we've actually done quite a lot so far. We've obviously add the background and the eagles and the clouds, and in my opinion, it's looking a lot nicer than it did before. But there's two more things we have to add. And they're quite easy to add, they're not super complicated. This actually also adds a nice effect where the spie balls are hidden, which makes a game maybe a little bit more difficult. But I think that overall, this makes the game look a lot nicer and a lot more kind of alive as you kind of jumping through clouds instead of just wandering through this blue sort of mass. And we can see the clouds are a getting destroyed, just like they should be. The eagles are taking their sweet time. But I'm there we are, There's our first one. I think it makes the game look a lot nicer, which is pretty cool. But anyway, like I was saying, there is no particle effect, not only when you collect a diamond, but also when you die. And I think that you'll find by adding these small little things to your game, it makes it look a lot more impressive in the long run. Especially to someone who doesn't necessarily know how kind of simple they are. Actually to add in makes the game look a lot more impressive than it's kind of actually the amount of work it takes to add in. So I'm going to show you exactly how to do that now. We're going to go to my diamond sprite. I'm going to add a component called a particle system. Now this is arguably one of the most complicated components in the whole of Unity. I don't even fully understand how it works, to be honest, but I have found a way of working with it that does usually work for most of my games. And I think it's quite an easy way to do it as well. So I'm going to show you now without going into too much detail. Obviously this particle system is based on a whole bunch of different things over here which you can see listed. We've got velocity of a lifetime, shape, emission, render all of these pretty overcomplicated things, but we don't actually need to worry about most of them for now. In fact, I'm going to show you which ones are going to enable, we need emission and we need shape. We don't need any of these ones. We're going to need color over lifetime and we're going to need size over lifetime. Then none of the other ones should be that necessary. We might have to enable text sheet animation depending on what we want to do. But let's just try it like this for now. Once you've gone ahead and enabled these five different menus, open up the renderer and make sure you set this material to be a sprites default material. Now we're spawning in random sprites. There's actually one more sick thing. We need to add this text, a sheet animation. We're going to select that. We're going to select mode to be sprites. And we're going to go ahead and this is for our diamond, we want to spawn in our diamond, star sprites, we're going to choose star. Now we have a whole bunch of stars flying off this diamond, which looks pretty cool on its own. I'm not going to lie, but we only want this to happen once we collect the diamond, we've set our texture animation up and the only thing we need to change in renderer was this material. Once we've done that, we've got all of we need from these two menu. The last ones are coming from these ones over here. Let's start by going to my original menu, actually at the top here. This is also a menu. I'm going to make the duration 0.3 seconds. I'm going to set looping off, I'm going to make the start lifetime of these 1 second, or rather 0.6 Actually, obviously you're going to need to tweak this as you go. And let's see how that looks over here. We have a few things spawning, which looks pretty good to me so far. I want the start size to be one is maybe a little smaller. I'm going to make the start size two, see how that looks. I'm actually going to keep that at one for hour because what's running it is the size of a lifetime, not this value. I'm going to set the 0.3 seconds, not looping. Zero for the start delay is 0.6 for the start lifetime. Five for a start speed is fine, and one for a start size. I'm going to keep the rest of these as they are for now. Then I to change this rate over time of emission to something like 30 and see what that looks like. It's a whole bunch more. I think that should be okay for now as well. Let's go ahead to the shape. This shape is a cone. It doesn't really matter too much. We use, we could use a sphere as well. I'm going to use a sphere, and I'm going to make the radius 0.2 So they're all coming from the center of the diamond. I think that looks quite cool as well. Now we need to go to color over lifetime. If this is hard to follow along, don't worry too much, because I will go over everything we've done. But just try and follow as best you can right now. Let's go to Color over Lifetime. And now we're going to open up this window over here. We're going to click Mu. Then we're going to go over here to this thing at the top and set the alpha to be zero. We're basically creating a gradient here. We're saying from the start, set white at the end, still be white, but at the start of here have full alpha, and at the end be completely translucent. We can see the effect of that. Now it looks a lot more like a particle. Then the last thing we're going to change, we're going to go size over a lifetime. We're going to click on this size, and we're going to make it this one over here. It's going from big to small. You can see the effect. I'm going for it like this cloud of sparks that dissipates right now all I've kind of changes, I've changed the duration to be 0.3 seconds. If you'd like, you can pause the video and copy these along. I will kind of scroll through them all quickly, but I'm going to change them a little bit more. So maybe just stick with me a little bit while I go back to all of these and make sure I have them set high. I want I'm going to keep the duration at 0.3 seconds. I think that's good. I'm going to make the start lifetime 0.6 I think that's fine as well. The start speed, I'm going to increase maybe to something more like six. Just to see how that looks, I think that's a little better. Maybe even something like two might actually give a nice effect, considering the particle actually gets destroyed. I'm going to set it to something more like one, just so it's more like a lingering thing that you have. After you've collected, I'm going to set the start size to 0.5 and see how that looks. I think that looks a little better. Then I'm going to go to my color over lifetime and maybe actually change this a little bit. I don't want them to be com 16. Lesson 15 - Creating a starting hub: Hither. And welcome back to Unity. Now in this episode, we're going to be creating a starting hub for our platform, a game. We're also going to be giving it a name. A name I arrived on is Sky Miner, which is God awful. But thankfully, this game isn't going to be released to anyone. It's just for you guys to learn how to create platforms. I've settled on Sky Miner and I'm going to create a starting hub for this game. As well as make it so that you don't automatically play the game. The minute we click play. Right now we're in leapt right into the game. And I don't want to be like that. I want it to be so that you can choose when to start. I'll explain how I'm going to be doing all of this, but basically I'm going to be building like a starting hub at the original, making it sound pretty dramatic, it's just a big cloud. I'm going to have the title in the top as well. Then I'm going to make it so that the minute you pass along a certain point, then the game starts. Not the minute you start the game, the minute you pass a certain point before I get to ahead of myself. Let me go ahead and import all of my different assets. I'm going to go right click. Import New Asset, just like always. Then I'm going to import these two assets which I've created called starting and title. Let's just set them to 12, single point, no filter. And then I'm actually going to go to this cloud over here. And I'm going to delete it because I'm going to replace that. I'm also going to go to these prefab clouds and I'm going to put them in storage because I don't like the fact that they're just sitting underneath it. That looks a lot neat, in my opinion. Then I'm going to drag this starting cloud in. You can see what it looks like. This is what I've got envision for the start of the game. You start with this massive, obviously not like that, has to be about there. You start with this big cloud in the middle and I'm actually going to move it down Us don't want to take up that much of the screen but don't want that little either. I think that's probably maybe good. I might adjust this as I go on, but I actually think I'm going to move it up a bit more. Actually, let's see. We can obviously change this as we move on, but I think that's actually pretty good to start now. I'm going to have the title in the middle of the screen just so I can see everything that's going on. I'm going to click this icons. I can hide all of this extra stuff, but I might also choose to move some of these clouds now that I'm creating this new hub area, but I'll get to that later. First, let me just disable these clouds. I'm also going to drag in my title, and you can see my title over there in the middle of the screen. I think it's a somewhat decent title. At least for now. I'm actually going to disable them just because hiding them only works in the editor, and I want to see it in the middle of the screen. Then I'm going to go to my title, which I'm actually going to want to keep as a sprite. I don't want to be a UI object, center it at zero and then put it right at the top over here. I'm also just for the time being, going to disable this UI because I don't want that to show up at the beginning of my game either. I'll obviously fix all of this when I'm going to create my game. But just bear with me from a minute. First of all, I'm going to have this right over here. Sky Miner. Actually, the first thing I'm going to want to do is create a title animation. Let's go create new animation. I'm going to call its title then. I'm just going to make this slowly go up and down. Let's have the first 30 seconds moving, let's say from 2.6 to 2.4 You go like this, and then I want to stay at 2.4 and move slightly down over the next 30 seconds to maybe 2.3. So we go then we want to go back up to 2.4 Slightly faster. Then back up to what we originally had up here, which was, I think 2.6 Yeah. Let's see how that looks. See if we're going to the game that's a little fast, but I think it gets the job done. It looks pretty. All right, as a subtle looping animation, let's make this 0.3 speed. Let's see if we hit play how that looks. So we're going to have to see the camera move along and we're going to die in Son, because there's no things. But I think that does a pretty good job. It's moving very slowly through the thing. That actually brings me to the next thing I want to do, which is get started actually building this starting area, not just having a square. Let's add a box collider two D. We're going to have to obviously tag this as ground. Let's go ahead and make sure this is the correct dimensions. It might be quite hard to see this if you have all the things I do. So I'm just going to disable the background as well now. I'll be able to see it. Now let's move this to about there. There doesn't need to be that much higher here because you shouldn't really be able to fall through. That should be everything done over there. Let's now test if we can play the game. I've always disabled my background in the editor. It's going to show here that looks pretty good. I'm actually going to make this ever so slightly smaller. I'll move it down to about there. That is pretty much the. I just realized this is going to be a bit of a problem. Let's move this like maybe a bit and down a bit more. I think that's probably good now you can stand on the end of the cloud, but it's not too much of an issue. That is going to be the basic for my starting block over here. And I've got my title which is going to move up and down. The title. I actually never want to move. I want to keep it here all the time. I don't need to do anything with this. Same with starting. These are fixed positions. But what I do want to do is I want to, so that the things Follow the camera like the UI or only enabled once we've walked through this. And I also only want to start the game. Once we've walked through this imaginary point over here on the middle of starting, I'm going to create a new empty object. And I'm going to call it boundary, just like we've done before. Over here at this boundary, I'm going to make a collider. I'm going to make it an edge collider because it's going to be a boundary. I'm going to make the 0.0 0.5 and negative five, it's a long boundary. It's going to be a trigger and it's going to be of type start zone. In terms of tags, I'm going to make the tag start zone and I've got this big trigger collider. And I'm going to say once the player passes this, I want to start the game. So obviously you can see we can move along. I'm actually going to make this just a little bit longer because otherwise it's going to be able to fall through. Depending on how weird this looks, I might make this a box collider and then another collide undernath, But that seems like a bit of extra work for a small change, I'll see. But right now all we're focused on is having this boundary. And we want to say, okay, the minute the player passes this boundary, then we want to start the game. We've labeled this tag start zone. But we're going to actually be doing the coding on this thing itself. We're going to say when I collide with the player, we're not going to worry about the player colliding with it. This is just a formality. I'm going to re enable storage so I can see all of the things I have and I'm going to start customizing this. I don't really want that cloud there anymore. I don't really want this cloud here. Whoops, I did not mean to delete the entire UI. I don't want this cloud or this cloud here actually, because our game looks all right with just the sky thing. Since we've now added in the other stuff, I don't even really want that cloud. But I'm going to put this cloud over here just so I have something to jump to when the game does start. Move this cloud up here slightly. We have one cloud to start us off. That's going to be how the game looks when you start. Obviously, once you pass this point, we want the game to start. Let's go ahead and write a new script and we'll call it start Game. The way the script is going to work is we're going to replace a lot of these void starts we've got which start when the game starts. Two voids we're going to call. The only ones we're actually going to be concerned with are the camera movement script and the map generation script. If we go over here, we can see camera moves over here. We're going to want to concern ourselves with this one and we also want to concern ourselves with this map generation script over here. These are the two ones you can see over here. We've got to spawn piece, but we want to change this to begin game and we're going to make it a public void. We don't actually even need to make this void. We could just stray up, spawn a mappiece. But for convention, I'm just going to have it be this thing over here where we only start when we call this game void. This update void is not really going to be a problem because we're not going to be moving the camera, so we don't have to worry about spawning more map pieces as well. Let's go back to my game and let's create a collision on trigger event. On trigger enter two D collision game object dot compare tag. Just like we've done the whole time is player. In other words, if the player just walked into us then we want to start the game. We're going to create a reference to these two scripts. Camera move, we're going to call it camera move. We're going to create a reference to our map generation script as well. Call it map. We're going to do is we're going to say map begin game. In other words, start the game. We're going to say camera, camera move. Camera speed equals. And then we're going to have this default value over here on our camera move, which is going to be what we want the speed to be. I'm actually going to change this. I'm going to make this public float camera speed. Then we're going to have a public float underneath it, which I'm going to call speed. The speed over here, I'm going to set to be the variable which is moving it. And then this camera speed is like this setting I want, I'm going to set this in the game, but it's only going to be influenced by speed. And I'm going to say camera speed is equal to camera speed. In other words, I've got this setting over here, camera move, camera speed, I've got the setting over here, which tells me how fast I should be moving. Then I've got the speed variable, which is obviously going to start off at zero. Then the minute I start my game and I say, okay, set the speed to the camera speed, then it's going to change to whatever I've put in here and I'm going to start moving us along. This is pretty much all the code we should actually need to start our game manually. The way we can test is we can go into our boundary over here. So let's go ahead and drag in start game. And then drag our camera move script from our camera and our map generation script from our camera. Then that we can see the minute I touch a player, I should start this code. I should start moving. Let's go back to my main camera. Let's set my camera speed to one point. My speed is zero. Now have a hit play. I should not start the game until I move along there. Let's see if that works. Currently moving, nothing has spawned yet. Obviously, the clouds are still spawning, which I do want, but nothing else has. But the minute I cross this boundary over here, the game does start. See over here. Now I can start actually playing the game, which is exactly what I want. Obviously, this first cloud is a little bit weird, because spawn on top of another one. I might just have to adjust that initial offset and make it start slightly further along, but I think that would be fine. We can change that a little bit. Let's just get focused on moving this. Maybe you don't even have to jump for the first cloud, it's just a cloud into another cloud. Then the first cloud should spawn above that, so it's going to look a lot better. Now, that actually worked perfectly fine. I'm going to move this boundary a little bit to the side of here. The minute you pass a certain thing, it actually goes. But there's two more things I want to do. First of all, I want to make sure this sign displays your high school of diamonds. That's actually also quite easy to do. All you need to do is I need to go into my UI and I'm going to create a new text over here. Let's go Legacy Text, because we don't want to use the text me. Let's call this diamonds. I'm going to move it over here. I'm actually, for simplicity sake, just going to copy this diamonds counter I've got over here. And move it over here. Then I'm going to set a test value of 300 or so. It doesn't seem like anything showing. Let's try to resize it. It's behind it. I'm actually going to have to change the order of this canvas. I'm going to make the canvas order in layer two instead of one or actually even five, because we pretty much want the canvas from front everything. So let me just make it ten, see if that has fixed our issue. If we go back here. Yeah, now we can see we have this showing up in front, which is exactly what we want. I'm going to rotate the slightly because the sign is a little bit crooked itself. I'm going to resize it back to what it should be, which was something more like that. I'm going to set that to that. I'm going to rotate it a little bit more. I think that's probably good. Might have rotated a bit much. Let's turn it back a bit. There we can see now we have a little marker that shows us what our maximum diamonds collected in one of the run was. Now we need obviously program this to actually display the high score. That's actually incredibly easy. All we need to do, it doesn't really matter what script we pick. We can pick anyone, but I'm going to pick this player diamond script over here. Because that's already got UI here and it's already got a reference to text object. Let's create a new one, public text, call it high school. Then all I need to do under the start void is say high school dot text is equal to high school diamonds dot two string. That's going to basically say okay, when I start the game, make sure to set that text or whatever my best score is if we go back into my game now let's go to my player and see if that does work. Let's find over here we've got high school. Set it to this counter. I'm going to rename this to high score count. Then if we had play, we should override that. At the start of the game with our high school, which it looks like it has done, our high school shouldn't be zero, it should be one. We seem to have a bit of a bug, but I believe, actually the only issue is the fact that we're assigning it before. We've assigned the variable over here, which is exactly what it is. Let's just go back here and put it underneath. And then it should work perfectly fine. If we go back into our game, we hit play, We should see, now this should change to one the minute we start the game. And it looks like it is. That is perfect. Now we have a high school counter. We have this thing that allows us to start the game by walking through it. And we have everything else working just like it should, which is pretty cool. All we need to do now, the very last thing that we actually need to make sure is just make sure that when we start again, it doesn't give us any glitches. What I'm actually going to do instead of moving this cloud is just make it so the first cloud spawns a little bit further along. And then I'm going to do that, I'm going to go into my map generation script. I'm going to have bullion over here to be starting block. In other words, if it's the very first one, I'm going to set to false over here, but over here it always needs to be true is the very first block. And that just basically allows us, when we call in this object, to call in this method, we can enter a value over here when we call it from here, we can differentiate from where we call it from here. Then all we need to do need to go and add a little if statement at the end. We need to say starting. In other words, if there's the very first one, then I just want to move it a little bit to the side. I'm going to say saw spawned tile, transfered opposition. Let's add a starting offset. So let's go public float start offset and we're going to make it slightly bigger than the one we have over here. Just put that over there. And we're basically going to say, okay, let's put the tile there. But if it's a very first tile, I actually want to put it somewhere else. So let me put it there. It is going to spawn it in a different place, but it really doesn't make a difference. Let's go back over here, and let's go back to our main camera. And let's make the starting offset 18 rather than 15, and see if that works. We now move that a little bit, let's see if that works a little bit better in terms of spacing. Let's then test that lasting mold, which was see if the rest of the game does run smoothly. It looks like 18 is actually working pretty well. We've got an issue over here with the one which you need to fix, it's not going away. We've actually also got an issue with the UI, which I also want to fix so that it doesn't stay when you're not playing the game. But let's just first test the other thing, die, then camera still moves. That's another problem we need to fix. Let's go back and everything seems to be working fine. Let's go ahead and quickly just look at what we've got to fix. First of all, the reason why the camera is still moving is because this original script over here, which edited the camera speed when you die, changed the camera speed variable. We want to change the speed variable because we've changed how that script works. And so we want to make it change the speed, not the camera speed. That's the first thing. The second thing we want to do is we want to make sure that this text over here that we have does not keep moving as the camera moves. The way I'm going to do that is I'm going to actually create a new UI and have that one stored in there and make that one not move. And then have this UI that I can edit and spawn in when I want to start the game. We've already done quite a lot of episode, I know it's been a while, but we're almost done. So just bear with me as we finish these last two things. First I'm going to do is I'm going to go to the starting thing and I'm going to create a new canvas. I'm going to call this two. Then I'm going to copy my high school account and put it inside two instead of where it was originally. And I'm just going to change UI two to screen Space camera and drag in my camera, then double click on it and let's see where it is, not where it should be, but let's just move it back up. We're going to change this order and layer to be ten as well, just like the other one. Then let's move it to there. I think that's about where it was. We can obviously adjust it as we play the game, but I think that's pretty good for now. Then actually, once I've oriented this, I'm going to go back and I'm going to change this to world space. In other words, it's not going to move with the camera. Once I've positioned it perfectly, that should actually work perfectly. And now we have this UI which is not going to move with the rest of the world. So if we now hit play, and we see if that does work, this UI is going to stay exactly where it is. And as we move along, it doesn't follow us, which is perfect. Obviously, this UI is still here, which is a bit of an issue. Let's make this UI only get activated. The minute we land on this starting position over here, we're going to have a little animation just so it looks a little better. Let's go window animation. Go to my U over here and let's create two animations. Actually, let's go to assets animation. And the first one is going to be a fade in animation. Then the second animation we're going to have is going to be what we're just going to call a static animation. And that's just going to say, okay, keep the positions exactly where they are. Let's set hearts to this position over here, 498.5 And let's set diamond to this position over here, 52.94 59.8 sorry. Um, and these should now states, now if we play as animation, it works. Let's see how my faded animation works. I want this to go from here over there about 2 seconds. I want it to fade into there to where it was, which is position 400. And what was the position? I think it was 459. Let's go to our other animation just to see it. 502.9 for the diamonds, and then 459.8 for these. Let's copy these hearts position. Go back over here, and then over here. At this point I want the hearts to be at that position. Let's change it to 459.8 And then I want to do the pretty much the exact same thing, with the diamond going to go from here. Then 2 seconds later, I want it to be at the other position, which let's go get 52.9 over here. At this point, I want the diamonds to be there as well. See, now they're going to fade in like this, and then the game is going to start. All we need to do, need to, right? Oh, let's also have one more animation where they're out of view. Let's create a new one and we'll call it out of view. That's actually just going to be when these two are kind of off screen. It doesn't really matter where they are as long asy're hit. And we could also have them kind of be actually deactivated. But I'm just going to do it like this for now because it makes it a little easier since we're only changing their positions. This is actually going to be the default animation. We're going to start with this or out of view things. Let's open up the UI. Let's set this to the default state. Then we want to make sure that the minute we faded in, we go right to statics. Let's go make transition over here. This is going to introduce us to a new concept which is like automatic transitions. We're going to set these both to zero, but then we're going to keep, this, has exit time changed. This means the minute this is done, change to static and exit time of zero means it's going to complete the animation and then move here. Which is going to look pretty cool. Now all we need to do is have a trigger which is a new type of parameter as well. It's very similar to a Boolean. Think of it like a button instead of a lever. We're just going to call it start. We're going to go over here and we're going to make this transition condition. Start this to zero, make sure it doesn't have extra time and the transition duration to zero as well. This is basically going to work that the minute we click this over here, it's going to fade in and then stay there. This is all we need to code to make sure that our UI doesn't start when we start the game. Now we need to add in one more parameter over here to our start game code. Going to create a public animator, which is going to be our anum. Then let's just go underneath here and say I an set trigger, I think we called it start. Now these three things together are basically going to allow us to start the game manually from that event. And this one over here is going to make it so that we make sure our UI only starts when we start the game. Let's go back into my starting script. Over here, boundary, it was here. Let's drag in that UI animator and see if everything works just like we needed to. Let's play, and let's see. We start with the UI out of screen, exactly like one or two. We start with the score of one, nothing else. In the minute I start this game, we can see my UI fade in. And that actually looks really, really cool. Now I can start playing my game just like normal. That is the last big change when you make to our games need to still add audio and sound. I know I say that pretty much every single episode, but I think this is a pretty cool change we've made to our game so far. And we've made it so that it looks a lot nicer, especially with the extra visuals. And now with all this other stuff. And now we've also got to start in hubs. So if we die and we lose the game, we see everything go away, then we're going to start over and we start again, just like where we were with a new high score because we got a lot more dimes that time, which is really, really cool. So that's everything for this episode. We're going to obviously add in our audio and music next episode, and then we should make a few final touches and we're done with our game. So you're almost actually completed with this entire course, which is really great and great job if you've been able to follow along everything so far and your game is looking like mine. If you've got a few things that are different, maybe just go back and watch a few videos and download the resources to see where yours are different from mine. Because you should be able to build my exact game pretty much using the files and recess that I provide under all the videos. So just make sure that you have everything the same. And I've even attached my code in case you want to check that as well. So hopefully you've got your game in the exact same state that mine is now. And you've been able to follow along everything in this video. Great job in making it this far. And we're going to get started adding audio and music in the next episode. Thanks. 17. Lesson 16 - Adding sound effects and music: Hey there, and welcome back to Unity. Now the time has come for our game to finally add an audio, because even though we've done pretty much everything else, our game is still entirely silent. Adding an audio is just one of the other things that makes your game feel a lot more responsive and alive to the player. To add an audio, we're going to follow a pretty simple process. We're first going to create a new object called an Audio Manager, and this where we're going to keep track of all the central audio, things like whether audio is enabled or disabled, and what to play when. Then we're going to edit all of our scripts and we're going to say play a sound at this point. To start, let's create a new object, call it Audio Manager. I'm just going to set it to zero for no reason other than preference. Then I'm going to create a new script and I'm going to give it the same name audio manager. Then inside my audio manager script, I'm going to have a reference to every single audio source, which is where we're going to play audio from in the game. And then going to have different voids for each one that's going to say play this, play this, play this, et cetera. I'm actually going to simplify it. I'm going to have one void and I'm going to say play the sound. But I'm getting ahead of myself. Let me first just write a public audio source. I'm going to have to create one of these for every single audio file that I have. Now, before I create this, let me first actually import my audio files. I'll go and create a new folder, call it audio, and then inside this, I'm going to want to put every single one of, I think there are seven audio files I have so far. So let's go ahead and import all of those. I've got all of them here and I'm going to leave all of these settings for now. These are basically just a whole bunch of audio files. This is for collecting diamonds, this is for the batteries. Make a Zap. Sound This can be a game of a sound. This is take damage, Sound, a jump, the music of the game, and then also sound effects for the robot. I'll get into all of that now, but for the time being, let me just add an audio source, or actually I'm going to add seven audio sources to this audio manager script, and then I'm going to create a reference to everyone. So let me go ahead and type in audio source. I'm going to add seven of these, seven right here. And the miner I've done that, I'm going to now get started with basically mixing my audio. So let me go ahead and disable all of these. And these are all different sounds and some of them are a lot louder than I want them to be. Now, due to the recording software that I'm using, you may not be able to hear the audio from my game coming directly through the video. If that is the case, then you just want to obviously follow along the process. View will be exactly the same and you just want to adjust the volume of each audio clip as you added into your game. So let me first start with the music. I'm going to drag the clip into this audio clip property. I'm going to set play a wake true and loop true for the music. And now I just want to change this volume. I can tell already one is going to be way too loud, so let me try 0.2 at first and see how I need to adjust it. I think 0.1 is slightly nicer, just so it's more like background music. Let's maybe set 0.15 is probably a good in between then I'm going to do the exact same thing with every single other one of these. I'm, instead of changing it, I'm just going to mute the one above it and then make the jump sound play on a wake and loop. So I can get a good volume for that as well. Obviously, that's a little too loud. Let's make it 0.20 0.2 is still too loud. 0.10 0.05 I think 0.1 is probably probably a good in between. Let's make it 0.1 I'm just going to repeat this process on and on until we've done this every single thing. Then I'm going to basically disable all of these ones, which I don't want to be set on awake if you've been following a long, hopefully have similar audios to me, I found these works. You can obviously adjust them for your game. I might change these as I go, but that's how I'm going to get all my audio mixed and then I'm just going to go ahead and uncheck Play on awake for pretty much every single one as well as mute and loop because I don't want any of these looping or playing on a wake. Really same thing with the hit, like that I don't want the game over either to be any of these things, nor the robot. And then I'm going to set the same thing for jump over here, which we're going to set off as well. The music, I'm going to keep playing awake and loop on just because you do want to obviously play the music when it's on. Now, before I go any further, I'm going to get started with adding in a mute and a sound off bun. Which is going to basically program these to say, okay, disable all of those and save all of those. The way I going to do that is I'm going to create a public audio source array. This is going to be the sound effect to create another public audio source. And this one is going to be for the music. Then I'm going to create a few voids. The first void is going to be a mute music void, which is going to set Music mute. Equal to true. I could actually create another void over here that says unmute. Music But I'm actually combine them into one void. I'm going to call it un, mute. Mute. Music It's going to have a bullion over here, which is going to be called muted. It's originally going to be set to false. Then I'm just going to set muted equal to muted. In other words, change whatever muted was. And I'm going to set this over here to muted as well. Not muted. The first time I click this, it's going to say, okay, muted is false. Set mute to not muted, which is true. And then set muted equal to not muted, muted is false. Therefore, set muted at true. Then the second time, it's going to say set muted to not muted, muted, it's not true. So it's going to set to false. Basically, this is going to alternate there every time we call it. I'm going to write the exact same void for the sound effects, mute, mute sound effects. We're going to write for each audio source AS I have to type it like this, because as is a reserved word in SFX. Other words, every single audio source we're going to assign to this object S, S is first, can be the first one, then the second one for every single one in here. This is what's known as a four loop. It's actually a for each loop, but you can think of them as like repeating code O. This is saying for every single S it's written for us a little bit, but just think of it like for every single audio source inside this thing. Set the mute value of it equal to not whatever my muted is. For SX, this is muted. Music This is going to be muted SFX. Let me change that quickly then. Just copy this over here, over here. I'm going to say muted FX. In other words, update every single thing, so it's the same. Then set muted SFX to whatever it wasn't before. In other words, alternated This code over here is going to allow us to enable or disable every single audio source we have in our game. Now we need to write codes for playing the specific audio sources, But I'm going to combine that into one void. I'm going to call it public void, call it play. Sound As an input, we're going to basically input an audio source. We're going to input audio source AS the entire void is going to be as play. In other words, we're going to play an audio source that we are choosing from here. Then I'm going to call this void. I'm going to create a reference to this audio manager script in a bunch of other scripts where I need to call voids. Call this void specifically and I'm going to pass in the sound that I want. Let's get started with filling in all the sounds. First of all, we've got our game over Sound as well as our damage sounds. Let's go over to Player Health. Let's create a reference to my audio manager. Let's call it AM. Then over here inside my take damage void over here I'm going to write AM Fx. Now I need to choose whatever index I'm going to have. Let me start actually assigning the indexes on this. Before I do the rest of this over here, let's go ahead and drag my audio manager script to the bottom here. I just make all of these minimized because I don't need to edit the settings anymore. Now I'm going to have Music This source up here and all the other sources. There should be six other sources I'm just going to drag in like this. And you can see it's actually giving us a bit of an issue. Now we have these ones that's not here. So I'm just going to delete those right clicking and saying delete Array Element. And then I've got my six audio sources and then jump, then robot, then game over. Then hit, then electrical, and then diamond collect the one that I want to refer to here. Hit is the fourth one. It's element three over here. And you can see that over here, this is element three. Hit. Let's go back to my code and let's say Am element three. And I'm going to pass that into AM, Play Sound. Let's go ahead, go like that. This is basically going to say, okay, play a sound and play whatever audio source you have stored in. The third thing, which is the one we just made, I'm going to repeat this process pretty much wherever we have a sound we want to play, let's go to the Death. In the death one we want to play the game over. Sound Which is, so believe it's the second last one. It's actually, it's the third one I think. Yeah, it's the third one, which is element two. Let's go over here and let's play element two here. Now we've got two of them sorted. We still need to add in the jump sounds. Let's go to the movement script. I believe it's over here. Player movement. We're going to create another reference to my audio manager, call it AM. Let's go over here to my jump void and say AM Play. Sound And we now have to find the jump sound. I honestly can't remember because haven't been memorizing these. But I want to say it's the first. Yeah, it's the first one. Let's go over here and let's play the very first sound. Now, we've done three of them. There's only three more to go. We obviously need the sound for the electricity, as well as the sound for the robot. And we need the sound for the Diamond Collection. Let's go to the Diamond collection, One first. We're going to have to on this event over here play the sounds. Let's get public audio manager AM underneath the particle system. Let's go AM to play Sound. I believe Diamond Collect is the very last sound. Let's just confirm. Yeah it is. That's element five over here. Let's go there and play the last one. Now we've got two more sounds. We've got the robot Sound, which we need to play whenever there's a robot on screens that's a little bit different. This is actually going to be a little more tricky. So I'm going to change what I'm doing here. Instead of having this sound be a part of the array that I'm going to necessarily focus on, I'm going to have the sound play in awake and be looped. But instead, I'm going to have it muted. And then whenever I have a robot spawning in, I'm just going to make sure that I set this thing so that it is muted. And every time I have a robot that dies, I'm going to set it so it's no longer muted. This is going to work for the most part they might give us if there's a robot that spawns and then dies while another one still on screen, It might be one robot without Sound, but for our time being, it's going to be a pretty much perfectly fine solution. Let's go over here to my void over here. Let's see in my script, when I start as a robot, I'm going to want to set my audio source, which I'm going to create a reference to the audio manager. Again, M over here, I'm just going to say AM of X. I'm going to refer to it is the first element. I believe it's secondly the second one, but it's element one in the array. Mute equals false. In other words, play the robot. Sound Then the minute this robot dies, the minute it no longer exists on screen, we're going to want to set that mute to true again. The way they're going to do this is actually by editing the script which is above the, which tells what to delete. We're going to go into that script over here which is called Tile clear. This is the script that is going to destroy the tiles. The minute there. I'm going to add a new variable, call it robot, on board. And it's going to be of type bullion. Then over here when I destroy my game object, I'm just going to add another line right underneath. And I'm going to say if a robot was on board, then I want to make sure that my audio manager is no longer playing a sound. I'm not going to create a reference like I don't know here. I'm going to use Game Object Find Audio Manager because that's going to be a lot easier for a pre fab Get component. Then I'm going to find an audio manager script attached to it. I'm going to say X, attach the element two or was it element one? I believe it might have been element one. Actually, yeah, it was mute equals true. All I need to do in this robot script of here is the minute I mute it, I need to attach, go to my parent objects and transform parent. Then I'm going to say get component tile clear and I'm going to say robot on board equals true. This might be a bit of a weird way to do it, honestly, if you really don't want to add in this robot Sound, it's not the end of the world. Basically what I'm doing is, I'm just saying, okay, this specific element of the array it doesn't actually need in the array. I'm just keeping it there kind of for keepsakes. And I'm saying, okay, mute. It set the mute to false the minute I spawn in and make sure I tell my tile that there's a robot on here, and the minute my tile then gets destroyed, if there was a robot on there, it has to make sure that this mute is set to true. We could also actually just set it to true every time we destroy a tile that wouldn't work anywhere near as well, because then any tile would mute. The robots here don't exist for a momentary time. So this is going to hopefully survive for most of the robots lifespan. And it's going to work just fine for now. If we go back to my audio manager, I've already programmed in my music script and I've got the jump done, I've done the robot now, done the game over, and I've done the hit as well as, But the electricity. Sound I've done the diamond as well. Let's go to the electricity Sound Which is going to be in the battery script over here. Let's find my battery script, it's actually in Unity store, it hasn't been opened. Then are going to do this battery void over here. We're going to have a reference to my audio manager. Again, I'm going to have to assign this one via code as well because it's going to be a prefabs. I'm going to say M equals game object dot find audio manager get component. Now I'm going to find an audio manager script on that. I'm going to make sure I've assigned that correctly. And then all I'm going to do is I'm going to say this code just like I've said on all the other ones, like Player Health over here, it's here AM. Play Sound And then I'm going to choose an array element. I'm going to play the sound when the battery turns on. I believe it's the fifth sound. Let me just check to be safe it let's play element five. Now the way this is going to work is now we've created our audio manager, which has every single sound stored in it, as well as the script, which is hopefully going to allow us to mute the music and not And we haven't programmed that in yet. But we're going to add that the minute we've got all the sounds working. Then hopefully we've been able to call every single sound appropriately from every script, so that we are able to play the sounds when we need them. Let's remember all the sounds we first did Music Which didn't have any programming. The jump was referenced in the players Sound Let's make sure we assign the audio manager over here. Just like that. Let's go back, let's see what else we've already done. The robot is going to be assigned by the robot. And actually just realize that we haven't created a reference to this audio manager script in Start. Which we probably should do because this is another prefab. So let's write the exact same code we wrote for the battery inside this other prefab. The reason why we're doing this for prefabs is because generally when we have objects, we can say, okay, put this in this object, but because these objects haven't been created yet, these are like robots and enemies. We have to write in code to do it for us, because we're not there to drag it in them and at the game starts. So that's why four, a few of these, we've had to write this code over here. Anyway, that should be the code we need to assign the robot. So let's see what else we have. The robot is done, the jump is done, game over and hit are both going to be on player health which are assigned now. As well as diamond collects is going to be on diamonds. And I think diamonds, I can't remember if we remember to assign it via code, but I don't think we did. So let's do the exact same thing we've done there. Just make sure we assign it via code. We did do that for the battery as well. That means the last one we have is just for the player taking damage and dying. So let's go to Audio Manager, go to Player and make sure that we assign the player health script to be this audio manager script over here. Now let's go ahead and hit Player. There might be some issues, but we're going to fix them along the way. But hopefully we've done everything so we don't have any bugs. And we can hear the music and let's hit play and see if everything works. It looks like jumping works. We have our audio, we have the jumping sound. We're going to test every single one, Obviously, I'm actually going to go ahead and mute the music just so I can hear everything else. It doesn't look like my heart Sound seems to be working my battery. Sound Doesn't seem to be. But let's test. Heart is obviously working my jump, My game over seems to be, which is great. That's actually most of them. Let's see what ones are remaining. Going to go ahead and mute the music again, the jump sounds working. I have to test the robot and the gameover is working. Hits working. I have to test the electricity. Doesn't seem to be working. Diamond collector, I haven't tested yet. And the robot I don't think is working either. Let's just go ahead. We've got an error here that says object reference not set to instance of an object. Yeah, it seems like our code isn't working exactly. And I think the reason is over here we've sort audio manager wrong. Let's just go ahead and fix that. We put a space there where it shouldn't have been. We have to go I think we wrote this in these three lines of code over here and we also wrote it in tile clear. Let's make sure we are we got to right that time. Right. Let's go ahead and try that again. I see all of those errors were trying to play sounds but they couldn't because they couldn't find an audio manager object with a space which makes complete sense. Let's try again. I'm going to turn the jump down just a bit because it is quite loud. Let's try that again. I'm going to mute the music again so I can hear everything. Let's see, Jumping seems to be working. We've got a diamond. It seems like the diamond Sound is playing here. At least something's playing, but we've got the wrong sound playing. Let's just test. We made any other mistakes. The diamond Sound is playing when we collect a diamond as well. Interesting that probably actually we assigned it in the array wrong, but let's go ahead and try that. The robot Sound is also working, which is great. Let's go back to my array. Let's go over here. Electricity Sound Should be the fifth one. Let's go ahead and drag that in and just see because I don't think it was assigned properly, that was probably the issue. Let's just go to my battery and check if we're calling the right thing and we're calling element five, we are actually calling the wrong ones. Let's change that to four. We got one more error over here which said object reference not set to instance of an object and it says script robot moves. Let's go ahead and see what exactly the issue is here, finding an audio manager and we should be able to get this code working as well. It looks like the issue might be over here with this get component tile clear. Obviously all of our tiles should have that script over there which make sure they delete themselves once they reach certain height. I made a new few new tiles. At some point I might have gone to add them on. Let's just make sure it's not on all of my tiles. Let's just check which ones don't have it. Those all do, Those all do that one does, that one doesn't. So these two don't have tile clear. Go ahead and add that to them. We don't have to set anything, obviously. And then to the rest of them. Yeah, they do, It's just those two. Now, if we go back into the game, everything should be working pretty much fine and all of our sounds and everything should be great. Just go ahead and hit play and see if it all does work perfect. So we've got my music playing. The minute I start playing everything hoops in, Looks, I've sounds working as well. Seem to have a bit of a glitch where two have spawn on top of each other entirely. Sure what that is. But it looks cool. Whoops. You can hear everything going on, You can hear the zapping, and you can hear the robot ever so slyly. Obviously, if you die, we have that all starting again, which is really cool. That is pretty much all the audio setup we need to do for our game. The very last thing is we need to now add in something that allows us to mute the audio and the sound, because we coded that right at the beginning. Let's go into my UI. I'm going to go to this UI over here. This Camas I made, I'm going to create a button. I'm going to have two buttons. Let's go legacy. I don't need button with Text me. I'm just going to move this down over here. And I'm going to delete the text component and just rename this to Fx and rename the one underneath it to Music. I'm going to put them about there. I think I want on my cloud to be able to mute the music like so. Obviously going to use actual sprites here. I'll set these positions. Negative 4.445 negative 445, cool. Then let's go into my sprites and let's get these two sprites which I made specifically for the following. Music And I think the other one was called Sound. There it is. Let's import those two. Make sure we have both selected and do the normal thing that we do when we add a new sprites. Let's just go over here into the source image and make sure to the X one we drag in our sound sprite like so click set native size. Then we're going to have to scale this according to the rest of the game. But before we do that, let's add pixels. Let's add Music So we can do the same at the same time. Then let's just see how we need to change this. That is obviously one pixel. It needs to be a, it's a little big scale down. Again, that should be fine. Perfect. I think that's good enough. Maybe a time it's smaller. Yeah. Now we need to do is we need to go back into the scheme over here. Let's just make sure that we have an event system because that's what we need for these buttons to work. Let's go ahead and drag that one up here, and this one down here, until they're looking like that, maybe a little bit to the side. I'm actually going to want both of them at the bottom. I think like this. Let's go ahead to music and move it. We have our buttons there. I'm actually going to move both of them a little bit up as well. I think that looks all right for now. Now all I need to do is I need to make sure that that code that I made runs when I do these buttons. So let's go ahead select them. And then on click I'm going to drag in this audio manager object and I'm going to choose Audio Manager mute S of X. And then for music, I'm going to change that to mute mute Music. Let's see if these work. What should happen is actually the last thing I'm going to do before I'm done with that is I'm going to go back to audio Manager. I'm just going to make a reference to these two buttons. Let's go using Unity Engine. Let's create a reference to my two buttons, Public button X and the other one is music with a capital. This time then all I'm going to do is I'm going to say, okay, if I'm actually going to create a couple of colors, I'm going to create one color called Grade out. All I'm going to do is I'm going to say, okay, if you have now muted the music, then gray out Music You can see the change. Let's go ahead over here and let's say if muted Music In other words, if we've now muted mic muted will be set to true the minute Music In other words, if we've muted it, let's set my music image color equal to grade. Then underneath that I'm going to write L. Music Image color is equal to color white. I'm to write pretty much the exact same code underneath the sound effects over here. Say if muted X, then X dot image dot color is gray. Otherwise set it to white. Let's go back into my game then. Underneath my audio manager script over here, I just need to create a reference to these two. Let's drag X in there and let's drag music like let's make the create color something like this. And see if we can see that in action as we play the game. Let's go ahead and hit Play. And just test out these two buttons, see if they work. It looks like it does. I'll see if we click the sound thing. We shouldn't have any sounds at all. So let's go ahead and mute both while I'm talking, just to test if anything is not working. It seems like robot is still an issue. And the reason for that is because we're actually unmuting this manually. What I'm going to do instead is I'm going to say set the volume instead of muted. And then set the volume back. Which is actually quite cool. I didn't actually think of that. But let's just quickly make that change. Instead of saying mute is false, I'm going to say do volume is equal to. And then what is the volume which I want my robot to normally be, it's usually at 0.01 So I'm going to set the volume to 0.01 Just put an after that. That's what you need to do. Then what's going to be dictated when that's off again, is when I have, my tile gets cleared. So let's set. Instead of saying mute, I'll say volume is equal to zero. Then actually the last change you need to make after doing this is need to go back into my game. I need to go to this script over here. And I need to actually set that to zero at the beginning of the game. And not muted just like that. Now when I play my game, I shouldn't have any robot noises. When I start, if I mute both sound and audio, that should not be a problem I have anymore where we can test. Actually, this should still be going up to 0.01 when I play it, because it's muted when I hear it. We should have a robot on screen now, which is perfect. You can see it is actually working. Then the minute this robot actually gets destroyed by the cloud, See no sound effects playing. Nothing is playing, which is exactly what we want. The minute this robot actually gets destroyed, we should have this drop back to zero, which it looks like it just did. Which is great. That's actually all of the sound we need done for our game. And now you can obviously change that whenever you spawn into the game. You can select that whether you want it on or off. It will be on by default obviously. But then you can just turn it off on whether you want it, which is pretty cool. That's actually the last thing. Now, to make our game complete, the last thing now we need is final touches. But after that, we've pretty much finished our game, which is really, really cool. Obviously, like I said in the next video, we're is going to be adding up some final touches to make everything look a little better. But we've pretty much done, so if you follow along and you've got a game that looks like this, that's really, really cool. Because obviously this is quite an impressive game to make if you've never really used Unity that much before. So good job on following along. And hopefully your game you're quite impressed with and quite proud of it at the moment. And like I mentioned in the next video, we are going to be covering just some final touches to make our game look a little better. But hopefully, like I said, you're happy with how it is so far and everything is working well on your game as well, just like it is on mine. We'll be wrapping up this course over the next two videos and the next one, we're just going to be adding some final touches. And then I'll show you how to build and export this game and conclude this course. Thanks. 18. Lesson 17 - Final touches: Hey there, and welcome back to Unity for the last actual lesson where we're going to be developing this game. Now in this lesson, we're going to be adding in just some final touches. We're going to be adding two things. First of all, we're going to be making the camera speed up over time. Then we're also going to be adding in post processing, which is like full screen visual effects, which just make the game look a little bit better. It's quite hard to explain, but you'll see once we've added it in, starting with the original thing, before I do that, I'm just going to actually enable this curtain because I disabled it quite a few episodes ago and before I forget about it, when I try and actually build my game, I think it's look a lot cooler with that fade in. Let's go ahead and just see if that all works. So we have our fade in and our audio and sound is working just like it was before obviously. Let's get started with that. Camera speed up. I'm going to go to scripts and I'm going to create a new one. I'm going to call it camera speed up, the way the script is actually going to work. There's quite a few ways you can go about this, but the way I'm going to choose is going to give the player quite a lot of control over the camera speed at certain points. I'm going to have a variable over here called time elapsed. Every single frame I'm going to increment time elapsed by time delta time. In other words, time elapsed is going to increase, is basically going to be a counter. And if we go ahead and put this on an object, I'm going to put it on the main camera, for instance. Let's go ahead and add in my script over here which was called camera speed up, right to the bottom. There you go. Anyway, if we just watch that time elapse variable, I'm going to mute the music so I can speak while it's playing. Let's scroll down and let's just see over here we have this value counting up and up and up. We have an error right at the beginning which says value cannot be null, which I'm guessing is referring to that time elapsed because we haven't initialized it yet, which I'm going to get to in a minute. But basically it's just a timer. I just want to show you what it is. Let's originally start by setting this to zero, and it's now a timer. What we're going to do every single frame is we're going to say if time elapsed is greater than a value, which we're going to have basically mean step up a level, then we're going to step up the level of that. Camera speeds, we're going to have an array up top here. Public float array, It's going to be camera speeds. Then we're going to have an array next to it, which is going to be times. What we're going to basically say is the minute I'm greater than a time, then you have to up this camera speed by that amount. This time variable we're going to store in another float called current time. The minute we start the game, the minute this starts, we're going to set current time equal to the very first time on our time. It's going to be times zero. Obviously, camera speed is going to be set to zero as well. We're going to need to create a reference to my camera speed over here. Let's go public camera, move, call it camera speed. Camera script rather. Then we're going to say camera script. Camera speed is equal to camera speeds zero. This is going to allow us to do is we're basically going to allow us to change the speed of the camera. This actually makes that change we made earlier where we separated the camera speed and its current speed, a really useful one because now we can change the speed without worrying how fast the camera is actually moving. This is just how fast it should be moving, right? But it doesn't mean it's going to start moving if certain time elapses while we're dead or anything like that. Which is really, really cool right now. We have a script up here that says set the current time to zero and set the camera script to this camera speed because we're using the same variable over here. I'm actually going to set this to another variable, call it index. At the start, we're going to set index equal to zero, and we're just going to set this equal to index. And then every single time we have time elapse, we're going to increment time elapse. And we're going to say if time elapsed is greater than times of index plus one. In other words, if we've moved up, if we've now passed enough time to go to the next level, then the first thing we're going to do is we're going to increment index. We're going to index plus, plus, in other words, increase it by one. Then we're going to say underneath this, actually before this. Rather we're going to say camera script, camera speed is equal to camera speed index. And we're actually going to move that below. Basically what we're going to do is we're going to increment camera speeds by that amount. Well, this is going to allow to do the way this code is going to work, like I've explained. We're going to have a time lapse area which is going to count up from zero. We're going to have a list of camera speeds and a list of respective times. And we're going to have a current time and a camera speed and a current index. This current time variable we don't actually need. I don't know why I created it, I can actually remove both of these over here. Basically, all we need to do is we need to have this float over here that says time elapsed, camera speeds, times, as well as a reference to the script and an index at the start index is set to zero. We set our camera speed to the original one. Then as long as the time elapsed is greater than whatever, the index is greater than one. Obviously, the minute we run out of a raise is going to give error. I'm going ad a little code erneath it that says As long as we're not at the maximum index and the minute we're at the maximum index, I'm actually just going to destroy the script entirely. But until then I'm going to increment my thing every single time we have time elapsed is actually greater than the one that's next. They're going to increase index and then I'm going to set the camera speed to whatever that is over here underneath this. I'm going to say if index is equal to camera speeds, length, in other words, if we've reached the maximum, index will work as long as it's one less. But the minute it's one more, in other words we're at the maximum thing, I'm going to delete this script off. It's not going to be an issue because when we reload the scene, it'll be back there. But basically just for the time being because I don't need anymore, I'll say destroy game object dot get component camera speed up. Or rather instead of destroyer, I'll say game object dot get component camera speed up enabled. Because I think destroy might actually get rid of the game object itself equals false. Basically the minute I run out of stuff, just disable myself. And obviously they'll be reenabled when we start the scene. But this should actually work pretty well in terms of telling us how fast the camera speed should be. Let's go to main camera, score it onto the bottom, and let's set my camera speeds. I'm going to set initially four I'm going to set. This obviously has to be the same length, say after 2 seconds passed, after 4 seconds, after 6 seconds, after 8 seconds, I'm going to make it 123.4 So we'll be able to basically see everything. They're going to pick my camera move script. I'm going to go ahead and hit play. And let's see exactly how this works. We now no longer actually need this camera variable. We've got over here camera speed to be assigned of there. This is not going to make a difference. Let's go ahead and just re zero. That doesn't really matter. Then let's go ahead and hit play. And before we actually hit play, I just realized that we're going to be assigned the camera speed before anything actually starts. We only want this void to be called when we actually start the game. Let's go public void begin. And it's going to actually be called by that start manager script we made a while ago. Let's go back here and let's create a public camera speed up speed. Let's go over here here and say cam speed begin. Otherwise the camera is going to start moving before we start the game. Let's go back here. Let's go to my starting script over here to the boundary. Let's make sure we add my camera speed up script there. Let's see if it works. Now what should happen is we should have 4 seconds, the first second, or rather 8 seconds, and four different speeds depending on how long we're playing the T, we start the game, we should still have the camera move at all, which is hopefully what is going to happen. Great, I'm going to mute this so I can explain. Then the minute I start move past, I'm moving at one, 2 seconds past. Then I should be moving at two. It looks like it says index is outside the bounds, the ray. Let's just look at what the issue is. Apparently, the index is outside the boundary ray, which means we're trying to reference something which doesn't exist here. Let's just look at how we've coded this over here. This is actually meant to be, is equal to camera length minus one. The index is actually one less than the camera length if the camera length is three. When the index is two, there's not going to be any third element over here. This needs to be minus one. Actually, I just realized that we also, I don't think have anywhere coded the fact that the camera script should actually be the speed that we've programmed over here. We're going to assume that the minute we begin it's going to sign it fine. But every single time we do this, we want to be making sure that we're elapsing, we're making sure that the camera speed is actually what the maximum camera speed should be. Do that we do actually have to take in the death into account. Let's create a reference to my public player health, call it Player. Then let's just go over here and we'll say all of this code over here is only going to run if the player is not dead equals false. Let's go back over here. And then let's go to my camera speed and say camera script speed is equal to camera script camera speed. This should actually have everything working perfectly fine. Now we're going to test again, obviously because you run into bugs like this every single time you're developing a game. Obviously, we've now hopefully fixed everything. Let's go back. Let's just see, the way we've coded this actually takes into account that we don't need a time here because we're never really referring to this time. We're only referring to as long as this many seconds are passed. So let's go ahead and actually make one more change. Before we do that, we only want to factor in time, elapse the minute the game has actually started playing. Let's go ahead and say, if we need another bullion, call it begun. Let's say if begun, in other words, if we're actually playing the game that begun is only going to be set true over here. Let's go ahead and take a look at the new code. There were quite few errors actually here that we need to fix, but they should all be done. Now let's go back into our game. Let's look at all of the different things we've got over here in our new script. We should have this time lapse zero until the game starts. And then we should be able to see the camera speed up. I almost forgot to assign player health. Let's go back here and assign this to my player, the double click or rather single click. Let's see if everything works right now. Begun is set to false, just like it should be. Let's disable the. Sound. Let's see if we don't have time elapse the minute we walk through. Time starts counting. Perfect, we currently have 1 minute, 4 seconds have passed. We should speed up now to two. It doesn't look like we're speeding up again. Let's just go back to script. Camera speed is currently set to one. Now camera speed isn't updating, maybe the dead variable is the problem. Let's go ahead and see because I don't think our index is actually updating. Yeah, it's not. Our index is sticking at zero. Let's go back and see if we can fix it. Third time is the charm. I think dead actually is not all. Yeah, is dead is the bullion. Let's go ahead and change that is dead. That is actually I think a sprite. Yeah, that's clearly why it wasn't working. Now if we go back into my game over here, we should be able to see the camera speed up as we go along. Let's go ahead and hit play to test If it does actually work. We should be starting with time elapsed of zero. The time shouldn't actually count down until we start playing, which looks like what we have. Let's go ahead and run into the game. And now we start off with a speed of one. And it looks like that is going to stay at one, maybe it's own out increase two, not increase three, and out increase to four. Obviously we can see the game speed up quite drastically, which is pretty cool. As we speed up the camera, these things get further and further apart. Actually, they don't get further apart, but they do get more frequent. But hopefully this makes the game look a little more scalable. Obviously, it's quite a fair bit harder to keep up with the camera, and if you don't, then you obviously die. What you're going to actually need to do is edit kind of what you want these to be. I'm going to set it 1.8 at the beginning, just like we had it. Then I think I want to set to 2.2 0.4 Then I'm basically going to actually increment this quite a lot. I'm going to make ten of them say from 2.4 we can go to 2.6 and then 2.62 0.82 0.83 and then we're going to go 3.23 point, 4.3 0.6 And I think that it should be at maximum 3.6 after you've been playing for a fair while. So let's set the time elapsed. It should only change from this after about 20 seconds, 30 seconds, 40 seconds, 50 seconds. And I'm going to say that you reach max speed after playing for about 100 seconds. And I mean, you don't have to use these exact values. These just can be the ones I'm going to use, But I think they should work quite well for how we've played the game so far. So let's see if this actually does work and feels natural for the beginning. At the very least, let's disable the sound. Just see we've got that same kind of speed we always got used to. And then 20 seconds time we should have the speed increasing and increasing, which is cool. So that's the first kind of step we need to do to the final cush we need to make to our game. The second thing is postpcing. Hopefully, luckily, it's a lot less kind of coding and a lot easier. Let's first start by creating a post processing object. And we're going to go Window Package Manager right now. We're going to find this postpcing package. What you need to do is you need to go into packages you might have in project set. So let's go to the Unity registry and find this post processing object. Then you're going to click Install. This is going to install this stack or package into your project. It's going to say installing. It might take a while, depending on how fast your computer and or Wi Fi is. But after that it's done installing. You can see you'll have this pop up over here, then everything should load in. Now what this postpsing stack allows to, I'm actually going to get rid of the curtain in the editor. We're using this button. It's not going to affect the game, which is cool. I should have done that earlier. But anyway, what this is actually going to allow us to do is basically add in visual effects to our games. Let's first go to this postpsing object we've got over here. The first thing we need to do is go to my camera and I need to add a post processing layer. Let's type posts, we can see if you've got all these new things. It might take a while to load them all in, but we've got a debug which we're not going to concern ourselves with. We've got a layer, we've got a volume. Just wait for that to reload. And then let's go back down here and add a layer to the camera. Now you can leave pretty much all of these settings as they are, except you obviously need to choose a layer to be affected by postpsing, which is like our special effects. I'm going to go overhead and make a new layer, that's a tag. I'm going to make a new layer, I'm going to call it post process. Go to my postpsing and make sure it's on that layer. I'm going to go to my main camera and I'm going to set my main camera to be that post processing layer which should have everything working. I'm going to leave the rest as they are for now. Now I'm going to go to my post processing object over here and I'm going to add a post processing volume. This is going to allow me to basically edit my game. I'm actually going to disable this now so I can see it, because you can only see postprocessing in the game. I'm going to be able to add a whole bunch of really cool special effects, you can play around with these. I'm not the greatest at using this, to be honest. This is basically editing its core. You're going to have a whole bunch of different settings and obviously, the better you are at photo editing and postpsing editing, I guess video editing, all of that thing is going to tie to this. I've gotten a few tricks that I use for my games, but I'm not the most experienced in this. Anyway, it's quite easy to learn, just like the particle systems, you need to start by creating a new profile. Then you can start adding effect. Let's go Unity and let's add in bloom. This is the favorite effect of most people. Now, before we're going to be able to see the effect of this, we're going to have to check, this is global box. Then you can see as you're going to scale up the intensity of the bloom. You can see the game becomes bright, obviously, we don't want it to be like that. But you can see if you have something like zero or you have something like 0.30 0.5 even. It makes the game look just a little bit nicer. It might not be super easy to see in the video quality, but obviously as you go to 0.7 or 0.8 even, you can see the game come to life a little bit. I want to set mine 20.8 which is quite high, but I'm going to leave it there for now. I'm going to lower the threshold just a little bit or rather raise the threshold. You can see there as I increase the intensity, some things are affected, but I think that, that looks quite cool for now. Quite a high threshold. But then I'm also going to have a decently high Bloom. Let's actually set it to two, just to test if it is actually doing anything. You can click that on and off. My threshold might be a bit high, set at 1.2 You can see now you can see a slight difference. I'm going to leave it at that for now. I'm going to add a new effect. The next thing I'm going to add is going to be a vignette or a vinette. I'm not sure, This is just a blacking around the edges. So I'm going to add a tiny bit on the sides, like, so just to make my game slightly more framed. Then after that, I'm going to add in some color grading. This is an incredibly complicated one. I don't usually use this too much in my games, but I'm going to set the low definition range because it seems to be preferring that. Then I'm just going to go ahead and I can obviously change my temperature, which I'm not really going to do. Leave that as that for now. I might make it -0.1 just to see if it makes any difference at all. You can see a bit of a difference, but I'm going to make it 0.2 And then I can obviously add in a color filter if I were inclined. I don't really want to do that, to be honest. But if I wanted, I could add in some filter, may make a game a little bit darker if I were wanting to, but I'm going to leave that out for now. Then you can also change things like the brightness, obviously like I mentioned, you can. I'm going to make game one more bright and I am actually going to edit the contrast just a little bit of my game. Make it negative two or negative three. Just to make things a clearer negative five should be good. These are the three effects that I've used so far. There are actually a whole bunch here that you can use depending on what you want for your game. You could add in grain, for instance. Maybe you can see what that does. This is obviously not the effect I'm going for, but if you wanted to, you could. I guess very large grains might look cool depending on what style you're going for if you're making a retro game. But I'm not going to do anything other than what I've got so far. You should be able to see that take effect, you can see the difference. And just make the game look, in my opinion, just a little bit better. I'm actually going to up the bloom just slightly. I'm going to make my color grading slightly less. I don't really want my brightness to be as effective as it was. Um, I'm actually not sure the color grading is a good change at all. I might actually delete that entirely. But like I said, you can play around these as much as you want to. And you can see now if I go ahead and reenable my curtain and play my game, I can now see what is my finished Sky Miner game. And this is the intermediate platform that we've been making over the last few weeks or however long you've been taking the course rolling. We can see, obviously everything looks a little nicer now. And then when we jump in, things slide in. And we can see this game in full development completed, which is pretty cool, especially if this is one of the first games you've made in Unity. I seem to have died. This is one of the first games you've ever made in Unity. It's pretty impressive to have been able to make all of this. If you've made everything and it's all working just like minus, then that's really great and good job on being able to follow along just like this. In the next video, we're going to be building and exporting this game. And that is not really even a video. It's just me showing you how to build it to a project so you can play it properly. But for now, we've pretty much finished everything for this game. If you follow along and everything's working just like minus, I hope it is. And I hope you've been able to learn quite a lot as you've made this game. And maybe you can even morph it into a game that you want to release onto mobile or PC or something like that. But for now, great job on making it all the way through the course. And congratulations on making your game. Thanks. 19. Lesson 18 - Building and exporting: Hey there, and welcome back to Unity. Now we've pretty much finished. Well, actually we have entirely finished our sky miner intermedia platform game. Over the last while, we've spent countless hours or minutes, depending on how fast you were able to get through all the videos, building what we have in front of us, which is actually really, really cool, that we've been able to make a game like this in, presumably not actually that much time. Like I said in the last video, congratulations on making it this far. And if you've managed to make it to the end of the course like this and your game is working just like mine is working, then great job. And that is actually pretty impressive, especially if this is one of your first games you main Unity. But even if it isn't to made a game Unity, any game in general is an accolade in itself, but especially one with sprites and music and scaling, difficulty and random map generation. All of that is a pretty cool accomplishment. So well done. Now we still need to be able to build the game because we can't exactly be like, oh yeah, check out my game and then load up Unity every time we want to show it to someone. So we have to be able to export this game to a file so that we don't have to play it in the editor. That's going to be the purpose of this video. I'm just going to show you quickly how to export your game and play it in a massive full screen window. And then I'm going to conclude the course While I'm playing the game in the background, let's go ahead to the top here and click File Build Settings. And this is where you're going to edit the entire kind building aspect of the game. Now I'm not going to go too detail into every single one of these because if you click Play A Sets, you can see just how many there really are. There's all of these. There's preset management. Well actually not forget about that. There's icon which you can change here, there's resolution, there's a splash image, which is kind of played at the start of the game. Then there's a whole bunch of other settings which you really shouldn't fiddle around too much with, especially if you don't really know what you're doing. Because, well, they can break the game. But for now all we're actually going to do is leave these default. This is the platform over here which we're going to build for. If you want to change this to an Andro game, you actually just install the module and click switch platform. And it does a lot of stuff for you. But we're going to be building our game for a computer. We're not going to be worried with any of these players scenes for now. But you can obviously change all of these. These are going to be built into the application. So you can change your company name, the product name. I can change to Sky Miner if I wanted to. And I can change the icon, the cursor, and pretty much everything else here. Like I said, don't filter with these other settings too much unless you know what you're doing or have Googled it. But these ones over here, you can kind of make whatever you want. You can change the icon. You can change the resolution. And you can also change the splash image, which like I said, if we click Preview, we can see it actually. It's an image which Unity displays when you start a game like this, which I'm actually happy with. I think that's all good for now. So I'm going to leave those settings default and just actually get started with building my game. We build it for 64 bit and I'm going to click Build. Bill is going to open up File Explorer. I get to choose where to put my game. Now this is the folder where my entire project is, so I'm going to create a new folder inside this call it builds. And I'm going to double click on that and use this as a folder to build my game. And that's going to start this process full building my entire game. Now, this does take some time, especially depending on how fast your computer is. But just in general, this is quite an intensive process. Just wait this, it should take anywhere 1-2 minutes, depending on how big your project is. For me, it might not take too long because it's not a very big game. But depending like I said on your project and everything else and also all of our post pressing we've added, it might take a while to compile. Just sit here and don't touch too much on your computer because it is running quite a few processes right now. Now, after a while, mind took 65 seconds. You should have this file over here, which gets created with the name of your project. And this is actually the executable file which you can use to run your game if you go over here to build. If we double click this file, we actually are going to load up our game. Now before I do that, I just want to say a disclaimer that the first time you load the game, you might have some aspect ratio issues. For instance, actually, if I were to load this up now, I'm almost fairly certain I would let me just test it and see. Because this is the last thing we need to fix for our game. And sure enough, there you go. We've got a few things that aren't really exactly where they should be. Let's go into the game. And the way we're going to fix these is by choosing an aspect over here, 1920 by 1080. And I'm going to go ahead and get rid of my curtain just so I can see things. This is going to allow me to resize everything and move it, so it should be the exact orientation that I want it. I'm going to move these to the side like that. That should be good. I'm going to move this cloud over there. I actually think I might also need to actually increase the spawn in time for the beginning. I'm going to make this 20 instead. Now I need to obviously increase the size of these as well. The hearts and the diamonds are both now the wrong size pixel wise. Let's go ahead and scale those up a little bit. Let's just see where we've got them. Depending on your computer and how much you've followed, exactly what I've done. You may or may not have this issue, I just happen to your computer might not. It really depends. But like I said, if you go to the game and you change this setting over here, you can build the game four different resolutions. I'm building it for 1920 by 1080 at the moment. Let me just make sure I recite that correctly just to get like a general view. It's not even close. Let's recess it up a bit more. Let's see. I'd say that's pretty good. Let's go ahead and put this back where it was up at the top over here. Put this over here as well. And then let's go to my counter. Move it there and scale this up a bit as well. About that should be good. Now. We're obviously just going to have to obviously test our UI animations as well since we've moved them. So let's see how those look. Fade in, Yeah, it's obviously now the wrong positions, so we're just going to have to set the start positions out there and out there. And then the fade in positions are now going to have to be over here. And over here should be good for now. Let's just make sure we have the same settings, 880 and minus 772 for the static, which we should be able to see if we play it now. And then out of view doesn't really matter, but they have to be out of view obviously. Let's go ahead and move those as well. Now, this process of scaling game does take some time. There's a chance we might be done here, there's a chance we might not. But the only way we can do is if we build and run it again and test to see if we have any other issues or anything else we need to fix. Let's see, now we load it up. It's actually looking pretty good so far. We can click these buttons and everything seems to be working. My graphic driver thinks it's a game, which I guess it is. You can see over there. Actually, everything seems to be working fine. In my case, the only thing I need to change was that one setting, and the rest of my game is actually working great, which is pretty cool. Like I said, you might be different depending on how much you've changed your aspect ratio and how much you followed along. But it's pretty cool that this kind of game is kind of so easy to whip together. I mean, obviously it's not easy and the more you kind of code, the harder the easier it gets. But to be able to make something like this without being too experienced developer is pretty cool in my opinion. I just want to say a massive. Thank you to you for supporting my course and for purchasing it and for making this game. And I hope that you're really happy with what you were able to make and that you learned quite a lot throughout the entire process. At any point, if you need help with anything with bugs or anything issues with your game that you have, you can use any form of discussion on this course page or leave it in a review, Whatever you want to do anyway. A massive thank you again for purchasing this course and I hope that you're really happy with what you were able to make. And there is no next video, so I won't be able to tell you what we're doing next, but I hope that if you do decide to develop games as a hobby or even as a career, you're able to make something really, really cool. Thanks again for purchasing this course, and I really hope you didn't enjoy it. Cheers.