Develop and Publish Flappy Bird in 3 Hours With Unity3D

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey Darren here with Renaissance coders if you want to see more videos like this one hit that like button and subscribe to the channel the Fancy YouTube algorithms will rank us higher and enable us to keep making great content for you thanks for your time now let's get into the video all right so in this video I'm going to show you my complete development process you'll get to see what I do to uh create or search for art how I run into errors and make design decisions quickly I'll try to cut out anything that isn't useful to your learning so just sit back enjoy and let's see how long it takes to build Flappy Bird if you have an Android device you can find and play this project right now on the Play Store just search Renaissance coders tapy Bird Okay so first I'm going to start off by opening a couple resources that I know I'm going to need ahead of time uh the first one being the unity API if I get stuck on a method call or something I don't remember I can just do a quick reference to the API another thing is flat icon.com this is what I use for for my free art Purp purposes basically um I could just search something like bird which is something I know I'm going to search for this project and if I select selection up here then I know that all of these are royaltyfree assets that I can use I just have to provide attribution to them in the game so we'll come back to that but I'll leave these open uh let's go ahead and create our new project so I'm going to create a new project I'm going to call it tappy bird so it's not going to be uh called Flappy Bird but tappy bird is okay for me and then I'll set my uh initial uh project assets or however Unity loads it to 2D and then I'll just select create project and that's going to take a second to load up and uh I'm going to provide a link to any of the resources I use in this tutorial so if I'm using a piece of software that you're unfamiliar with I'll provide a link to that with document a and resources uh so I'm going to start off by creating a few folders in my directory okay uh let's go ahead and start off by saving the scene so I'll say save scene and I'll just drop this in as game we're only going to have one scene in this project and that's going to be game so make sure I save that uh before I get any progress done I'm also going to add in some fonts so if you're using Windows you can do this like this you can just type fonts and uh the two that I'm going to use are FFF forward and Soo UI Soo UI is kind of a big one but uh I really like the way those look for general purposes so that's going to take a second to import um so while that's importing we can actually get into some art uh I use for art I don't use Photoshop I know Photoshop is great but I never took the time to actually learn it and from what I can tell I can do a lot of the same things in that people should show me in Photoshop uh so I'll provide a link to this of course there's a few assets that we need to uh make sure that we have though and I'm going to be creating several of these on uh 1920x 1080 canvas and that's just sort of a default landscape canvas uh I know that this game is going to be in portrait mode but I want to make sure that I'm covering that width on various aspect ratios so uh my clouds background my ground and uh my stars are going to be on this size image so uh you know I'm not going to go into too much detail as I you know create this art uh but what I am doing is creating a gradient from sort of a light blue to a dark blue and then that should be a good backdrop for our background for our game and I'm going the opposite direction I want the light to be on the bottom I want to be darker as it goes up okay too much light there it doesn't need to to be perfect and I don't want to spend too much time on the art I'm going to export this directly into my uh directly into my project Sprites folder okay and this is going to be called background and that'll take a little bit of time because there's a lot of color information looks like my fonts are still trying to be imported into Unity so so sigo UI takes a little bit of time for sure after background we will work on the clouds and the Stars those will both be pretty easy I'm going to create those on a separate layer so that I can export those independently of the background uh so the stars and the back and the clouds are going to be Parallax that's why I want them to be separate images so I'm going to use this brush and this stroke um and I'm going to use a little bit of a lighter color so it stands out it should make it HP a little bit more and I'll place these sort of pseudo randomly uh like I said this is going to be Parallax so these are going to be uh reproduced over and over it would be the same exact image and I'll use uh smaller stroke as well some smaller Stars maybe they're further back or something okay just randomly placing these no method to the madness and that looks good to me uh now let's create the cloud and I'll actually go ahead and save this I'll export that to stars and then we can create the clouds next so clouds will be pretty easy um I'll make well that's probably a good color for my clouds actually I'm going to use this stroke and make it a little bit bigger so I can just create a cloud something like this you know just sort of silly cartoony doesn't have to look exactly like a cloud obviously it's just a game and I also don't want to spend too much time on these it's really easy to spend a lot of time just perfecting the art but uh we don't really have time to be doing that in this tutorial and I'm sure a lot of you are more interested in the unity development aspect as well okay and this will also be an image that's just recycled over and over and hopefully that's okay I don't want it to be too busy but uh like I said I'm not going to spend too much time on clouds okay after that we also have the ground the ground isn't going to be Parallax uh in our case so uh it doesn't need to have too much detail it just needs to be like a gradient and I'll create like a sort of dark cartoon outline um so I'll put a I'll put a gradient inside this so I'll do an intersect select and then we should just see like a outline on the top of that so I need to find some greens I already have some here we can go with something dark darker than that I think and I'll do a gradient and this one needs to be straight especially if you're parallaxing the ground this needs to be exactly the same so it looks pretty straight to me I know I said I'm not going to Parallax the ground but just in case you are uh you need to make sure you do that so this is what our scene is essentially going to be looking like uh it's not too bad I think I might want to erase some of those clouds I feel like it's a little bit too busy so here's where I'm going to do I'm going to erase a couple of those I'll erase that one and that one or perhaps that one and let me add let me copy this one so I'm just going to paste that and uh move it over here this looks good to me so that's I think that's okay and then I'll I'll merge that down if I can looks like my layers are locked uh but I'm just going to export those clouds again back to where they should be and then uh since I created the ground I'll export the ground as well so export ground.png okay so we have background clouds ground stars um I need pipes and uh I'm going to need a different size image for that so the pipes that the bird is flying through I need to create those and uh I'll set that to a width of 360 and a height of 2048 the large height is just to compensate for the pipes moving up and down on the screen we just want to make sure that the player never going to see the bottom of the pipe so let's start off the white background and this should be the last piece of art that we're going to create we'll find some other art on flat icon um so make sure this is on a new layer and uh that looks like that font finally imported okay I'll try to make this as Center as possible I know it's not going to be perfect um I'll use that sort of dark color background since this is going to be sort of cartoony and uh let's give it a width of eight perhaps that looks good all right and I'll go with that same color green I think I think that works pretty well for this that gradient gradients make anything look good I think it's hard to mess up something with gradient um then we want to add some Strokes on this to make it look a little bit nicer I suppose you could say we'll do 20 and we'll do 20 and 40 I think I need that selection back actually so um we'll go something like this this won't be perfectly straight but should be close enough and uh then I'll add one of a darker color for the other side just like that then we'll go up to 40 this might be too big actually I think it's okay um then we'll come back here and do the same thing yeah that's okay and then I'm going to just add an airbrush over that that color could work actually let's see what this looks like needs to be a bit bigger little bit less opaque these are just some sort of artistic touches if if you will uh I'm not going to spend too much time though we want to get to the development the fun stuff I'm going to duplicate this and crunch it up so it becomes the top part of the pipe so I need the scaling method here and uh I'll increase the width a little bit and then I'll also increase the I'll decrease the height so I'll crunch it up there this will be the top part of the pipe and let's see what this looks like that's probably too big I need to Crunch that up a bit more more that's better let's move that to where it's centered I'll increase the width a bit more and that looks okay I think let's see yeah I think that's fine uh so I'll merge that down and that'll be the last bit of art that we actually create for this tutorial and this will be called pipe. PNG okay a couple more things that we need we need a button for play a button for restart and we need a bird so let's go to Flat icon and find those things so I don't want to spend too long looking for anything and we have to remember that we have to give attribution to um the author of The Art so I'm going to go with a monocolor because I want to be able to change the color of the bird if I want to uh this one looks okay I kind of like that let's see if I think I saw something that look sort of like the Twitter bird like this one this isn't exactly the Twitter icon but I think this one looks good for what we want so I'll add that up there so we have our collection of what we can download right here uh now we need a play button and if anything pops out I think we can go with something like this though yeah let's just do that and then restart or perhaps replay getting the right keyword is sometimes what you need to do and this one looks perfect actually because if we look at this icon it's sort of black and then it has a white icon within it and this is the same thing it's black and it has the white icon within it so we want that to be consistent I think okay so I think these are the only three ones I need if I need more I guess we can come back I'm going to download this as a collection that'll also give us the licensing attribution information that we need um I want to make sure that the color is white because if the Sprite icon is white or the Sprite color is white then that means we can change the color to whatever we want within Unity so now I'll download this as a PNG I'll just say 512 make sure it's high quality and we'll do a free download of course that'll download it as a zip and that's going to go into my downloads folder which is full of crap right now uh but we will say okay we'll find it in our folder then we'll cut and go to our project so I'll paste this right here and then I'll extract it right here and I'll show you guys the licensing information within it so we have license we can make sure we read that let's see if I can open this with just notepad is fine that's I don't want to use any PDF reader it'll take too long and of course it's not going to read it uh okay well let's just open WPS we want to be able to see what that's like inside see what it tells us okay but I can bring these pgs in I'll come back to that document let's go to Unity Unity okay and so my Sprites have to repport okay now let me find let's close this so let's go to my folder so I can bring these Sprites in I'll rename these as well so this is replay this is play and this is just Bird Okay and then I'll just drag those in Sprites so let's look at that let's look at that PDF document see what that tells us so free license with attributions we just have to give attribution to the author and normally it tells us who the authors are but it doesn't look like it's telling us this time we're going to have to yeah we're going to have to go back to Flat icon and figure that out but we can do that a little bit later I think so there's nothing else in here okay yeah we can do that later no no problem um let me go ahead and make sure all of this is good all these settings we want to make sure we're generating M Maps that's going to get rid of any anti-aliasing that we have We'll add border m Maps as well uh actually it's probably best that I show you what it looks like without and you can see why I'm doing that so this bird will bring down to size of about 0.25 let's look at it from the game view so we can see that there's a good bit of aliasing and if you can't see that you can zoom in here of course the zoom in also adds aliasing but let's just say from right here now let's go to our bird and add the M Maps uh functionality with the border m maps and we'll save this uh we don't need a Max size of 20 48 because the image is only 512 so it has limited uh limitations there let's apply and you can see the aliasing sort of uh blurs out so it looks a lot smoother and if I zoom out you can't see any aliasing so uh mid Maps is really important so I'm going to add that to I'll just add it to everything actually and uh I'll say one I'll say 1024 because we had some bigger Sprites in there as well so we have all of our art which is great it's a great start and uh we can consider our attributions later no worries there we have our game scene saved we have fonts and uh I think we are ready to start designing the UI so let's go ahead and do that okay for any UI we need to add a canvas for starters and uh we're going to use we're actually going to use a screen space camera uh canvas so we're going to drag our camera onto the canvas that just means that wherever our camera is is where our UI is going to be that's actually just going to make it easier for us to design the UI uh placed right over the 2D Sprites um this looks fine for now we might modify some the the Sorting layer layer uh later but for now we want to make sure that we're scaling with the screen size and we can just say expand that'll do a fairly good job of scaling and uh after we have our canvas we can start adding UI element so uh what I usually do with my pages is I put them in empty objects so we need three types of pages for this game we need a um we need let's see let me look at my list really quickly so we're going to need a start menu or I'll just say start page we'll need a game over page and we'll also need a countdown page uh now these are all of the pages that'll be loaded dynamically but we also have some static content which is really just the score so let's I think we should be able to see UI elements from here yeah so showing up right there so our score is going to our score is going to be placed up at the top so let me set the width and height to be even we'll say 60 by 60 and then uh I'll put a default value of zero in there we'll say best fit bring the max size up to somewhere around 100 make it white so it's nice and easy to see uh so we can see it showing up a little bit better now let me bring the positiony up somewhere around there and I'm going to change my font to FFF forward uh starting to look more like a game that's a good font and let's make it a little bit bigger we can say 100 maybe 100 100 okay that's a good size I think uh we can always change the color later if we need to um you know what I want to do is let's go ahead and bring our game objects into the game so we can see this UI being placed over our game objects so let's see our camera's right here so uh let me show you that screen space element on the camera so we can see our camera is right here and our canvas is right over there now if I set my canvas to be uh screen space overlay then I have to I have to uh zoom out every time I want to look at the UI so I have to come way out here I don't want to do that I want to be able to look at my game objects like this while I uh modify the UI so let's start off by first changing our aspect ratio um sorry let's change our build settings first to Android can say switch platform that's going to give us all the aspect ratios that are supported by Android so here we have our list and I'm going to set this to landscape for starters I know my UI element move but we'll come back to that in a second uh so what I want to do is just add the game objects here so we have a background uh I'll set that to Z 0 we have clouds I'll set to z0 and we have stars okay z z as well um we also have a bird of course we can drag the bird in then we can't see our bird so why can't we see our bird uh we can't see our bird because of the order and the layer we're going to come back to that momentarily uh later in this tutorial um let me change the size of my bird so he's to scale properly that looks okay now remember I said that if our Sprites are white we can change the color of them so as you can see I can change the color of my Sprite that's because it's white so that's going to be useful for us a little bit later I guess I could set it to I'll set it to black for now and we can also change the size a little bit later all I really wanted to do was take a look at uh the UI over the actual game colors so now that we've done that we can start messing around with the UI a little bit more let me go back to Portrait and uh now we need to find the text there's no telling where that's going to be uh now since the canvas is using this camera the camera's uh depth matters although it shouldn't matter unless there's multiple cameras so there's some reason why my uh canvas elements aren't showing up here we have a canvas we have an order and layer so on my actual canvas I can change the order and layer uh that needs to be above zero we're going to create separate later uh separate layers a little bit later um so we'll see how to do that but for now I'll just increase the the number okay let's bring this score up to where we want it to be um and then to make sure that this scales properly now I want I want to make sure that it's centered um take a look at what happens here when I go to landscape the text shoots off okay so it's still there it's just in the wrong spot so this is where uh Dynamic UI comes in we have these is called anchors and the anchors can keep our UI elements in place now a trick that I use pretty much works for everything is I put the anchors on the outskirts of the wct and no matter what I do uh with the screen resolution and aspect it's pretty much going to stay where it needs to stay no matter what so that's a little bit of a trick you just drag the anchors uh out to the outskirts of the or out to the corners of the wct and it'll stay in place no matter what okay so uh I'm going to design the UI in portrait mode since that's the default mode now and we have our score let me name this properly score text and then we need to create our start page so what is our start page going to have our start page will have a button for play so let's create a new button and we'll set the size of this to we can say 100 by 100 100 maybe and uh let's use our play Sprite then we're going to take a look at it from here now from this from the game view here it looks like the aling is really bad but when when we actually publish this onto our phones uh it's not going to look like that I think the editor might be doing less work so it doesn't bog down the system so it's not it's not working too hard to make this look too good right now um so we don't need text and this is going to be our play button and our play button is going to have a job we'll we'll set up an event for that later but not right now um so let's do our little trick where we oh um okay so my start page you can see is just this little wrect in the middle so I can't actually move my children anchors outside of that uh so what I forgot to do was I need to make the uh the empty object wct the full screen size uh the way I do that is I click on this anchor region right here and I hold alt and shift at the same time and then I press this bottom right button that's going to make the size it does two things it makes the size of my wct the exact size of the screen and it brings my anchors to the outskirts of the uh of the screen now I can click on my play button and I can bring the anchors where they need to be on the play button perfect um I'm going to move the play button up a little bit okay now we're going to run into another problem uh if I change this to landscape our play button stretches so the reason it's doing that is because over here in my image component I need to select preserve aspect so that will reduce any stretching whatsoever um so now if I go to landscape it maintains the aspect now we can go back and look at the wct and see that the rect has stretched but since we're maintaining aspect the size of the button is going to be limited by the smallest uh width so um right now the smallest width is the height of the wct if I bring the height up then the button gets bigger okay so that's what's going on there all right so something else that I want my start page to have is a text telling me my high score so let's move this text component down I'll color it white set it to Best Fit uh best fit just means that the text Will scale within the size of the wct so let's sort of demonstrate that if I move if I scale the size of my wct then my text will change size accordingly and that's what best fit is actually doing okay so I want this to let me go back here and uh position that where I need it to be positioned and uh so go UI might be the best font for this we can try let's just try doing uh FFF forward for everything and see what that looks like this is going to say high score and then it'll tell us what our high score is I can I can increase my width to make that bigger and that's the best fit feature doing its work okay so this is just going to be what my start screen has a play button and a high score text so pretty simple uh I need to make sure before I forget that I'm setting the anchors on my text and this is just something that you need to do to make sure that your uh U fits on every aspect ratio it's a really easy trick um so with my game over page and my countdown page I want to make sure I do that alt shift trick so alt shift bottom right button then I'll make sure that the size of my page is always going to be the size of the screen okay so my game over page is going to have a restart button and my current score so I'm actually going to duplicate these um so this text will be that text is going to be my current score like the score that I just died with and this play button will be actually be a replay button okay uh so replay we we'll go ahead and I'm going to hold shift and press this middle button that's going to set my anchors back to the middle of the screen so that I can modify the X and the Y I'll do the same thing with my text so I'm holding shift and pressing the center button um so I'm going to move my replay button up and I'll just put that in the middle of the screen and then I'll bring my current text to possibly right above maybe and uh this will say score so this this score is for the current session this high score is for all uh sessions whatever your highest score was okay I want to make sure that these text uh sizes are fairly equal so I'm going to reduce the height of this text so it looks like they're the same size that looks pretty much right uh another thing that takes a lot of time with game development is just UI tweaking just making sure everything is placed properly everything is scaled properly uh those things can take more time than the development itself than the programming so so I have the game over page and the start page done countdown page and I'm going to go ahead and disable these for now countdown page is just going to be um the the 321 at the beginning of the game and this is going to be placed in the center of the screen I think it's a good place for it so this will count down for us and that'll be considered its own page and I need to make sure that I'm setting my anchors I'm not sure if I set my anchors I think I already forgot on my game over page yeah I set those okay so we have all of our Pages for our UI um next we're going to get into some more non-coding development that's going to be dealing with things like rigid bodies and physics um before we actually jump into the programming aspect so uh we going to get into actually uh writing the logic for these pages but first like I said I want to get through all of all of the development that doesn't require programming so we're going to do that next I'm just going to create an empty game object not right there I'm going to create an empty game object to store my environment so I'll call this environment and I'm going to place my do I have two birds in here um that's weird so I'm going to add uh everything that's in the game into my environment that's going to clean up my hierarchy a little bit so my I'm going to rename my bird I don't know why I had two birds up there okay um my bird I think needs to be a little bit smaller so let's make him 0.15 perhaps I think that looks about right hopefully you guys will agree with me um okay and I want to add a rigid body so let's just go ahead and play this and we'll see that nothing is going to happen and sometimes the first time playing just takes a while okay so nothing's happening uh we want our bird to continuously fall and he's not actually going to be being propelled forward but we're going to be dragging the pipes back towards him uh so all that we need to do all that we need to concern ourselves with as far as physics is concerned is having the bird fall so there's a couple things we need we need a rigid body that's going to make our Bird fall that uses gravity and I need to make sure I'm using 2D elements so rigid body 2D um don't worry about too many of these settings uh simulated means you know that that's asking the question do we want our object to be affected by physics or not um simulated is yes and not simulated is no uh don't worry about any of these settings we don't need to concern ourselves with those except for constraints so I'm going to remove the constraint on the Z I'm going to add a constraint on the Z so that uh the bird doesn't rotate without us telling it um other than that we don't need to worry about anything now if we run the game then we'll see that the bird falls okay um so we're almost getting there now we need a collider 2D and I'll add a I think a circle collider is the most appropriate here um we can click on our object now if we want to be really mean to the player then we can leave the collider where it's at and they'll get really mad because it'll look it'll look like they're not hitting the pipes uh and that was essentially the behavior in Flappy Bird I think if I remember correctly but we're not going to do that we are going to bring the radius down to where it's somewhat manageable now there's still going to be a bit of wing space or space between the wing in the head where they can get hit and players might get upset with that but we're just going to get as close as possible and and we could even say something like this and with that there's still quite a bit of room that is going to be left uh so where they they won't get hit so we could the bird could hit his beak on something without actually registering a hit but I think we'll just stick with this it doesn't need to be perfect and um we'll leave we'll leave that the way it is I think we want this to be trigger so let's make that trigger trigger means that our uh game objects can just pass right through each other instead of actually bouncing off of each other so we're actually going to simulate the uh actual stopping of the objects whenever they hit each other that'll be pretty easy so we have our bird we have our collider um now we need to add our ground so let's go down here and add our ground there's our ground let's make sure that it's at the z0 position and our ground needs a collider too so so I'm going to put this in my environment and I'm going to add a box collider to this now my box collider goes around the entire Sprite but that's not actually what I want I just want the Box collider and I'll change the size from here so the I think the x is okay I just need to change the Y so the Y can be quite a bit smaller and I'll change the Y offset so if you pay attention to the the green outline there that's what I'm moving that's the actual Collider and we can leave it there so they actually it looks like the bird will actually fall into the grass before it actually hits um I think that's all we need they have some other cool settings here with unity 5.6 but uh we actually don't need to modify any of that I'll set the collider to trigger and that'll be fine okay so we have the ground we have the um the bird we need to add the pipes now right now nothing is going to happen I can run and you'll see you'll still see the bird pass right through even though I'm using colliders it's because we're using trigger colliders um and we'll get into more of that later when we start scripting so now I need to add pipes so let's add one of these pipes here and this is just massive right now it's obviously too big uh let's downscale this a little bit so maybe 0. five might be the right I'm just going to downscale it until the width of the pipe looks good the height doesn't matter because we can do some tricks to manage that um I'll just go down one more and I think that is good um now of course there is going to be a pipe on the bottom and a pipe on the top and we'll make that part of the same prefab uh but this pipe is still going to need a box collider on it and that box collider will also be a trigger so let's play with the width here I want to make sure that's lining up just right with the edge and also the height okay so that's hugging the pipe pretty good um I'm going to go with that that's pretty good we don't really care that it's not hugging right here because um if the bird was right here if the player was in this region there's no way that they're going to be able to save themselves anyway so they're going to die anyway uh right here it's more important we don't want them to accidentally uh you know go a little bit too low but they're not actually hitting the pipe and they still lose that'll just make them mad so uh we're going to make sure it's hugging that region okay so we have the bottom pipe and I'll label this as bottom pipe and then I'll uh duplicate it and I'll rotate it on the Z by 180 and we'll call it top pipe and I'll just make the Y position uh inversely proportional so instead of 3.59 I'll make it positive and it looks like it needs to come up a bit more so I'll say 5.3 and the bottom pipe will be negative 5.3 and uh this is where we're determining how big the Gap is so at this point we're getting into a little bit of game design uh that Gap is too big so let's let's change this tog five and positive 5 so bring those in a little bit closer to each other and that might be too close that's probably too close let's do uh 5.15 and 5.15 and so again this is defining the region through which the bird can pass uh now let's create an empty game object and set this to 0 Z okay and then let's change the EXP position of our pipes to zero uh now this empty game object is going to be our pipe prefab the reason I was setting those positions to zero is because I want to make sure that my pipe parent is right in the middle of the the bottom and the top pipe so when I drag these in like this okay now this z0 position is going to be controlling the pipe where the circle is that is the actual center of my full pipe that's pretty important so now we need to define a region through which we can score and that's going to require a collider as well so I'm going to create a an empty game object here call it the score zone and I'm going to add a box collider to due to that that's going to be trigger and we can see our box showing up here and that's fine that that would probably work but we want to make sure that the bird is going all the way through or at least halfway through so we're going to make make this a little bit skinnier so I'll decrease the size on the X to something like that and then I'll increase the size on the Y so this will be the score zone so if the bird's trigger collider uh hits anywhere within this score zone collider then we'll register a score okay um now what we need to do is we want to add some tab tags so object tagging gives us the ability to find objects quickly at runtime um and it also allows us to determine what types of objects we're running into so I'm going to create two tags and one is going to be dead zone and one is going to be score zone so we have a dead zone tag and then we have a score zone tag now the ground and the pipes are dead zones so I'll tag those appropriately and then our score zone is uh score zone tag so that's all the tagging that we need to do okay and uh let's see what else we need to do before we actually get into the code we need to create prefabs so let me create a prefab for my clouds stars and pipes those are going to be our three Parallax objects uh parallaxing is the process of uh moving objects a certain direction uh at different speeds to simulate depth uh in other words our pipes will be moving a certain speed um those will be moving the fastest speed because they're the closest to our player and closest to our camera the clouds will be moving a certain speed now those are going to go a bit slower because um uh they're further away and then finally our finally Our Stars will be going at a certain speed and those will be going even slower than the clouds because those are even further away so that's the process of parallaxing so when I say that we're creating Parallax objects that's what we're doing okay let me make sure all of this is centered I don't know why okay I see I'm going to make sure all of these or at 0 0 and then I need to set my environment to 0 0 um just making sure everything is zero based uh the reason that's important is because when we we start spawning these uh parallx objects uh they are they need to be uh we're we're going to be setting the the position based on the Zero being the center of the screen so that's why that's important anyway let's create our prefabs the way we create prefabs is just take an existing object in the scene and drag it into our folder so this is in our prefabs folder so now we have the pipe prefab uh we want the cloud prefab so we'll drag that down and then the Stars prefab okay let's talk about layering now right now our layers are doing a pretty good job um but we want to make sure that our UI is always on the top we want to make sure that our uh our ground is always in front of the bottom pipe here and we want to make sure that the rest of the game is uh on the correct layer so let's go to our canvas anything that has a sorting layer component on it and we can add a sorting layer now one sorting sorting layer that I want to add is UI and that's always going to be on top then I can also add a game layer so let's start off with these two layers we want to make sure that the UI is always being rendered on top so this means that the score will always pass uh above the pipe as the pipes move across so let me actually move that pipe over so we can simulate that so you can see how the score is above the pipe right now but I still haven't labeled our sorting layers so let me set the bottom pipe and the top pipe to be uh on the Sorting layer of game so you can see now that the game is being rendered above the Y let's go back to uh or let's go to our canvas canvas needs to be on the UI layer uh now let's go to our sorting layer so UI since it's on the bottom it's it's a little bit backwards but whatever uh layer is on the bottom is going to be rendered in the front or closest to the camera so if I move the UI back then the score disappears behind the pipe so this is why sorting layers are important we can say that no matter what if our object is on a UI layer it's going to be rendered above everything else okay and this is sort of a an um top- down approach so if we want to Define more granular uh sorting strategies we could say for instance the score text should always be above the start page um so we can set uh we can create a new canvas like this override sorting and we can set uh its own layer right here but we're not going to worry about doing that uh the way we're doing this is actually making it a lot easier for us uh now we can see that the uh pipe however is since it's on the same layer as the ground I believe anyway or no actually it's not so let's set the rest of our Sprite objects to game so uh ground background clouds stars and bird should all be part of game um now right now the uh bottom pipe is where it should be it should be behind the ground uh and that could be based on where it's at in the hierarchy um but maybe not so if I take this bottom pipe and I change the Sorting layer to one since that's above zero which is what the back or which is what the ground is at then it's going to render on top top now I want to make sure no matter what because sometimes when they're the same value they switch uh so I want to make sure no matter what the bottom pipe is always going to be uh behind uh no matter what it's always going to be behind the grass now we saw that it just went behind the background as well so I can say that my background is always going to be behind everything so we can set that to something like -10 okay so that should handle the bulk of our sorting now we could also say that no matter what the clouds are going to be in front of the Stars the pipes are always going to be in front of the clouds so let's handle that and now we're getting to more granular order and layer stuff um so it's part of the same sorting layer it's all part of game but we want to make sure certain things are rendering above everything else no matter what so I'll take my clouds or let me take my pipe now my top pipe is going to be a different layer my top pipe always needs to be above the clouds so I'll say five um and I'll say that my bird always needs to be in front of the pipes so I'll set my bird to 10 okay now if our top pipe is at five then we can say our clouds can be at four and Our Stars can be at three so um stars are always behind clouds clouds are always behind pipes and pipes are always behind the player Okay so we've set it I think we've set up everything that is considered codeless development um we've set up score zones and dead zones triggers uh We've added colliders and rigid bodies um we've added the layers and the prefabs so I think we're finally ready to get into the actual code development so uh we're going to start off with the controller for the player uh so let's go ahead and create our script to do that so I'm going to create a tap controller for our player uh so of course we need scripts and then uh we're going to create a new C script called tap controller so let's open that up okay uh now this is going on the player and I'm going to be doing some stuff with the rigid body so one of the things uh I can do is secure one of my assumptions that the player needs a rigid body so I can say require component type of rigid body 2D uh so this tells uh Unity that if I drag a CH a tap controller on my object it's going to automatically create rigid body 2D for me um so a couple things we need uh public float for tap Force we can set that to 10 initially we'll probably be modifying some of these values uh we need something for tilt smooth so we're going to have the uh player actually rotate downwards as he falls um then we're going to have a a start position so when we reset the game where are we going to set the bird back to so Vector 3 start pause uh we need some private references one to rigid body 2D we'll call this rigid body and then we need a querian querian is a fancy form of rotation it has four values it's a vector 4 essentially XY Z W uh all from values of 0 to one it's too complicated to go over but uh it's a way of basically having secure uh rotation so you're doing anything with rotation Quan are the way to go we're going to define a down rotation which is what we are slowly going to be moving towards and then we'll have a Quran for forward rotation so every time we tap we'll snap right back up to that forward rotation okay that's all we need for now of course we'll be adding some stuff later um and start we need to Define some of these values so rigid body is going to be equal to get component rigid body 2D that gets the component off of our object down rotation is equal to querian do Oiler 0 Z we'll say 90 and that should be putting him face down um so what's happening here is we're taking a vector 3 and converting that into a querian uh for us to use in our down rotation so here you can consider XYZ as normal Oiler angles normal Vector 3 angles that we are used to understanding forward rotation be equal to querian do uh Oiler 0 0 and again on the z-axis we want to have him facing up a little bit so we can set this to something we'll say 35 for now and see if that looks okay um next we want to say rigid body. simulated equals false uh this is going to say when we first start the game uh we're not actually going to let him drop or be affected by physics although right now we don't actually need to do that but we will be adding something like that later okay next up we can add an update function so we'll say void update we'll also have something for on trigger enter 2D this is going to be looking for dead zones and score zones and this is going to take a collider 2D since we're in 2D space we want to make sure we're using the 2D counterparts of these uh data types um so we'll be dealing with that a little bit later so here we can just say uh if input. Mouse button down zero zero indicates uh left click one would indicate a right click and uh this translates perfectly as a tap notification on mobile devices so we don't need to do any uh pre uh pre-process or directives uh for detecting certain os's uh we can just leave it how it is and it'll magically work so the first thing we want to do is say uh transform. rotation is equal to forward rotation so remember I said every time we tap we're going to snap back up to this forward rotation then we want to add a force so every time we tap we want to add an upwards force on our rigid body so rigid body. add Force we can say Vector 2. uptimes tap Force tap force is that public member that we defined up top uh this also takes a second parameter for Force mode so we can add Force Mode 2D do force uh this is actually the default Force mode but I'm adding it so you are aware of it there's also an Impulse that you guys can try out on your own time so Force Mode 2D do Force okay uh that's actually all we need for now uh we also or for tapping anyway we also need to slowly move our rotation towards the down rotation no matter what what so we can say transform. rotation and just so you know transform. rotation is a quitan it's not actually a vector 3 Oiler angle um so we can say this is equal to querian lurp so if you've ever used lurp it just means we're we're going from a source value to a Target value um over a certain amount of time so the first value is our current value or Source value rotation second value is our Target value which would be down rotation and uh then we have tilt smooth which is a public parameter defined up top that's how fast we're going to move towards that and we want to define or we want to multiply this by time. Delta time okay so I think we're good now we just want to check for whether or not we are actually hitting uh a score zone or dead zone so we'll add more stuff here as we continue development but I'll go ahead and Define what we need uh we'll say if call which is the collider 2dgame object. tag so this is how we access the tag equals score zone then we'll do something uh here if call. game object. tag equals Dead Zone remember these are the two tags that we just defined uh so here we will register so here we'll register a score event and and we might play a sound if we get to that so play a sound in The Dead Zone what we're going to do is say uh rigid body. simulated is false this is essentially going to freeze our rigid body our bird it's going to freeze him right wherever he hits and then we can say um we can register a dead event for scripts that we might need to know that type of information uh we'll get into that a little bit later and we can also play a sound again in if we get to that I think we're already about an hour in uh and I want to try to do this in under two hours okay so let's go ahead and go back to Unity and play this and see what it looks like okay so back in unity and I'm going to find my bird and uh I'm going to put a tap controller on him and let's find out what is start position should be so I think right there is actually perfect maybe put him a little little bit higher to start off with so maybe somewhere like this I'm going to move that pipe back although he's not going to do anything for now um so let's just say this 1.22 and 0.81 I'll just copy and paste those values the Z I mean the Z could be zero the Z doesn't really matter because uh depth is processed by the order layer in 2D mode okay um so that'll be our start position and we should be able to run this and it should just work for us okay so his tap force is a little low but he did drop and uh his rotation is moving properly so we'll leave the Tilt smooth where it's at I think that's fine let's just bump this up to 200 or so okay so uh I think I I think there's something that we're missing here let's change this to 250 I see a bit of a problem um the way the physics works is as we okay when we add Force we're adding the force to whatever the current force is gravity is always affecting our bird so if he's falling really quickly our click isn't really going to do anything so let's go back to our script and say every time we click we're going to set the velocity to zero okay so before we add any Force we want to sort of zero out our velocity so let's say rigid body. velocity is equal to Vector 3.0 let's go back and see if this improves the look uh the look and feel of the game is really important and we will spend a bit of time making sure that's right okay that's much much better better uh the only thing I would say is that his X tilt is a little too fast it needs to be more gradual let me pause this and set his tilt to something like one that might be a little too slow but it's looking better so we'll try two all right I think that's perfect okay so our player controller or tap controller is done for now uh the next thing we're going to get into is the game manager which will handle um menu item spawning and uh activation and deactivation of certain menus and I guess we'll see what else is in uh what else is involved whenever we get into it okay anyway uh let's go ahead and create our game manager so create a new C script call this game manager okay and we'll go ahead and open that up okay so inside our game manager script we want to First create references to all of those pages um so the start page the game over page and the countdown page uh so let's create a public game object for each of those and uh as we need them we'll activate and deactivate them so we have start page then we have uh public game object not game manager public game object uh game over page page and then also a countdown page if I remember correctly uh game object countdown page uh we also have a score text that we can keep track of within this script so we can have uh public text uh score text since I'm using that text data type I need to add a using statement up here for uh unityengine.ui so unityengine.ui and I won't get any compiler errors after that uh I want to know what my page state is so I'm going to create an enum called page State and uh let's see always add a nun to your custom enom it's always useful to have in case you're not on any particular State uh then I'll add a start a game over and countdown okay so we have those page States and we'll use a method uh for setting those then we'll have a score value so that'll be an integer initialize that to zero and we'll have a bull to determine whether it's the game over state so Bull game over is false to start off of course and uh we'll make this accessible but not modifiable to other scripts so I'll create a property for it so public Bull game over that's just going to say get return the game over variable so we can get this value but we don't want any other scripts uh accessing it to modify it okay uh we're going to let's see since on that note uh if if anybody needs to access the game manager we should probably create a sort of Singleton for it since we're not switching scenes it doesn't necessarily need to be Singleton um or we don't need to follow those guidelines but we can say uh public static game manager instance so we're creating a static uh accessibility reference from other scripts uh so if they say game manager. instance then they can access the public members within this class so in a wake I want to Define that I'll just say instance is equal to this um since we're not switching scenes we don't need about we don't need to worry about destroying on load or anything like that if you're familiar with Singleton you know what I'm talking about but otherwise don't worry about it okay so my game is going to have certain events that other scripts are going to care about so let's create a delegate so delegate public delegate void uh game delegate and uh this is going to allow us to create certain events for other scripts to be notified of so we'll say public static event game delegate so that's our our delegate name and then we can create the name of our event which is uh we're going to have two one is on game started and we're going to have another one called um on game over confirmed we'll talk more about what those are going to be used for in just a little bit so on game over confirmed just like that okay um let's go ahead and come down and uh we're going to have a a method for set page state of course so let's say void set page State that's going to take a parameter for page State and in here we're just going to switch whatever the state is and based on the state will deactivate and activate certain pages um so that should make sense once I start getting into to it so we'll switch on the state we have four possible conditions we have case page state. none we'll make sure that we had the break statement and I'll copy and paste uh the other cases here so we have three other ones and uh that's going to be start um this isn't a semicolon that's why these are being grayed out these should be colons okay uh so we have none start game over and countdown those are going to be our states and like I said inside each one of these cases will be uh deactivating the object so we have start page uh we could say if it's none if there is no page State then they should all be deactivated right so we can say page start page. set active false and we can say that for the other Pages as well so start page game over page and countdown page um doing as much copying and pasting here to go as quickly as possible of course so this should start making sense so for uh the the start condition we make sure that our start page is set to be active so we say set active true uh for our game over State we say that the game over page is active and for the countdown State we say that the countdown page should be active Okay now we have uh let's see what else we need so we're going to have uh those buttons that we created earlier in our UI we have a play button and we have a confirm game over button after the player dies so we need uh public methods so that we can create some events hooked up to the game manager so we need a public void confirm game over so whenever the player dies that button shows up with his current score and uh it's the replay button so when he hits that replay button all of the logic so activated when replay button is hit and uh we'll talk about how to actually hook that up in just a second uh also for actually starting the game so we'll have a public void start game and this is going to be activated when uh play button is hit okay uh I think for now that is going to work work let's go back and hook these uh hook these methods up to the buttons and uh then we'll come back and see what else needs to be added to the game manager okay so up in our canvas we have our start page game over page and countdown page start page has a play button and let's open this up and uh we have some events here so on click we're going to press the plus button to add an event and uh let's add the game manager script that we just created let's add that to our main camera uh and then of course let's before we forget drag the UI elements on here that we need to do and I forgot to write the code for the score text so we'll do that in just a second so everything is hooked up for the game manager uh now as far as hooking up that event you can see it's asking for a game object here I can drag the main camera in here which has the game manager on it so we can access since this is the play button we access that start game function that we just created okay now the game over page has the replay button so we'll do something similar only this time we are looking for the confirm game over method so when those buttons are clicked the corresponding code will run within our game manager so let's open up our game manager uh and see what else needs to be added okay so let's talk about what needs need to be added in the confirm game over method uh we're going to trigger that event on game over confirmed um that's going to tell our objects to reset basically so we're going to have our on game over confirmed we're going to have our and this is an event uh we're going to have our game objects reset whenever this uh event is triggered now remember that this is an event that we specified up here um then we also want to set the score text. text equal to the zero string so we're setting our score back to zero uh and then we also want to set our page state so set page state to start game so page state. start so whenever we hit the replay button the start game page will show back up so we can hit the play button and start over again so start game is just going to set page state for page state. countdown so whenever we hit the play button then we'll have the countdown page show up so our countdown text is going to have an event as well uh let's go ahead and create our countdown uh text script and uh we're going to be listening to an event from our game manager to say okay whenever the uh whenever the the time actually runs out whenever the countdown finishes we can set the page State To None we can say oname started which is the event up here and then uh we can set the score to the actual score the end score to zero and then we can say that game over is equal to false again okay uh we also be listening to events from the player but we'll get to those in a second so let's start off with creating the countdown text script so right down here we're going to create so right down here we're going to create the C script for countdown text countdown text that's going to be placed on our countdown page countdown text so we can just go ahead and add that right now let's open that up okay so we know that uh this class depends on the text component so we can say require component type of text with that we need to make sure that we're using Unity engine. UI and we're going to have that text reference so we'll have text called countdown and start we'll go ahead or we'll say on enable because we'll be listening to an event from um or I'm sorry we won't be listening to an event but we're going to uh basically on enable is going to get called every time we set this page to active so we don't want to use start here um if we use on enable then anytime the game manager uh uh anytime the game manager sets countdown page to be active then this on enable code is going to run so we can say in here countdown text or countdown. text is equal no just countdown sorry so countdown is the text variable countdown equals get component text then we could say countdown. text is equal to three because it's going to be initialized to three and then we can say uh start Co routine on countdown so what is this Co routine we have to create that so that'll be an i numerator called countdown so the way this works is we have the ability to wait a couple seconds or one second before we actually do something so it's really convenient for something like a countdown we can wait 1 second and then change this text to two and then change it to one uh so the way we're going to do this is start our count off at three and then we're going to say for and I equals z i is less than count i++ so this should loop three times then we say our countdown text is equal to count minus I do2 string uh then we yield return new this is where we're actually uh telling it to wait for a second we could pass any value we want here but conveniently we only want to wait 1 second uh so this will say 3 2 1 and then it should trigger an event so we need to create an event that the game manager is going to listen to so we can say public delegate void countdown finished uh public static event countdown finished on countdown finished uh a lot of people will complain whenever I create my events as static it does make it harder to manage events especially if you're not comfortable with using events um you can run into a lot of issues that are hard to debug but to me I I find it to be much easier to just make them static uh you can make them public but then you have to have a reference to the game object and I've never really run into any issues with making them static as long as I know what I'm doing so I I'll make my event static for this tutorial and then here we're going to say on countdown finished this event is going to go to the game manager so if we go back to the game manager uh we can create an on enable on enable and uh this is just something I always do I always I always subscribe and unsubscribe to methods in these two methods um so in on enable I'm going to subscribe to countdown text countdown teex Tex or um yeah countdown text do on countdown on countdown finished plus equals on countdown finished so I'm going to create a method within my game manager class uh called on countdown finished to unsubscribe you just say minus equals to subscribe you just say plus equals um so I need to create this method and when I do that remember when the countdown finishes I can just set the page state to page state. none there's no longer need to have any Pages up until we die again uh also I can say oname started which is a uh an event defined within my game manager that's going to um provide some use to some other scripts that we'll see and then I can set my score my integer score to zero and I can say game over is equal to false now how do we tell whenever the game is over well we need to listen to an event that we're going to create within our tap controller um remember in our tab controller we have uh the ont trigger enters and here I want to register a scor event here I want to register a dead event both of those events are going to be listened to by the game manager so let's go ahead and Define those events within our tap controller uh we should definitely be getting worried right now because I've written a lot of code without doing any test testing so hopefully we run into minimum problems but um I mean this is sort of a challenge for me I want to see how fast I can do this and uh yeah I mean so if we run into a lot of errors I'm sorry but we should be able to fix those pretty quickly anyway so our first event or our our delegate can just be called player delegate so he's the the delegate of these events and then we can say public static events I know somebody's going to complain at me for using stat events everywhere um somebody always does but that's okay and uh so I'll just use on player died and then I'll use public static you guys think I'm kidding but I'm serious people people get upset um they say it's bad practice or but here's the thing I've never run into any issues with it so I don't know the only issues I've run into it is whenever I I was a novice uh using events but once you get used to using events and you can keep track of them and you know a good practice here like as an example what I'll do is I'll say that this event is going to be listened to by a certain script so um down here whenever I actually score I'll say on player scored and I'll say event sent to game manager so uh this is where using static events can be tricky um since you don't need a reference to since my game manager doesn't need a reference to my player it can be uh a little bit less than obvious that he subscribed to certain events so if I want to sort of track where an event is coming from or where it's going to then I can say that right here U make a note of it um so also I want to say that on player died right here and we can also say event sent to game manager okay so in our game manager we want to make sure that we're subscri driving to those so um we can have a similar format as to what we did here I'll just copy and paste this uh and the difference is this is coming from our tap controller and this is coming or this is our on player died or on player scored so on player died and then our uh second one from our tap controller is on player scored on player scored okay and then we want to make sure that we unsubscribe to those okay uh of course we need to create the methods for those um so let's do that we can just do it right below this one so void on player died and on player scored okay on player died what we're going to do is say um well first of all game over is true so can say game over equals true and then we could say int saved score so we want to make sure that we're saving our highest score we can say in save score is equal to player prefs dog int there's a sort of like sub registry for each project that uh player preps is saved in um we can call that whatever we want that's going to be saved in some magical place and what we're doing here is we're retrieving our saved score so our latest high score is going to be saved in saved and saved score and then we say uh okay if our if our current score before we reset it to zero is greater than our saved score then we've made a new high score and with that we can say player prefs do uh set int high score these two string values need to be exactly the same so that we're modifying the same value and the second parameter is the value that we're setting high score to be so these two strings are the same uh we're getting the high score here and we're setting the high score here okay finally we can say set page state to page state. game over so when the player dies we open up the page that uh basically says game over on player scored we're just going to say score Plus+ and score text . text is equal to score. two string that'll convert that to a format that our text component can handle okay so like I said I've written a lot of code hopefully nothing breaks uh I'm sure I have a couple of errors that I need to fix make sure that I'm saving everything uh but let's just go back to Unity and see what we're left with okay so I have an error uh the name oname stated I just misspelled that let's go back to the code and and fix that so it's started not stated and then we'll go back to Unity okay only one error very nice so let's run this and just see what sort of happens I guess so if we hit the ground it should be game over okay and then our uh score pops up we have a score of zero we didn't pass through any pipes then I have the play button so I can hit play uh now we have a null reference so like I said we're going to run into some issues um so game manager at 95 no reference exception let's see what that is uh so something that's listening to my event it looks like I didn't subscribe to it um whatever whatever this event is being sent to so on game over confirmed basically nothing is listening to that yet uh that's the issue we're running into um so for now let's do this and uh go back to Unity okay and let's go ahead and play this and see if we can get past that error okay so we're able to get past that error now we have the issue of our and looks like we have another error at 49 uh we have an issue where the game isn't being reset whenever we hit play uh let's see what this error is okay so also the same thing my game manager is trying to send down events that uh aren't being listened for or aren't subscribed to so uh the deal is let me go ahead and make a a note of this so event is sent to tap controller here and uh that's the same deal with oname started okay so on game confirmed and on game started need to be uh listened for by tap controller so what we'll do is we'll add the void on enable and on disable uh methods here so I need to say game manager. oname started plus equals oname started and uh oname or I'm sorry game manager. oname over confirmed uh plus equals on game over confirmed we'll talk about what uh each of these methods are going to be doing for us it has to do with basically reconfiguring our game objects uh whenever we create our Parallax or script we'll also be subscribing to these methods I believe uh because we need to reset the pipes and reset all the Parallax objects so uh let's go ahead and create these methods void on game started and on game over confirmed okay on game started we need to reset the velocity to zero um I mean think about if if our rigid body velocity isn't set back to zero uh on game started we have this sort of buildup of gravity so when we press start our players is going to fall really fast so on game started we want to make sure that our velocity is being zeroed out Vector 3.0 the documents uh recommend that you don't modify velocity if you don't know what you're doing or even if you do know what you you're doing you shouldn't modify modify velocity um but I've always found that having that control is better than not having that control so uh rigid body. simulated we're going to set to true because when we die we want to set simulated to false which is what we do here so when we die our uh our bird stops listening to physics and it just freezes that's what uh setting simulated to false does whenever we actually start the game back up we want to make sure that we set simulated back to true so what happens in on game over uh we want to on game over confirmed so after we die and we say okay let's restart we want to reset the the position of everything so here we want to say transform. uh position or local position because I think we're inside I think we're inside of a uh an environment parent object so anytime you're inside of a parent object you want to make sure that you're setting local position just to be safe so local position will be equal to the start position which is uh defined up top here okay and uh then we want to set our rotation transform. rotation is going to be equal to quitan do identity uh at this point remember we haven't actually pressed play so the bird will be set back to the start position and he'll just be sort of freeze framed in a start position so that's all we're doing here okay so now we should be able to go back to Unity and uh see the ability to uh die and restart the game and all that should be fluid okay so after these scripts built hopefully we have no errors and let's play okay we might modify that X tilt looks like it's still dropping a little bit too fast but anyway if we die uh he freeze frames so he's stopped there we can press play um and it looks like our X tilt is still moving and I think I know the reason why uh but if we hit play then it counts down and then our bird starts falling again uh but as you can see uh he's still being updated when the game isn't uh when we're in game over so uh let's go back and say hey if game manager. game over we're not going to update anything so in update we can say if let me get a reference to my game manager and uh my game will be equal to my game will be equal to gam manager. instance and uh I can I can say down here if game game. game over then return we're not going to do any updating if our game over state is true okay so let's run it and that issue should be fixed okay so he's stopped he's not tilting or anything and he won't start tilting until this countdown finishes perfect so the only thing left to do is uh really to set up the Parallax and the score script let's do the score script first because that's really easy to set up so we're we going to create a new uh C script or actually I forgot the score is actually set up from the game manager isn't it yeah I already set that up uh so we don't need to do anything else with that uh we do have a high score text though so if we look in our game over we have this text this is going to be our actually that'll be in the start page I think because the game over page is going to be let me see yeah the game over page is going to be the current score start page should be the high score so we need a high score text and uh that's just going to be pulling the player prefs so let's create that first so high score text high score text let's open that up or let's drag it on our text first after this we'll do the Parallax script which is the last script that we need for this game um at least as far as I can tell and after that we will be pretty much done uh with the exception to adding sounds and things like that so I do want to require component of text and use Unity engine. UI so we'll have a reference to high score text and start we'll say I think we can do everything in start actually high score is equal to um get component text and we're just setting the high score. text in the first you know the first configuration there's nothing Dynamic about this text so we can just say high score. text is equal to um player PRS dog in and I believe that that that value is just high score like this and that's all we need to do for high score text and of course I have an error so let's see what that's about uh I need to set this as to string because it's returning an integer and I guess it can't implicitly convert an integer into a string so we just say two string okay and now we are cleared up no errors and the only script we have left is probably the most difficult one because we're going to be getting into object pooling uh which means that we aren't going to be calling instantiate or destroy at runtime only once in the configuration process and then we're going to be uh moving the different Parallax layers so that would be the pipes the clouds the Stars uh we're going to be moving those layers of different speeds so let's create the SC the the script to do that it's going to be called Parallax uh this again this is going to be a pretty big one pretty important topic too uh Parallax and the paral axer is going to go on some empty game objects since we are doing this as a pooling technique uh we're going to store all of the pulled objects within some parents so I'll create an empty game object for clouds I'll create an empty one for um what else do we have stars and then also the pipes and The Parallax script is going to go on all of these so pipes stars oops uh stars and then the clouds and so those are our three Parallax lers uh Parallax layers those are going to be moving at different speeds uh back towards the bird the bird's not actually going to be moving forward just up and down U but it will create the illusion that the bird is moving forward so let's open up The Parallax script and see what we need to do okay so I've sort of been dreading this I know it's going to be a lot of work um hopefully the script isn't too long but the concept is sort of I don't know it's it's just a little confusing I think uh so we're going to create a pool object class uh this needs to keep track of um all of the objects of a certain type so it'll keep track of all of the pipes or all of the clouds or all of the stars and it'll be responsible for determining whether or not that object is in use uh because we aren't actually going to be in stand instantiating um during game play except in start during configuration because we won't be instantiating or destroying we have to be determining whether or not that object is in use or not so let's start off by just creating some variables for the pool object we'll have a public transform we'll have a public bu in use so that'll determine if it's available or not uh let's create our this is going to be sort of a condensed format I don't necessarily recommend writing your code this way um but regardless I'm going to do it anyway so uh we'll have our Constructor here that's going to take a transform to initialize and we'll set transform equal to t uh down here and I need a semicolon here now down here I'm going to have two methods one is void public void use or use so if I call use that means I'm setting in use to true and then I'm going to have a method called dispose if I dispose a pool object I'm setting in use to false so public void dispose inuse should be equal to false okay so that'll be the extent of our pool object um let's create some parameters so we need to keep track of what type of prefab we're going to be spawning so that's going to be a game object type type of prefab uh we need to know what size our pool is going to be so how many objects should we spawn how many pipes should we spawn uh how many is going to be enough we will figure that out with this parameter so pool size we'll have um a shift speed so how fast are The Parallax objects moving so shift speed will have a public float for spawn rate how how often are these objects spawning um we'll also have to have some position information so what's the default spawn position so public Vector 3 default spawn position um how about whether or not we want to spawn immediately so uh if you're familiar with the sh the shuriken particle system in unity they have a Boolean called pre-or and that basically means whenever you press start the particles are already taking the shape that they need to take so we're going to have a similar property called um spawn immediate and that's going to be responsible for setting up our Parallax objects uh automatically at start so we'll have a public pool called spawn immediate um that will be true for everything except for pipes basically um because we want our clouds and Our Stars to already be in place so then we also have the immediate spawn position because that could be different from the uh default spawn position so public Vector 3 um immediate spawn position um I'll just say immediate spawn pause so that isn't too long uh then we'll have a Target aspect we'll talk more about that in a second target aspect is going to make sure that our pipes and our Parallax objects aren't being spawned uh within the screen space remember we have to consider since we're publishing this we have to consider all aspect ratios uh the aspect is 43 on iPads I think so it's a lot wider than mobile devices in portrait mode um we might be setting a position that works in portrait mode on mobile devices but doesn't work too well on something that's like a 43 aspect because then we'll have objects spawning too close to the center and it'll look like they're popping in and popping out so we want to make sure that our default spawn position and our immediate spawn position is uh made relative to our Target aspect okay uh now we also have a Ys spawn range remember the pipes are going to be spawned sort of randomly on on uh the Y AIS so let's create a new struct here system. serializable uh this needs to be serializable so that the struct is viewable within the inspector public struct uh y spawn range this will have a public float for Min and public float for Max so what's the minimum uh height of the spawn and what's the maximum height of the spawn and uh up here we'll place it above the default spawn we'll have um y spawn range call that y spawn range just like that okay uh a couple more member variables that we need to consider that are local uh we need a spawn timer so float spawn timer we need to have an array of our pool objects I'll put that down here uh pool object array pool objects we need to store our Target aspect so this let's call this these different names um the way that we are going to handle our aspect ratio is by divide dividing the width by the height so if our Target aspect is uh if our Target aspect ratio is 10 x 16 so width by height that would be portrait mode 10 x 16 we say 10 divided by 16 is our Target aspect um because the camera class doesn't actually give us um like an aspect X or an aspecty it only gives us a x / y or with divided by height so we need to store our Target aspect ratio uh within a float that'll give us a close enough um generalization of where we need to start spawning objects okay uh then we'll have a reference to our game manager because that's always nice to have uh so let's create a skeleton so we'll have awake for initialization uh we're going to be subscribing to on game over confirmed remember remember whenever we get on game over confirmed we we are going to be respawning our objects so uh we need also start to initialize our game the reason that uh this needs to be in start is because the game manager is defined within a weake and start is always called after a weake so by doing this we're ensuring that game always has a nonn reference we're going to to be subscribing to events like I said so we'll have on enable and on disable uh we'll have of course an update method for shifting so update and then some other methods down here so we'll have a configuration method that'll actually be called in awake it'll also be called here let's go ahead and subscribe to the game manager really quickly it's only one event so game manager dot on game over confirmed plus equals on game over confirmed and we'll unsubscribe and undisable and we'll create that method right here and make sure that we don't forget this unsubscribe minus sign okay uh so on game over confirmed that is just going to be handling disposing our pool objects and um con reconfiguring so for now we at least know that we can call configure here because we're going to reconfigure our game objects in this um but let's go through and add the rest of the uh methods that we're going to need so we need something for spawning objects our Parallax object so we can say void spawn we need something for spawning immediate remember there's going to be a different method for spawning if we choose the pre-warm option I'll add a comment to that as well so spawn immediate is like particle pre-or that's essentially what we're doing so that's going to have a different spawn uh method um we need something for shifting so how do we move The Parallax objects we need to check if an if an object needs to be disposed so check dispose object and we'll receive a pool object from that so a pool object is going to be passed in here and uh let me see what we have we need to check if in use is true or not um or actually we're going to be what we want to do for this is check to see if the parallx object is off screen uh if it is then we set uh dispose which sets and used to false which makes it available to be spawned again so we also want a way of getting available pool objects um so transform. or just transform get pool object that's going to return to transform for us and uh I think that's all of the methods that we need so let's start off by I I guess this will sort of help us understand a little bit better let's determine how we're going to get an available object first so what we do is get the first available object in our pool objects array so we can say let's just Loop through it let's just say for uh in I is equal to zero I is less than pool objects. length and then i++ okay and here we say if not pool objects at I do inuse so if it's not in use if this object is not in use we can just return um we can just return pool objects at I okay uh we also want to mark this as being used so now it can't be selected again until it goes off screen so we also want to say pool objects at I do use so we're calling use on that that's going to set in use to True uh we can return null we have to return something in this method no matter what so we'll we will uh return n here okay so that's kind of how we get pool objects we can work our way up how do we check if we need to dispose an object so we can say okay if pool object. transform because remember our pool object class has a reference to the transform if pool object. transform.position not pool size. position. X is less than uh now what we're going to do here is start using the Target aspect so without the target aspect we can just say default spawn position dox actually I'm going to do it that way and uh I'll show you guys what I was talking about with the popping off and on screen uh so conceptually this should make a lot more sense though so if the position dox is less than the default spawn position dox uh now remember default spawn positionx should be offc screen should be spawning things off screen so we we can assume that the negative version of that should be offen screen in the negative Direction so when it reaches that point we can say pool object. dispose and that's going to say in use is now equal to false okay we also need to set the position to some place off screen right so we can say pool object. transform.position is since it's not in use shouldn't be considered in use it should be off screen uh so it's sort of of hidden from the player doesn't need to be seen by him so we can say that that's equal to some ridiculous value way off somewhere else um okay so that's checking dispose so this is disposing objects and using objects okay um I think it makes sense to just keep working our way up so how do we shift well we can just continue looping through our object so I is equal to zero I is less than pool objects do length um i++ okay and so we're just going to be moving based on we should have a shift speed variable up here so shift speed and uh that's the speed that we're going to be using to actually shift our transforms so we can say pool objects at i. transform. position plus equals negative Vector 3. right because we'll be moving to the left all of our parallaxing will be moving to the left so negative Vector 3. right uh times shift speed time time. Delta time to make it frame independent uh now we also want to check to see if an object needs to be disposed so this is where we're going to be calling this method U as we shift we want to say okay is the position less than uh the the Dead The Dead Zone essentially is what we're looking for so um is our pull object position less than the default spawn position so we can say um just check dispose object pool object pull objects at I actually okay um going to jump around a little bit so let's talk about configure let's let's see so how are we going to configure well we know we need to instantiate certain uh a certain number of these prefabs based on pool size so when we start the game we'll be instantiating um instantiating things and whenever actually I just thought of something we don't want to instantiate uh every time on game over is confirmed but so we're going to have to figure a way around that um so maybe we don't want to call this here um anyway I just to show you what I'm talking about in configure we we want to say that the um let's go ahead and set the target aspect so Target aspect should be equal to Target aspect ratio dox divided by Target aspect ratio doy remember the the target aspect ratio is the variable that we have up here as a public member we're going to be modifying that from the inspector uh should be 10 X6 default Android uh Android portrait mode I think for most phones okay so we'll set our Target aspect uh that's fine so if the for any reason the target aspect changes uh during game play it should this should be reset every time we reconfigure okay now we'll create the pull object array pull objects equals new pull object array and that's going to be a size of pool size public member that we defined up top uh now we could say for n i is equal to zero I is less than objects. length i++ then we can say game object goo short for game object is equal to instantiate so we're actually going to be creating the object spawning it into the game um but this should only happen once and we're spawning the prefab which is a public member we defined up top uh and we're going to cast that as a game object make sure that that's the game object type uh we want to store the transforms trans trans form T is equal to go. transform uh we want to set the parent to this current object remember we put the Parallax script on all of our parent objects so uh T should actually set the parent this new instantiated object T should uh have the parent of whatever object the script is attached to so we can just say t. set parent transform um now what we want to do is set the position this this is basically initializing it off screen so t. position is equal to Vector 3.1 * 1,000 that's off screen for sure uh now we can actually initialize the value within our pool objects array so pool objects at I should be equal to a new pool object where the value passes a parameter is just T that's the only parameter uh within the Constructor pool object that we need okay now we want to say say if in our configure if spawn immediate so if that spawn immediate Boolean is true then we want to call spawn immediate okay now spawning isn't necessarily the same as what we did here um for our Parallax we consider spawning as placing them in the correct position the objects in the correct position to be shown on screen so that's what we're going to Define as spawning so if spawn immediate then we want to make sure that we're calling that version of Spawn uh let's go through the regular version of Spawn uh right here so every time we spawn something we want to say transform T is equal to get pool object so we want to get the first available pool object uh if T is equal to null so we actually couldn't find an available pool object we're just going to return we can't do anything um if this is true so if true this this indicates that pool size is too small all right hopefully that makes sense um now we're going to define the position that we want our Parallax object to be placed at when we spawn so Vector 3 pause equals Vector 3.0 I'm just going to initialize this to Vector 3.0 and we're going to set the x and the Y now pause. X is going to be equal and again I'll just say default PA spawn p.x uh this needs to be dependent upon the target aspect but um I'll show you what goes wrong and why we need to consider the target aspect and then we'll come back and modify this code accordingly pause. Y is going to be equal to random. range uh y spawn range nope that's actually the type variable uh so that needs to be lowercase y y spawn range do Min and Y spawn range. Max so a value between the minimum and maximum specified from the inspector finally since pause is an independent variable we want to set that uh transform. position equal to pause now remember transform this T is coming from uh one of our pool objects so all we have to do is set the position and we can consider it spawned now what's the difference between this and spawn immediate well remember that spawn immediate cares about sort of customizing or pre-warming the position where something is spawned initially so let's go oops I just knocked my mic um so let's go to Unity and see if we can figure out what I'm talking about okay so I know I have this aor but I'll address that in a second um so let's consider our clouds um our clouds are going to be one of the paralax objects that we want to be pre-warmed or spawn immediate so the the thing is if we don't spawn immediate then uh what we'll end up with is our Cloud's moving over and then once they get off screen then we'll get something uh spawning over here we'll get some new clouds that spawn over here off screen and there's going to be this big gap of clouds we don't want that uh what we actually want is for our clouds to be spawning off screen right there uh but we also want our clouds to be initialized at zero so we're want to have two Cloud objects initially so initially we should have two Cloud objects spawned and then as these move over um what's going to happen is when this this when when these clouds get into a certain position over here that's when the new clouds will spawn on the right side uh we'll actually see this in action it's a little bit hard for me to explain but uh I'll try to show you what it looks like when it's bugging out and then I'll show you what it looks like when it's working properly uh but uh essentially what I'm trying to say is that our spawn immediate function needs to spawn two versions of this one right in the center of the screen and one on its default offscreen position and that's going to be our sort of pre-warm for our Parallax okay so let's go back to the script and uh let's look at this error first Parallax already contains a definition for y spawn range um let's open this up see what it's talking about yeah so this needs to be a lowercase y that's my bad um and that should fixed that error okay let's go back down to spawn immediate so this is going to be really similar we're just going to really we're just going to copy and paste this uh and then we're going to call spawn under this because remember one of those objects the the clouds on the right if you can imagine are the objects that are being spawned from the default spawn pause um now remember spawn immediate is going to spawn two objects uh only this object should be placed at the immediate spawn pause dox okay and and that should that should be it for our spawn immediate okay now we can look at update and see what we need to do there uh just like we did in the tap controller we don't need to be updating if game. game over so we can return if that's true and uh then we want to call shift so we're going to be shifting these Parallax objects then we want to increase the spawn timer plus equal time. Delta time if spawn timer is greater than uh our spawn rate I think is the name of that variable spawn rate yeah so if spawn timer is greater than spawn rate we can say spawn timer is equal to zero and then we can call spawn so that makes sense right and that's all we need to do for update now uh on game over confirmed we want to dispose all of our objects we want to basically remember dispose uh should move them off screen like this so we want to call dispose and move them off screen so that's what we're going to do on game over confirmed remember uh the bird will go back to a start position on game over confirmed and so we should restart all of the game objects on game over confirmed um so let's go ahead and I believe that that might be why called configure however we only want to we only want to do this part uh let's do this the only part I really care about with configuring or reconfiguring furing is checking the spawn immediate value because we don't need to recreate the pool again so uh this should work but if it doesn't we can always come back and fix it um let's go ahead and say if spawn immediate then spawn immediate right there but we also want to dispose all of our objects so uh 4 in I is equal to Zer I is less than pool objects length i++ we say pool object at I dispose and pool objects at i. transform. position is equal to Vector 3.1 I told you guys this was going to be a big script I did warn you um way off screen so times 1 th000 but we are almost done and we almost have a functioning game and we must be up around 2 hours at this point um but hopefully we have enough time to add sounds so I think we can start testing I want to make sure there's nothing else I guess we can just play it and see if we have any issues okay so we do have an error Parallax 21 uh looks like a misspell so this should be object and we'll go back okay uh cannot implicitly convert type pool object to transform so let's see what that's about so here since our return type is transform we want to make sure that we are returning the transform property within our pool object okay no errors looks good uh now I need to just set up some variables for the let's just do the pipes to start off with uh the clouds and the Stars aren't really important pipes are the real gameplay so uh let's set up the variables in The Parallax here so we'll add the pipe prefab the pool size we'll say we probably shouldn't need any more than five but we'll see I'll set 10 just to be safe our shift speed I don't really know yet so we'll say one and spawn rate again I don't really know I'll just say every two seconds uh spawn range now here what we can do is look at our pipe let's set okay so the Y is already at zero so what I'm looking at if I go back to pipes uh I'm trying to figure out a Min and a Max for the Ys spawn so what's the smallest yv value and what's the biggest yv value so I'm going to click on my pipe here which is centered at zero on the Y and I'll say I'm just going to look uh to see what I think the best value looks like so on the Y I would say that looks good 2.72 and the Min could be 1.79 negative 1.79 so 2.72 negative 1.7 79 2.72 okay um so we're going to of course play test this and see if it works we don't need spawn immediate on the pipes default spawn position so now I can determine what the best spawn position might be so I'll set my y back to zero so on the X I'll just move it until it's off screen sufficiently uh I'll say 4.5 is a good value for the default spawn position so 4.5 and our aspect Target aspect should be 10 by 16 of course that can be whatever you guys want okay I think that's going to work I'm a little bit nervous uh but let's just see what happens I suppose so I'm going to to deactivate this pipe and let's just run it so no errors that's a good sign my bird is tilting a little too fast so it doesn't look like and then my game froze so that was weird um I think my pipes are on the wrong layer let's run that again and pause it see what's going on so uh I definitely have pipe spawning my suspicion is that those are on the wrong layer yeah you should be on the game layer so they are spawning but if you take a look I'll change the Sorting layer to game and now that one's showing up so for some reason or maybe I just didn't apply this prefab so let's run this again so I just applied the values after I'd been changing it this whole time there we go now that is way off um something something's definitely going wrong there uh let's just run it again I want to look at that transform so we have some pipe spawning uh the scale is way off the X and Y is way off um I don't know what's going on there and uh I I do have a a suspicion though I'm going to say that so let's go back to our script my suspicion is we need to be modifying the local position remember I said if you're working within a parent game object it's always best to go with local position and that's what you should be shifting on is the local position um I don't know if that's going to work exactly or not but uh we can definitely try it okay so we're coming back and trying that out so let me pause now so that definitely wasn't the answer for some reason my pipes are a canvas oh no that's that's okay yeah I so you some of you might have caught this but I need to copy that component um yeah my pipe shouldn't be UI elements I was wondering why the positions were so far off uh these need to be within the environment let me create empty game objects within the environment I was getting really worried there cuz that definitely didn't look right uh and then I'll paste the component as new so all my values are are maintained there okay um let's run it again I think this is going to fix it I want to change the bird's tilt speed I think it's a little too fast and looks like that got reset too I think I set that to two Okay let's run this again and it shouldn't be okay let me go back to my T controller so it it shouldn't the the the bird shouldn't be moving until I hit play so I need to set rigid body and start rigid body do simulated to true or false I'm sorry okay so now when I play the bird shouldn't be falling but he is tilting uh that must be due to game over I should ini initialize game over to true I suppose uh because when I press that play button it sets it to false let's see start game I should say I say game over is false on countdown finish okay so let me initialize game over to true and then go back okay so just a couple little things that need to be fixed uh we knew that we would run into things like that but that's okay okay good so it's not going to start until I hit play now there's another issue that I want to fix really quickly and that is my UI this needs to say high score colon and then the high score so let's go back to our high score text script in our high score text script we need to concatenate this value like this so we can say high score colon just like that uh and I think I did a similar thing in my game manager I just set it equal to yeah so score. text should be equal to score or no not this one um but the text that I'm [Music] using in my game over screen let's just play it see what's going on okay I don't want to get sucked into all of the little bugs let's just see if we can play it okay so there's the countdown and we can play and there's our pipes correctly sized but they are definitely too close together my scores are going up doesn't look like my scor is being set here um so we can fix that though that's not too big of a deal let's go ahead and address that uh my score text is in my game over page and I don't actually have anything for that um I definitely need to have a script for that I think or let's see I think I can just put my score text component on that let's just create a new script for it and we'll just call it score text um yeah that's going to be the easiest thing to do right now so I'll edit this this is using unityengine.ui we have a text component and in start is the only place we need to set set that so score is equal to get component text score. text equals um score like this plus uh we can say game manager. instance. score we should be able to let me look at my game manager I feel like there should be something built in here for my score but I don't think there is uh so what I'm going to do is create a public property for this and just return score and then I can say uh within my score text game manager. instance. score uh so this should work let's go back to the game and now I just want to see when I die if I get the correct score now my high score is working so we can see high score is equal to two which is true I just want to make sure that that game over screen score is showing up properly so I'll get one point and then I'll die okay so now we see score one uh I suppose this isn't really necessary since we have the score up here so I'm actually going to get rid of it I'm just going to say that that says game over uh another thing that I just noticed is that this button needs to be the replay Sprite so let's fix those things so like I said I'm not going to use the score text that was sort of silly on my part um all this needs to say is game over and I need to set my replay button Sprite to the replay Sprite just like that uh so I'll go ahead and delete this and now we need to work on our pipes so we want to make sure that those pipes are being uh Parallax properly uh it looks like everything is working but the spacing was off so here we're getting into sort of the design aspect of the game so what I want to do is take my bird and just turn off his collider so I can never lose the game uh that's my reason for doing that and I'm going to press play and I just want to take a look at this from the side so I should see my pipes coming in they're coming in at the right position uh what I need to do is go in and click on my pipes here and change the well the shift speed looks like it could be increased a little bit so I'll increase the shift speed to point or 1.25 maybe okay so then I'll also increase the spawn rate to three and we can see that this is changing pretty much right off the bat so this looks pretty good they are deleting and spawning perfectly off and on screen uh now I'm going to show you why we need to care about this aspect ratio because remember we didn't actually Implement that yet I'm going to save this component copy component and I'm going to make sure I paste those values that I liked now let's go into landscape mode or you know let's just go into something less dramatic uh let's go into a portrait that is closer to an iPad so maybe 32 uh we can do 32 portrait we might be able to see it popping from here let's see okay so it's not popping from here uh I guess there should be one of these let's try something that's a little bit wider so just to show uh what I was talking I don't even have a 43 aspect on here let me just add that uh aspect ratio so we can say the width I think that's the aspect of an iPad but somebody can correct me if I'm wrong okay so we're on the 43 aspect let's run this again and uh we should see popping or else I suppose I'm a liar okay so it's popping on the screen space right there so if somebody was playing this on an iPad it would just look really buggy and it'll pop off the screen space right there so this is where Target aspect ratio is important um you'll see what this is going to do for us we can use a ratio to increase the spawn positions based on the width of the screen space so let's go back to our Parallax script and in our parall axer script what we want to do is uh we can start off by the check dispose object so this is whenever it's checking if it's off screen so we can say negative default spawn position uh and we can multiply this by our current aspect so camera. main. aspect and we divide this value we divide this value by our Target aspect like this and that's what we want to do whenever we spawn is as well so if we're looking at our spawn uh our spawn method right here this needs to be default spawn p.x times camera. main. aspect what's the current aspect of the camera is what we care about and we're going to use that to increase or decrease our spawn position divided by Target aspect think about if our Target aspect is what the actual screen space is then uh by simple math properties camera. main. aspect and Target aspect turn into a value of one one to one multiplied by default spawn positionx is going to be just default spawn pause so if our current aspect is the target aspect the nothing changes so that's how you can think about this ratio all right um we need to do the same thing with spawn immediate so we want to make sure that we're multiplying this by oops camera. main. aspect and divided by Target aspect now when we run this without changing any aspect uh properties when we run this on the 43 aspect we should see that they're spawning and uh being disposed properly okay so let's just run it and see if it works it should work automatically okay so here come in the pipes it's not going to be completely perfect uh they might be spawning a little bit too far off but they're offscreen uh nonetheless so it's certainly better than having them pop on screen and pop off screen okay so that's fixed and uh we can go back to our normal portrait mode for the rest of our testing so I have the I think I have the pipes spawning properly doing what I want them to do now I'm going to uh get rid of these clouds and stars and uh I'll get rid of this for now I suppose and uh I'm just going to duplicate this for the clouds and the Stars so my clouds Parallax layer and my stars Parallax layer so my clouds they're going to be using the clouds prefab um I can decrease this certainly to probably three but I guess to be safe I'll say four so that's the maximum number of objects that'll be instantiated at runtime uh shift speed this will be much slower so we can say probably 025 and the spawn rate we can say something like 30 or maybe 40 seconds um our our y men and Max just say maybe that's a variation of one so the maximum range on the Y spawn is is just a value of one so that's pretty small uh the default spawn Position will probably be somewhere around 15 uh let me just drag my clouds back into the scene to check that and uh I shouldn't have deleted those so this my cloud need to be on game let's see if I can no I don't want to do that uh I did change my layers earlier in the tutorial uh I think my clouds were let's see what is the layer that the bird is on okay so oh what about the pipes let's see the pipe layer is five so my clouds need to be behind that so I can say four my stars can be on the third layer so let me bring this back on yeah they weren't showing up so I had to make sure I changed that okay uh and I'll go ahead and save these prefabs okay so I'm I'm looking for the cloud spawn position so I'll duplicate this and uh the the cloud should be spawning over here right there would be good um that that's basically our our cloud trail so I'll do a similar thing with the Stars well the star should be in the same exact position 17.44% so I'm going to go to our clouds Parallax and I'll set that to 17.44% slower so we'll say 0.1 and we'll say the spawn rate is like 75 I don't know if these values are going to be going to work but they should be good enough at least for for now um yeah so I'm going to now delete these and when I run we should see everything showing up okay so everything is showing up look like they're moving the wrong direction uh oh nothing is actually moving yet cuz we're not playing so this is the pre-warm I was talking about we have a we have we have two clouds or we have four clouds what's going on there okay so there's a little bit of a bug I think oh um no that's not a bug our pool size is four so we spawn four clouds we have two that are up here these top two so those are the top two that are actually positioned so that's our pre-warm same thing with the Stars we have the top two those are being there uh pre-warmed right there so that's exactly what we wanted so let's let's take our bird turn off his collider and see if we can get these moving at the correct rate so I'll press play and then everything is moving that's good uh to test this a little easier since they're moving so slow I'm going to write some code that increases the time scale so it'll make everything move faster so let's go ahead and do that uh everything looks like it's working right now though so that's good okay so I'll say from my tap controller what I'm going to do is say if input dot yeah I I know I already have one here but yeah uh I'm just going to say okay if I click then I'll increase the time scale time. time scale this is sort of a debug property I suppose I'm just going to get rid of this plus equals 1 uh you'll see what this does let me go ahead and run so what I'm trying to do is just get my make sure that my clouds and my stars Parallax are is lining up properly so I'll go ahead and run this I'll set my bird collider off so he doesn't die and then I'll press the play button so that's going to run now if I click in the game it'll increase the time scale and uh again I'm doing that so I can look at the clouds and see whenever they're when whenever they're popping out popping in so it looks like they're the clouds are popping in a little bit too soon so I'm going to increase the spawn rate see let's say 60 and see what that does I'm going to increase the time to get a little bit more so it should spawn okay we're almost there say 65 probably 70 okay I need to let these run through when I change it at runtime it it thinks that the spawn time is seven so it spawns a lot faster so once this runs through we can check it for sure so after these clouds get to where they need to be and they spawn I can confirm that it's working okay that looks perfect so they're definitely spawning almost perfectly uh now I just need to check the Stars so the star shift speed actually doesn't look that bad it's going to be harder to tell if the stars are off or not and in fact I don't even mind if stars are overlapping a little bit but I do know that the cloud shift speed is almost or almost three times as fast spawn rate is 70 so this spawn rate should definitely be increased I'll just say 150 and that should make sense for me I think okay so um I'm going to copy this to make sure I have those values and just remember the value that I had for the Stars so post component values um and then this one was 150 okay so everything is working in terms of the parallaxing which is great news uh let's just play it and see if we find any issues so this is I suppose the fun part and it looks like we're uh oh so I wasn't paying attention let's see what happened there uh my gravity is accelerating really fast oh uh I forgot let me go back to my code I forgot to every time I'm clicking I'm increasing the time scale so that would be a really difficult game now we can go back and it should be fixed okay so about to play the game just going to see if there's any bugs and if there's not we can set it up for publishing I have a feeling I'm going to get a little bit addicted to this you know what I want to do is add some red on the background of the game over and I also I know I'm going to be tweaking this I also want to reduce the tap Force it's a little too too strong I'll say 225 um now what was I going to do okay on game over what I want to do is add a background image so I'll place that above the TCH so it's it's drawing behind everything and uh I want this to be sort of a red tent so something like that would be perfect perfect okay I'll turn that off I'll turn the start page off okay let's run this oh I actually need the start page to be on initially okay let's see if we can get a high score greater than two should be able to right okay that tap Force feels a lot better with a game like this you know simple as it may be the feel is really important and uh tap force is also really important because we don't want our bird to be able to uh we want our bird to be able to tap within the pipe uh at least when he's at the lowest position of the pipe so this might be a little bit too easy it's definitely too easy either the pipe either the pipe width needs to go down or I need to increase the tap uh or I need to increase the tab Force so I would rather actually I would rather decrease the pipe width so what I'm going to do is change this to say negative 5.05 no I'll just say negative five and then uh the top would be five so that moves it in it inches it closer just a little bit another thing I want to do is increase the speed of the pipes uh so let's do that let's increase the speed just a little bit we can say instead of 1.25 let's just say 1.5 and see what that looks like because I don't want this game to be too easy it's Flappy bir after all okay that's much better it's definitely going to be trickier uh the only problem now obviously is that they are too far apart but as far as the tap force and the height of the pipes go it's definitely going to be a lot harder so this is easy now because the pipes width are so far apart so let me go ahead and change that and the way you change that is just by decreasing the spawn rate so we'll say 2.25 so spawns a little quicker moves a little faster should definitely make it harder our clouds and our stars are parallaxing really nicely I like that okay this is pretty much perfect I think this will definitely be tricky I think so I'm just going to play this for a little bit I'll probably do a time lapse and if I run into any bugs I'll just uh stop the time lapse and address those uh actually I just saw a bug looks like the stars are drawing above the pipes so let me fix that um the pipe yeah the order and layer should not be okay no never mind okay the pipe is at order and layer five and the stars are at three so why were the stars drawing above okay I just have to run that again and see it happening and then pause the game so you'll see this star right here drawing above the pipe I need some sort of God mode actually I don't need God mode uh I'm just going to move one of these pipes so that's kind of weird I definitely saw a star drawing above maybe some of you did too there it is uh it's the bottom pipe so that's definitely an issue Our Stars are probably just spawning too low I need this bottom pipe well I could set the bottom okay I think I know what I have to do so the bottom pipe needs to spawn above this star or it needs to draw above this star but it needs to draw behind the ground so let's just do a little bit of layer tweaking and fix that uh the bottom pipe I'm just going to put it at the same as the top pipe so five but then the ground is drawing uh behind the pipe so we want to make sure that the ground now is at we can just say six so that's probably a better way of doing this so bottom pipe needs to be five and the ground needs to be six okay now I'll probably do a time lapse and if I run into some bugs then I'll stop it and we can address those together okay so it's definitely really difficult uh I don't think I'm going to change that though I think this game needs to be difficult that's why I got so popular I think uh but the thing is my top Wing always Clips so the the tap force and the width of the pipes is what's going to make this game challenging or easy um and right now those are just like perfectly aligned so it's just a really difficult setup I can I can make it easier maybe I will before I publish it um but I'm going to take a little bit of a break and then we'll come back and uh well it's going to seem like a second because I'm just going to skip the video but I'm going to take a break just so you guys know and we'll come back and talk about publishing hey this is a really long video isn't it but we are making a full game and Publishing it if you like the format then let us know by Smashing that like button and then you can leave a request for the next mobile game that we should clone is there something that we can improve on you can tell us that in the comments as well all right guys uh it looks like this is going to be about three-hour video we have about 30 minutes left I think uh so that gives us enough time to add sounds I know we said that we're going to get into publishing but I did forget about sounds so there's this application called bfxr you can Google it uh and download it so I think it just works based off of sort of randomized noise and then you work with these sliders to get it to sound the way you want it to so um we need a sound for tapping scoring and dying so I'm going to work on getting the the sound for tapping and then I'll let you guys listen to it after I mix around a little bit and we'll work like that until we have all the sounds and then we'll go back in unity and uh actually go through the code for playing those sounds at the appropriate time okay so I think I'm going to go with this sound for the tapping so it's not exactly like a flap but I think it sort of fits I mean it's sort of silly I suppose so I'm going to going to export this as a wave and I'm going to find my directory for a game and let's see uh sounds and this will be tapwave so we'll save that okay and the next one I want to find is uh the the die sound so I'll work on that and then and I'll let you guys listen to it okay so I think I'm going to go with this for if the player dies just something quick and sort of deep so I think that'll sound okay now the next one I want to do is for uh scoring so that one should be a little bit easier but I'm going to make sure I don't forget to export this and and this is going to be called uh die sound so die. wve okay and like I said I'm going to work on the scoring one and then I'll let you guys listen to it and then I'll save it and we can go back to Unity okay so this is the sound that I'm going with for scoring and I'm going to export that and then we can go back to Unity and see how to implement these things okay so I can close this and let's go back to Unity okay so our sounds show up as waves which is exactly what we needed now uh I think all of this can actually be implemented right inside the tap controller so let's go to the tap controller and see what needs to be done okay so we want to add three audio sources so public audio Source tap audio uh audio Source we'll have score audio and we'll also have die audio okay and all we need to do is let's see so when we score we can just say score audio. playay for our Dead Zone we can just say die audio. playay and then our tap audio is going to happen inside this get mouse button at zero so we can say uh here tap audio. playay and it's as easy as that so uh the only other thing we need to do is actually add the listening components to our player so let's go ahead and do that in unity okay so our player is our bird and I'm just going to add some empty game objects for tap die and score and I'll add some audio Source components to these so audio Source uh play on awake is false the audio clip for tap is tap um we can play with the volume after we actually play it we can see how it sounds so I'll just copy this component and paste it on these two objects the only thing that needs to change is the actual audio clip and after we do that we can just play and see how it sounds okay so I forgot to go to my tap controller and actually add those sounds so let's see that's going to be on my bird and I just need to drag in these audio Source objects so now I can play and I shouldn't get any [Music] errors Okay so not like the sexiest sounds or anything but I mean we just made them in like 2 minutes so what I do want to do is sort of even out the volumes I think that bouncing audio is going to get really annoying really fast so let's take the tap actually I think I'm just going to bring all the volumes down uh we don't want anything overshadowing any other audio I'm just going to set them all to3 see what that sounds like um the D one is actually okay that's not really as high pitch high pitch sounds tend to sound more annoying especially if they're playing all the time so I'll leave my die volume all the way up uh that didn't sound too loud my score volume is probably going to be the most annoying of all uh let's just play this see what it sounds like and I might actually make I think I'll make my tap volume much lower that shouldn't be the same volume as my score volume so let's go to my tap and uh I'll make that like Point 08 pretty low I'll reduce my die a little bit okay let's try that oh no I was in play mode crap I hate when I do that okay uh tap was 08 die8 and score we can just leave that okay let's run this we're getting closer to publishing so close Okay so that's tolerable yeah I think that's pretty good actually so I think I'm going to play this for a minute see if I can find any additional bugs before we go into publishing and I'll let you guys know what I find uh I did find something already if we look at those pipes you can see that the colors are inverted because I rotated the top one by 180 so this this is sort of picky but this color should be on the same side as the bottom pipe uh to fix that I'm just going to scale the prefab for the pipe the top pipe the X just needs to be scaled negatively so let's run that and that should fix it okay yeah that's I think that's better it is kind of picky but you know we want it to look good and I think that I'm going to make it a little bit easier uh those pipes are way too actually you know I think an easier way to do this the pipes are pretty prettyy narrow I'm just going to reduce the tap force and that should make it easier so I can be inside the pipe and tap without having to worry too much that's pretty comfortable and it's probably too easy uh so I'll increase that it was at 225 I'll just split the difference I'll go whatever the difference is 212 good enough um okay so now we're going to get into publishing talking a little bit about that okay so I've done a little bit of looking around and uh the problem is with publishing this bird let me reduce my Gizmo size uh this bird is like some slightly older version of Twitter's icon uh I was able to find it has this little fin on the top of his head and I found some branding guidelines on Twitter so these guidelines are basically saying that you know we can't modify or even show this in the wrong color I'm not even going to take a chance with it uh it was on flat icon and I'm surprised that it was under the selection uh group because that implies the that we can use it it has the flat icon basic license so I just found this bird this was actually created by freepic and I think they're the main author on flat icon so I'm going to credit free pick for this one and I'm going to download this this uh Sprite and use that is the main character uh in this game so I'll go ahead and just click PNG I'll download the 512 and I'll credit free pick and uh so before we publish we have to make sure that that we make our attribution within the game so let's go back to Unity so back in unity I'm going to open up my file explorer and find that bird that I just downloaded I'm going to replace that with the one that I'm using now so in my downloads we should have the bird somewhere in here and I think it's a piece of Blackbird Maybe so I'll I'll drag that into my Sprites okay and I'm just going to switch those out so uh I'll click my bird and I'll switch out that Sprite and I want to make sure I remember to enable generate MIP maps and Border MIP maps and I'll reduce the quality to 512 normal quality and uh that'll get rid of the aliasing I think he looks pretty cool as well so I'm pretty I'm pretty happy with that change um now I need to go in my start page and add a text component I'm just going to say uh um let's let's duplicate this text uh and then let's bring it up so bring it up to here and this text is just going to say with help by free pick at flat ion.com I'll change that font I think Soo is finally going to have a purpose um UIL is probably going to be good okay so we'll see how that looks I think that looks good that's a good attribution right on the front um and you know this is a clone anyway I'm not trying to take any creative responsibility for this game um so well I'm sorry that's the wrong way to phrase that I'm not trying to take any creative credit obviously there's some responsibility with uh taking a Twitter Twitter logo for instance but um yeah I don't have any problem with giving attribution I think it's definitely worth it now I do want to make sure that my new bird has a good enough collider it looks about the same the size of the bird looks the same so it doesn't look like we have to change too much there okay so I'll go ahead and save that and uh with regards to publishing we can see every uh pretty much all of our requirements in terms of getting it on the app store or the Play Store from the Google Play developer console if you haven't created an account you need to do that uh it's $25 a year I think unless they've changed that so once you do that we can take a look at the play console but with regard to Unity we need to go to our build settings make sure that we're in Android at our open scenes let's go to to play settings and see something that we need to change so we only want this to be in portrait mode I'll get rid of uh the landscape uh options and the portrait upside down options um everything else is pretty straightforward I do need an to add an icon um Splash image yeah um let's go ahead and go through this really quickly so their new Splash image editor is pretty cool and this might only be a unity plus uh feature I'm not sure so we can preview what the splash is going to look like um I'm honestly fine with that I don't have a problem with that at all so I'm not going to mess with it um other settings now we need to change the company name ours is Renaissance coders and I'll put a space for tappy Bird that's what's going to actually show up on the Google Play uh store we'll say com. RC tappy bird is our actual package name and the version is 1.0 so that's fine um if we run into any issues uploading this we can come back and change these settings if we need to uh we do need to create a key store so let's see if I can remember how to do this it's been a while so we need to create create uh or click create new key store and create a password for that I'm going I'm going to write that down so I don't forget it so the key store is really important you you can't upload your game without the key store and if you want to update your game you have to use the same original key store that you used when you first uploaded it so it's really important that you keep your key store um correct me if I'm wrong on that but that's been my experience so make sure that you remember your password and all that good stuff uh now there should be like a create new somewhere in here oh so you click browse uh browse key store and then you can create your new key store so that's the way it works so I'll just call it user that's the default value and it's saving in my uh Flappy Bird or it should be tappy bird but my Flappy Bird folder so notice the directory that it saved in and I'll just save it there um now we can say create new key okay and we can fill out the aist the aist can be whatever you want um I'll just call this RC developer password doesn't really matter um I'm sorry it doesn't really need to be different than your key Store password it's up to you um but it can be different than your key Store password first and last name I mean all of this stuff optional you don't really need to do all that so I can create key just like that that'll create and after that is finished creating I should be able to see it as an option in this Alias drop down okay so here we have RC developer this is the key store that I just created that's going to be what I have to use to upload to the the Play store okay um you will get an error if you try to upload without creating this key store and uh and that's basically what you have to do you just have to create the new one and then that option will show up add the password you'll be good to go so the only thing left to do really is uh art so let's go over to the play console and see what we have to do there okay so now we're over in the play console uh you can really just Google um the Google Play console developer console like I said uh or I don't know if I've said this yet but I think it's about a $25 fee unless they've changed that it's been a while since uh I looked into that but this is what the front page is going to look like it'll give you a list of your applications and this has changed quite a bit since I was last on it um I've already created tapy bird but if you want to create a new application you just hit create new application and that will pull up a fresh window um with uh a column over here for all of your settings for that application so I've already filled out the uh requirements for this application but I'll go through and uh just basically talk about the minimum requirements to upload to the Google Play Store so anywhere you see this blue star that's going to be a requirement so uh we just need a title description uh a short an aold description then you need to add some art so you just need a minimum of two screenshots for the phone you can also add screenshots optionally for different devices but uh minimum requirement is two screenshots for the phone then you need a highres icon a feature graphic and those are the only two Graphics required um Beyond these screenshots and it tells you the size uh requirements for those images uh then we come down we have the option of adding a promotional video we determine the application type the category and then it'll ask ask you right here to fill out a uh content rating so that'll take you to a new page and uh ask you a series of questions and then you just submit it and it'll show up here uh now you have to upload your APK file um you get the APK from building the unity project once you get that APK you uh put that up in your app releases I'll show you that in a second uh but basically it'll tell you you can't do this until you upload your APK okay uh you have the option of adding a website you have to you're required to add an email for support and then uh you can just determine whether or not you have a privacy policy right here so uh really all you're concerned with the minimum requirements is uh filling out these four rows so app releases store listing content rating pricing distribution so um let's look at our app uh app releases that's going to be where we actually add an APK so here we have edit release but you would normally just say manage production you can also manage a beta file or an alpha file for us we don't need that um so we have a release that hasn't been rolled out at this point you would see the option for adding your APK uh your APK file if I hit edit release then we can see upload APK I already have an APK uploaded right here here uh you determine the version of your APK or your your game and then we can go to review and from here we can say start roll out to production uh but this actually won't be an option that's available until we get these three green circles showing up so uh we looked at store listing let's look at content rating and this is going to be the page that you get uh brought to for your questionnaire uh that's going to determine the rating of your app and this is what's only available after you add the APK file pricing and distribution uh determine if it's paid or free there's some other requirements if you determine to make your uh or if you decide to make your app paid obviously you have to set up a merchant account uh we're not going to do that for this game uh countries you can determine which countries you want it to be available in so it gives you full control over that I'll just say it's available in all countries um and then you're really just looking for these blue stars so these are the requirements no it doesn't have ads uh you can determine if you want to add categories for the game uh accept the content guidelines and the US export laws and that's it so once you fill out all of that you should get these four uh green check marks and then we can go to app releases edit release uh review and then start roll out to production Okay so that's it I think we covered everything this was a really long tutorial and uh of course ask your questions in the comment section below and uh you know if you didn't like it if you didn't like this format because this is definitely a different type of video we haven't done this before uh but if you like it let us know and we can do some more definitely takes more time to do these types of tutorials uh but if you didn't like it let us know that too so we don't waste time uh making these types of videos uh but otherwise I hope you guys have a great day thanks for watching and I'll see you in the next tutorial
Info
Channel: Renaissance Coders
Views: 2,155,409
Rating: undefined out of 5
Keywords: unity3d, unity 3d, flappy bird, tutorial, c# game tutorial, c# game, how to make your own game, unity 2d tutorial, unity3d developer, unity game design, unity game developer, unity development, unity programming, unity 5 tutorial, unity game development, unity android, unity for app development, unity app development, unity android app, unity mobile app, android unity, unity tutorials, how to develop an app, how to create an app, how to make a video game, parallax
Id: A-GkNM8M5p8
Channel Id: undefined
Length: 172min 24sec (10344 seconds)
Published: Mon May 29 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.