Make a 2D Platformer Character in Unity - Complete Course for Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so for the series on setting up a 2d platformer character inside of unity i'm going to be using this pack called pixel adventure off of itch.io by pixelfrog it has a bunch of really cool characters enemies and player characters that you can use for a platformer game and the different player character sprites inside of this pack have very similar animations so i think that this pack will work out really good for this tutorial because the different characters in the pack will have the same animation so if you want to switch over to a different character you can pretty much follow the same steps alternatively if you have your own 2d platformer character animated in a program like asapri already you can use that instead so i'll include a link on getting to this page so that you can download the assets at the bottom you just got to click download now and you can go ahead and grab the pack download it and save it to your computer so the next thing that we're going to need to do is to start a fresh 2d unity project so i assume you already have unity hub and some version of unity installed uh currently i'm running on 2020.1.9 f 1 f for final i believe and we can start a new project by going over to new over here so we want 2d since this is a pixar game and we're going to go to project name and then you can give the project name anything you want so i'll call my project platformer character and then let's go ahead and hit create so when we boot up our project for the first time we should see a layout similar to this it's not critical but if you do want it to be exactly the same you can go up to window layouts and then revert factory settings and you should get the same look so inside of our project window that's in the bottom left hand corner here we're going to want to bring in our assets that we downloaded so that we can use them so what i'm going to do is right click to create a new folder so i'm going to go to create folder and i'm going to call this art so the way you decide to set up your folders and your project is completely up to you but what i like to do is put my art assets into a folder called art and then the assets i'm bringing from outside sources like edge.io pixelfrog i'll put it in an imports folder so i can remember that i got it from somewhere else so i'm gonna go to create folder here and i'll call this imports so now if we double click into this we're in assets are imports and then we need to bring the pixel characters into here so i'm going to drag this window slightly out of the way and double click on the zip file for the and then double click on the zip file for pixel adventure we can double click into free to see all the stuff that exists inside of this pack but when we extract it to the project we probably want all of these to still be contained within one folder so i'll navigate back up to where we have the free folder and i'll extract this to the desktop rather than leaving it with the name free which doesn't really tell much i'm gonna rename it with f2 and i'll just call this pixel adventure and a dash and pixel frog for the author name and now to bring this into the project we can just left click on this hold it and drag it into imports so you should see this little icon next to the cursor and if you see that and you let go it's going to add all the files into the project okay now we can go back into unity fully and we can check our imports folder for the assets inside of there so this tutorial is focused around creating a main character and animating it so we're going to double click into main characters and you can see that there's four in this pack there's mask dude ninja frog pink man and virtual guy so you can double click on each of the folders and you can see the sprites that exist inside of each of them and get a sense of which character you might like and i believe that they all have the same animations so once again you can pretty much choose whichever character you like for me i think i'm gonna go with virtual guide for now so the last thing we'll do in this video is to create a game object which contains the sprite for virtual guy so inside of the default scene that's loaded up and if you want to rename that we can just go back to assets folder scenes and then find the scene and rename it so we'll just call it tutorial scene i guess that would be a little bit clearer and reload so now you can see the name changed up here but inside of our scene uh we just need to basically drag in a sprite of some kind so let's create our character game object by bringing a sprite n so let's start with idle so the default animation and probably the first one we're going to work on is going to be the idle state where the character's not doing anything and really if you look at this you can see that there's actually many different sprites inside of here so this is really a sprite sheet but for right this second just drag it into the hierarchy of the scene so when you do that you'll get a game object that also has a component called a sprite renderer so the sprite renderer allows a 2d sprite to be rendered visually onto the screen uh basically your images you can see them in the game object and you can animate this later on and all that kind of thing so one of the first things you're probably going to want to do is rename this character so instead of calling it idle 32x32 i'm going to go up here for the name of the game object and i'm going to call it player makes a lot more sense before i fix anything else another thing i want to do is go back to the assets folder and i will create a new folder here for characters and so inside of this character's folder we'll store the prefab for our player game object by left click dragging it in here and then it gets stored to this player.prefab file and the prefab basically is a copy of the game object that's stored inside of our assets folder which we can instantiate onto a scene or basically create a copy of by dragging it in here and then when we have these copies we can change details about them so for instance we can increase the scale of the game object to make it bigger and that changes this copy but it doesn't change the original and so this instantiated copy has different values now like the scale but if i double click on the original prefab you can see that the settings still have the scale at one and one so if you want to change something across all objects you would set it in the prefab and if you want to change something about the copy of that prefab you would just change the one that's inside of your scene one of the reasons we need the prefab right now is that if i was to accidentally let's say delete the player from the scene and hit control s save the project that that player isn't completely gone we still have the prefab as a file here so we can add it back to the scene quite easily and we don't lose our work so having a prefab for any game object that you're working on is a really good idea generally so two final problems that we need to fix before we wrap this video up one uh the sprites look blurry so the pixar so they shouldn't have any anti-aliasing on the edges there there shouldn't be any blur they should be crisp pixels so we can easily fix that and secondly we brought an entire sprite sheet into here it should actually only show one of the sprites at once so to fix both of those we need to go back to the folder where we have the virtual guy character or whichever one you decided to go with so if we click on any of these imported sprite assets you'll see a bunch of settings for instance sprite mode set to single so if you have a sprite sheet where actually has multiple sprites for different frames of animation you need it to not be in single but rather multiple mode secondly on all of these sprite assets you'll see the filter mode is set to bilinear for pixel art games you should have that set to point to save time while editing those i'm actually going to left click on the first sprite sheet inside of here hold shift down and then left click on the last sprite sheet so what we're actually doing here is selecting all seven of these texture 2d objects so now if we change the setting like filter mode from the linear to point which you should do now then we can apply it to all of them at the same time so hit apply you should see the character inside of the scene become much crisper and if we bring in any of the other assets you should see them render properly with none of the blurriness around the edges so now it looks more like proper pixel art okay now the other thing for sprite mode not all of these are actually sprite sheets some of these are single frames so the single frame ones should be kept as single frame so what you can do is left click on the first sprite sheet that actually has multiple frames hold control down and then left click on each of the other ones that are sprite sheets and then we can change it from single mode to multiple mode and then hit apply so now when we do that it looks like our player disappeared if we double click there it's missing a sprite so not a huge deal there what we can do is actually break apart our idle sprite sheet and then set the correct frame to appear here so i'm going to left click on the idle sprite sheet we're going to go into the sprite editor here so let's click that in the inspector and then we need to slice this up by the number of rows and columns that are across the sprite sheet so go down to the slice menu choose slice type and make it a grid by cell count so we can count the number of columns here obviously the rows are one so one two three four five six 7 8 9 10 11. so we need to put 11 in for columns and one for rows hit slice and proof you have a perfectly separated sprite sheet assuming that the sprite sheet was set up correctly to begin with so whenever you export a sprite sheet from a program like asteroid um each of the frames should have the same width and height so you can see here they were 32 by 32 so this sprite sheet was done properly and that's one of the things you have to watch out for whenever you are exporting a sprite based character so now that we have our frames properly separated we can hit apply up here and now we're going to have 11 separate frames and we can see all of them by hitting this little looks more like a play symbol here and we have our 11 frames separated here so now with player you can see we still have the missing sprite right so what we need to do is just left click on this first frame with the sprite sheet expanded and drag this into missing sprite and now we have our player there we can double click on it to zoom into it you can see that the pixels are very crisp the character has the sprite renderer has a name and has a prefab so one thing that we maybe should have done actually is edited this change on the prefab so if i click over here open prefab asset you can see that the prefab is still missing the sprite so if you want to change a setting that applies to all of the instances of the character then you should do it in the prefab mode that's the quick way to do it and then you can just drag it in here but let me show you another way so back on the tutorial scene our player you can see that the sprite field here the bright property is a little bit highlighted here so what that means is that there has been a change that's different from the prefab and we can apply it directly to the prefab here by right-clicking and choosing apply to prefab player so now if we go back into the prefab by clicking on the arrow you can see the prefab now has the sprite idle frame 0 as well and if we go to our characters folder and find our player prefab you can see it's in the preview there and we can also just keep dragging copies of it into the scene like a madman and yeah now we have six players in the game which is completely unnecessary so i'm going to delete all of them okay so so far we've actually made a lot of progress we have the art assets inside of our unity project we have a player prefab with a sprite renderer it's properly rendering the idle frame we've separated we've corrected the import settings for our sprite sheets for pixar game minus one thing which is the except for the idol sheet we haven't gone to these other sprite sheets and separated them properly using the sprite editor which you should usually do whenever you need a sprite mode multiple but we will do that in the following videos so that's going to be it for this video i hope you guys are following along well so far and i will see you guys in the next one okay so in this video we're going to be continuing where we left off we have our player game object with a sprite attached to it so you can see in the sprite renderer we have frame 0 from the idle animation so we did properly break up the sprite sheet into separate frames so now what we need to do is to take the multiple sprite frames and combine them into a animation that can be played by our character so that it can change the sprite as time goes on but before we get to that we're going to need a couple of components added to our player game object so first i'm going to hit this little arrow in the hierarchy next to player so that we're editing the prefab rather than the player instance in the scene so the original rather than the copy and we're gonna go over here to add component and the inspector and the component we're going to need is a animator component so you can see inside of the animated component that there are several fields the one that we care about right now is the controller or more specifically the field for a runtime animator controller so we're going to need to create a animator controller so that it can be assigned here for the animator for this game object so in this folder to create our animator controller we need to right click go to create at the top menu and then inside of this scroll down to animator controller you might also notice animation and animator override controller so the animator controller is going to contain the state machine that controls how we switch between animations for our unity character and then each animation is where we assign the frames that are going to be played how it should loop and possibly other settings such as having triggers happen at a specific frame during that animation and then animator override controller i don't think we'll get into it too much for this i don't think we'll cover it too much here in these videos but when you want to basically take a animator controller the state machine here and replace all the animations in it with new ones possibly for a different character that acts in much the same way then you can use an animator override controller to reassign the animations without recreating the state machine and you'll see what i mean by state machine in a bit here so let's create the animator controller and we'll give it a name i like to give mine the name name of the character and then underscore ac for animator controller you can use whichever naming scheme you prefer and then there's a couple of ways we can create the idle animation one is to right click go to create and then down here at animation or we can go up to window animation animation and with a character selected that has a animator controller assigned which we do not um so we can go ahead and assign the animator controller by selecting it in this project window and just dragging and dropping it into the controller on the animator for the game object and then once we do that we can select our player and the scene the prefab here and it'll pop up with the notification to begin animating player create an animation clip so the second way is that you can create the animation clips directly in the animation window so let's go ahead and do that when we do that we'll have the ability to create a new animation file so i'm going to call this playerunderscore idle and the extensionist.anim which assigns automatically so we can just hit save here and we'll see that animation pop up i suppose the advantage of creating the animation clip directly in the animation window is that it automatically assigns it to the animator controller here and we can see this animation clip in the animation controller by going up to window animation and animator so you'll see here that the player idle animation is placed here as a state so wherever we have these boxes we're talking about a animation state and you can see that there are transitions that go in and out of different states for playing different animations we'll get to more on that in a second so for right now though we want to assign the player idle sprites so i'm going to click on the art folder and the project window double click on imports pixel adventure and let's go to main character right now i'm using the virtual guy so you can use whichever character you want for this and we have the idle animation which is broken up into separate sprites so i'm going to expand that now and let's just rearrange these windows a little bit and i wanted to bring all these idle frames in here to the animation so we can do that really simply just by left clicking on the first frame holding shift left clicking on the last frame and then dragging these into the animation so you'll see that a property is added automatically for our player game object that is the player sprite so whenever you want to change which uh sprite image is displaying you would change the player sprite value so that's in straight renderer and then sprite and if i zoom in here ctrl middle mouse wheel you can see that all of the frames from that animation are added in here and they are different frames so if we want to see that animation be played we can go back to the scene window of course we're still looking at the prefab make sure it's selected and then hit play in the animation window and we can see the idle animation playing so one thing though this idle animation is currently playing way too fast you can see here for samples it says 60 that would basically mean 60 frames per second so uh for this pack the animations are all designed to play at 20 frames per second so we just need to change this from 60 to 20. so changing that end there and now the animation plays much more like we would expect so if we look closely there's one more setting uh that i really should have changed in the first video but we can edit it now and that is the compression for our pixel art so you can see here that as the animation plays that some of the colors get discolored that's not how it was originally meant to display and we can correct that by selecting all of our images inside of the folder all of our sprites and then we go down here in the inspector to where it says compression setting and change it from normal quality to none and then hit apply so for pixel we don't want it to compress in any way we don't want it to filter in any way we just want it to render the pixels exactly how the artist designed it to display so just make sure that the compression is set there to none and it should start looking correct so now we can go over to the animator window we can see that the entry point for our animation controller is to go right into player idle that's probably what we're going to want for most characters in our video game that's probably going to be what we want entering into the idle state before any actions are taken to change it to something else so one last thing we'll do for this video is to create a run animation clip and then in the next one we'll actually work on transitioning between the two and allowing our character to move properly so um in the our assets for virtual guy we have the run sprite sheet you can see that there's no kind of play button next to the run sprite because we haven't actually separated it into separate sprites so we need to go into the sprite editor and then when we're here we need to slice it by the number of columns so we can do that really easily just count the number of sprites here 1 2 3 4 5 6 7 8 9 10 11 12. okay so that means we have 12 columns so let's go to slice and change type from automatic to grid by cell count i think doing cell size by 32 32 would also work but cell count so we change the columns to 12. and for a sprite sheet where everything is separated properly by 32 32 pixel squares like this we can also go to uh grid by cell size and change it 32 by 32 and you'll get the same results here but it does depend on if the sprite sheet is separated properly where everything is separated by the same amount of space um either way you want to do it is fine as long as the sprites are in the right location so we can go ahead and hit apply and now we can close that out we have our run sprite frames so we can click on player i'm going to open up the animation window by hitting control 6. it's just much faster than using the window and we can click on the drop down where we see player idle for the animation clips that exist in this animation controller and then hit create new clip so next we're going to want player underscore run save it by default it's going gonna save in the same folder so that would be uh the characters folder here so we can see player on and next we just need to bring in all of the frames for the run animation so let's left click on the first one hold shift left click on the last one bring them in to the animation window and uh yep pretty much done there so we're gonna want to select the player in the hierarchy and hit play and we can see our character running way too fast though of course because every animation in this pack is meant to play at 20 fps so i'm going to change the samples to 20 hit enter and we have our one working so now we can switch from run to player here and we can see that we have two different animations set up on our character however if we go to animator we'll see that there's no proper transition between player and run so this is going to get a little bit more complicated because we're going to need to introduce some logic to our character but for right now we should have two animations playing properly idle and then run so that's gonna be it for this video hope you guys are following along well so far and i will see you guys in the next one in the last video we set up our run and idle animations but the problem is now that we need to be able to transition between them inside of the animation controller and in order to do that properly we need to get some input logic in a player import script and then what we'll do with that logic is to feed it into parameters here for the animation controller to use so that it can decide when a character should transition between two different states such as idle and run in this case the obvious transition is going to be whether we're trying to move the character left and right so if there's no movement input the character should idle and if there is movement input the character can run we can either do this really two ways we can test if there's input at all and that will determine if it's run or idle or we can check the velocity of the rigid body object that we haven't created basically is the character moving an actual game space for this video we'll check whether there's import rather than checking the velocity depending on which way you do that it'll give you a little bit of a different feel for your platform or character so we're not going to mess around in the animator window right now we're going to get the input on a player script so i know in advance we're going to need a rigid body component so first i'm going to make sure we move into the prefab for the player so it applies across all instances of the player so for right now we're going to need to create a player import script so i'm going to click add component and i will type in here the name of the script we want to create so in this case i will call it player input pretty straightforward we'll do new script create and add just so you know this player import script gets created in your assets folder later you might want to move it into somewhere else like creating a folder for all of your c sharp scripts something like that or you could put it in characters if that makes more sense to you so let's go ahead and open up our player import script so i'm going to so i'm going to click on the three dots and then do edit script here so just so you know i'm using visual studio code as my editor for the c sharp code you can use anything that works for you this is just what i prefer to use so let's go ahead and start working on our script so inside of our player input script the first thing we're going to need to do is to get access to the animator component that is on our character so there's several ways to do this but i want to make sure that we select the correct animator component manually inside of the unity inspector so i am going to put in here public so that we can access this field and then animator as the type of field we want to find and i would just call it animator and semicolon to complete our line so now if we go back out to unity wherever we have our player import script we now have a field for an animator component so we can click on this little button here and we can select the animator from the player object you can also left click hold and drag this field over here so that you're directly dragging and dropping that in so now we're going to have reference to this animator component and we can set some variables on it the variables we're going to want to set is going to be the x move basically whether the player is trying to move left or right so we're going to want to get access to the input values in unity so i'll put in dot get access and then we need the axis name which i know is horizontal so i'm going to type that in here and we're going to assign this to a float variable so float we could call it move x if we want and then we just assign the float to whatever value we get back from the input dot get access so to know what these fields are called why is it horizontal specifically that is set inside of the unity editor so if we go to edit in the unity editor and we go down here to uh project settings i believe then we can find input input manager axes and then you can see horizontal axis has the name horizontal so that's why we use this string to get access to this value you can also see the key bindings that are set up for that axis so left arrow right arrow or a and d on the keyboard work for that and inside the input manager you can also see lots of other actions that can be pressed down such as jump so jump the positive button here is being set to joystick button 3. so later on we'll probably make this something like spacebar but i will leave it alone for now and we'll come back to that later so just so you know whenever you want to change your import key bindings you can do that in here in the input manager so let's go back to the script here we have the movex import get access value now depending on the perspective of your game you might also want to get the vertical axis but because this is a platformer character we want to move vertically by pressing up and down but rather what we would do is a jump key so i'm not going to bother getting move y here then we would just do import dot get access vertical if you needed to do that so the next thing we're going to do is to assign the animator value uh for the move x so animator dot set float because that's the type of value we're setting and we're going to call it move x and then the value move x so right now it's incredibly simple it won't actually move the character but it will give us the value that we can use in the animator to change the animations so let's go into so save the script i'm going to close out of the animation window and i'm going to drag the animator window down here so that we can see the scene and the animator at the same time and next we need to create a float value for the move x as a parameter in the animator so if you just try to set this value here uh to move x when no parameter had been created i think it would get an error so we need to go in here and do plus float oops okay i'm gonna have to delete that and miss click and then do plus float and then give it exactly the same name so if it's move x in here it also needs to be move x in your code and now we need to use this parameter to control whether the player should run or not so i'm going to right click on our player idle state make transition send it to player run and then we'll also make a transition back player run to player idle so when we're making the transition between idle and run states we're going to need a condition added to it so we can hit the plus arrow here and you'll see move x pops inside of here and we can set it to greater or less than zero so one way to handle this would be to basically have two separate transitions one for a move x is greater than zero one is moving in the positive or right direction and then another transition where we check if it is below zero when it's moving in the left direction so regardless we're going to need this move x variable eventually to get a sense of how far to the right the joystick the player is pressing or the arrow key in that case which would always be set to one i believe but in any case we are going to need that move x value but a simpler way to check if the player should move from idle to run is going to be to use this movex value in the code to generate another parameter in this case a boolean variable so this is going to be called is moving and if the character is moving it's set to true otherwise it's set to false uh one of the advantages is that by having this determined by code that we have separately and the player input uh that we never really need to worry about how it determines is moving inside the animator controller but we just need to worry about it here set that value when it's appropriate here and then the animator controller will do the rest so rather than using move x for the condition i'm going to use is moving so is moving set to true puts it into run and then from run to idle we do is moving equals false so here it's simplified and really easy to understand and we just need to determine the true and false states inside of our player and port code so back in the player input code we're going to take this move x value and we'll determine a new boolean so we'll call it boolean is moving and what we'll do is we'll check the value against what we consider to be moving and what we consider not to be moving so i'm going to use the math f function library and we're going to check if the move x is approximately zero so move x and then compare that to the float value of zero so what we're saying with approximately is that if it is moving the tiniest bit to the right we're just going to exclude that and we're going to say that it is still not moving so um what we actually need to do with this value here i think is to invert it though because we're saying that if it is approximately 0 that it should not be moving but this boolean value is set to is moving so we just need to inverse that with a exclamation mark so exclamation mark math f dot approximately move x comma zero f for the value to compare it to so in other words if it's not not moving then it is moving and then we're going to take that value and we're going to set that in the animator so animator dot set boolean this time and then is moving comma is moving the parameter so now we're mostly ready to test our animations out and make sure that the player import script is working so if we go over from scene view to game mode we might notice one thing though which is that a pixel art character is probably going to appear really really tiny here so in the case that you guys are using the same pack that i wore um pixel adventure here we can open that up and go into the character that we want to edit so if you click on any of the sprites you'll see pixels per unit here is set to a hundred which would mean that you would need a character to be 100 pixels to be one unit of game space inside of unity and if we go back to the main scene here you can see that one unit is one of these squares and and our character just looks really tiny by comparison so one thing you could do is to change the pixels per unit for all the sprites across the game but another option might be to go to your main camera and to decrease the size so i'm going to drop the size down from five to one here and so if we go to game view now our character appears much more properly represented on the screen so another thing that i'm going to add in to our camera component is going to be called a pixel perfect camera so i believe this is default in unity these days but to make sure you have it you can go up to window package manager and then make sure that the 2d pixel perfect package is included in your project so having this script added to your camera is going to help ensure that your pixar games look correctly as your characters move around the screen okay so now we can go ahead and hit play enter game mode and start testing our animations out so inside of the animator if we click on player and have that selected we can see that the player idle state keeps looping its animation let's bring this down here next to console so that we can see the animator and the game view at the same time so now if i hit left or right or a and d on my keyboard it's going to start receiving movement input well first you have to actually be selecting the game view and then you can hit left and right on the input and that value is going to be assigning as a parameter and the animator so you can see x move and is moving here note that the move x value takes a second to get up to its full value of 1.0 so if you like that you can leave it like that with get access so as long as we press left or right or a and d on our keyboard we can keep the character and the run state and if we let go it's going to return to the idle state one thing to note though is that because we're using get access instead of get access raw at the moment it takes a second for the move x to go from 0 to 1 or 0 to negative 1.0 so if we use this as a multiplier value to figure out how much force we're applying to the character then we can kind of have the movement accelerate over time that might be something you want or as an alternative let's go ahead and get out of play mode here we can switch to uh get access raw so get access raw instead of get access horizontal so the name of the field's still the same the difference is now that when we go into play mode and then we hit left and right it instantly goes to move of negative 1 or 1.0 it's up to you whether you want the character to accelerate or just instantly reach its max velocity now another problem you might notice is that it takes a little bit of time from when you press the key to actually switch to the animation state that's because our transitions currently have exit times so we can actually edit these while play is running which is quite handy so if we click on one of these transitions you can see has exit time is checked we can also expand settings and see the transition duration is set to 0.25 so the transition duration is how long it takes to move from one state to the other state and then the exit time is how far into the state do you need to be in order for basically idle to run transition to occur we want the character to be able to transition at any time so we're going to uncheck has exit time but then we also want the transition to be instant there shouldn't be any kind of in between here so i'm going to set the transition duration to zero and i'm going to do the same thing for the run to idle transition as well uncheck exit time and set transition duration to zero now if we use left and right to control is moving and move x you'll see that it changes instantly for most 2d platforming games this is probably going to be what you want so that the controls feel much more responsive one other thing i want to change is the background color i really don't like the solid blue that comes default in unity so i'm going to change the background to maybe something more like a very dark blue black for now and hit play so i just think this looks a little better for right now it also contrasts our very bright sprite as well so i think that looks pretty good now there's a few things we need to add to our character which will be the next video on um being able to make it actually move first off we need to have it have a rigid body uh which is the physics component which allows a character to move to receive forces and then we're gonna need to actually add a force to it in script but rather we're going to add a behavior script to player on so that it can move but only when it is in the player run state so that's going to be it for this part i hope you guys are following along well and i will see you guys in the next video so currently we have a character with idle and run animations however we're not able to move the character yet because it has no rigid body component and we're not adding any forces to that rigid body however before we set up the rigid body we should actually add some ground in so i'm going to be using the pixel adventure pack to set up some basic tiles and then in the next video we'll add the rigid body we're doing it in this order because if we add the rigid body without having tiles or ground beneath the character it's just going to fall off the screen and that'll be a mess so let's go ahead and add some tiles to our game so inside of the terrain folder for pixel adventure which we grabbed at the start of the series you can see that they have a bunch of different tile sets for creating levels so what we're going to do is change the sprite mode from single to multiple the filter mode from the linear to point and the compression from normal to none having the correct settings here for a pixel art game next i'm going to go into the sprite editor and we're going to slice all of these by the cell size so we can see by the name of this file that it is 16 by 16 for each square so i'm going to put in pixel size 16 by 16 slice it and we should get a perfect slice of all of the tiles that actually have some pixel information there note that unity ignores the places that have blank space which is handy because those would be useless tiles so let's go ahead and apply here and now we have all of these sprite squares that we can use as tiles inside of our game so to create a tile map we're going to right click in the scene hierarchy go down to 2d object tile map and then that's going to add a tile grid let's see if we can double click out for that and yeah if you're looking at grid and then player you can see that there is a tile grid here now so currently for the game everything is set at 100 pixels per unit um for the characters and this is like a 30 by 30 pixel sprite so of course it's much smaller than an actual game unit so once again you can change your sprites and the pixels per unit to a lower value like 16 if you want them to appear bigger another option is to go into the grid and then change the cell size to reflect the size of the tile squares so in this case it's 16 pixel tiles 100 pixels per unit so we want 0.16 for the x cell size and 0.16 for the y cell size and now the squares should be much closer in line with the size of our character over there if we click on tile map now you won't see any area to really edit the tiles and take those sprites and put them in it's actually a separate window so we need to go to window and then let's see and then go down to 2d tile palette and we can put this somewhere i like to have it next to the inspector so we need to create a tile palette and then using that we draw onto the tile map which is inside of the grid so let's go find the terrain here so right now we're in the terrain folder we need to create a new palette in the tile palette window so let's go ahead and give it a name i'll call it pixel adventure tiles i think we can leave the cell size to automatic for right now uh though i'm not sure if that needs to be changed we'll see what happens and let's just save the tile palette inside the folder with our assets here and so now we need to give a place for the tile palettes you could put it in the folder where you imported the art assets or you can create a new folder for these kinds of things so i'll just create a new one for now i'll call it palettes or tile palettes and then select that okay so now we have pixel adventure tiles which exists in that palettes folder and we can drag this entire sprite sheet with all of its items just by grabbing the original image and if we drag this onto the grid here it's going to it's going to try to automatically generate tiles with the exact same placements as that sprite sheet uh so once again i guess i will put it into the tile palettes folder i'll create a new folder here called tiles because it's going to create a lot of files and we can organize it a bit more later but let's select the folder there and you should see all of the items being imported into this palette it may take a while in this case because there's actually a lot of them you can see 144 squares or tiles being created and we can see um the sprite sheet imported correctly here now if we go to selection mode we can click on any of these tiles and then we can paint onto a tile map so this is going to be really handy we can zoom in make sure you're on greater tile map and then we can go into paint mode with tile palette so that's the paint brush over here and you can start drawing with any of these squares that you want i guess i'll use these metal tiles with the darker color here so i'm just going to left click hold drag it around and paint some tiles onto the scene we can also switch to a different square so this one which sits above is going to be used for the top tiles this one on the far right for the corner edge on the right and then this one for the left corner we also need to use these for the left edges you can see how there's that black outline so that is important otherwise it won't look right and then this is the bottom right corner this is the bottom left corner and then this is the bottom so by using these tiles we've created a simple platform which our character can stand on now uh right now there's no collider for these tiles so if we were to add a rigid body collider to our character he would simply fall through them so we need to go back to the inspector for the tile map and add a new component in called a tilemap collider 2d so tilemap collider 2d and once you add that in you'll see that there is now a square drawn around every single one of these tiles and just like that the collisions for the tile map are going to work correctly as long as the character is also set up right so in other words we have ground that we can stand on now worth noting here if you wanted to create tiles possibly background tiles on a separate tile map then you can just create a tile map and not add a tile map collider so that a character can move through them because you wouldn't want the background to block a character but you would want to add some background in to make the scene more interesting so just know if you want it to interact with the player have a tilemap collider otherwise you don't need it so that's going to be it for this in between video on setting up a simple tile map inside of your unity project in the next one we'll set up the platform of rigid body so now that we have ground that our character can stand on thanks to the tilemap collider that we created in the last video we can go ahead and add a rigid body to our character and have him fall to the ground so let's do that as well as setting up the left and right movement for our character so on our player game object i'll go into the prefab here with the arrow button and let's add a rigid body 2d to our character so we're going to leave it in dynamic mode what it means by dynamic mode is that it's going to take full advantage of the unity physics engine you apply forces to the rigid body and then unity calculates the rest for things such as what that character should collide into where it should stop sliding along the ground or edges so in dynamic mode it's much easier to move your character along properly without it getting stuck there's also kinematic mode which you manually move the position of the character in code and the problem is then that you have to set up collision detection and do all of that manually so kinematic mode tends to be a lot more work but if you wanted the character to interact with physics in a way that isn't standard then you might want to switch to kinematic mode personally i would think more on using it for things like a moving platform where it does move but not in the standard way a character would and then there is static body types for things that never move for instance a good example of that would be the tile objects down here now we don't attach a rigid body to the tile map directly but if we had a rigid body for each square it would be in static mode because they never move so we have dynamic mode set here there's a few options that are going to be relevant for the series linear drag when you want a character to slow down faster you can increase the drag it's similar to having friction except it also applies in the air at all times basically whenever the character's not moving the higher the linear drag the quicker it's going to return to zero velocity and then we have gravity scale down here so in unity uh they have gravity applied at negative 9.81 units so we can see in the project settings physics 2d gravity y negative 9.81 so the gravity scale here is like a multiplier on that so if you want normal gravity you would have the gravity scale at 1.0 if you want it to be more like moonwalking where the gravity doesn't affect the character as strongly then you can lower the gravity scale down further or if you want it to be affected by gravity more so you can increase the gravity scale so if you have a very floaty character having a lower gravity scale might be interesting the other thing that's relevant to us right now is going to be constraints so in constraints uh as we apply forces to the character we can limit what directions it can move so freeze rotation is going to be important for a character that stands upright because imagine there was a force coming at the character from something like the top right and it was pushing at it from here we wouldn't want the character to roll like a ball over the edge we would just want to push it back but not rotate it so for platformer characters you're probably going to want freeze rotation assigned with a z mark checked okay the other thing we're going to need is a collider attached to this character so the rigid body exists but there's no collider to detect when it collides into anything so that it can interact with the physics engine properly so we need to add component and pick out a collider so i think capsule collider 2d is going to work really nicely here so when we add that you can see we have something of an oval shape the difference between a capsule collider and circle collider is that it doesn't need to be a perfect circle it can be any oval shape so let's edit the collider here and then i'm going to bring these edges in uh for left right and top until it fits our character uh significantly better so looking at this it's a pretty good representation of where our character's body parts would be good enough for a 2d game like this anyway so let's turn off edit collider and you'll see here that i have a plus mark assigned to the capsule collider because i'm editing this on the copy of the prefab not the original so i want to make sure that this actually applies to the original as well so i'm going to click on these three dots go to add a component and choose apply to prefab player whenever you see that plus sign that means you added something on from the original prefab and you can also have minus for when you've removed something that the original prefab had so we're leaving is trigger off because this collider is something we want to use directly for uh basic physics in the game you can also have trigger colliders when you want a zone that objects can enter but not collide with but we are wanting this to collide we want the rigid body to be able to collide with the ground so that it stays there so let's go ahead and hit play now and uh probably the thing we're gonna notice is that the gravity is really really fast here so i can move my character up here and then when i hit play you'll still see it hits the ground very very fast because the gravity is set to 9.8 units right so each of the units in the game right now are really big compared to the size of the character and the tile map here and i think i actually want to change that i've been mentioning it a few times but let's actually go ahead and correct it so that the character is more like one or two units big rather than a fraction of a unit having it to 100 pixels per unit is nice in the sense that you know that every .01 is one pixel but i think i prefer it the other way so i'm going to click on our assets such as this terrain we edited and i'm going to change the pixels per unit to 16 and hit apply so that means that every square we draw from the palette is actually one unit in game so we're going to change the grid size to one because one unit is now 16 pixels for this background terrain and we'll also change it to one for cell size so now you can see that our tile map squares perfectly line up with the grid every square is one unit and maybe you find that makes more sense we can also go to the player sprites so in virtual guy i'm just gonna select all of these and change the pixels per unit to 16 and hit apply and our character should get much much bigger so since we're scaling everything up we also need to apply that to the camera so with the camera i might make the size 5 or so and for the pixel perfect camera asset pixels per unit we also want to make that 16. so the important thing is that we're consistent so if we're using 16 pixels for our pixel art we should probably just use that for all of the art we bring into the game so if we do that we can see in game mode it renders pretty nicely still and we can hit play let's go ahead and do that again and you can see that the gravity is now much more reasonable at its negative 9.8 units though you can also go up to edit project settings and customize the gravity so you don't have to reduce the pixels per unit you could just lower down the gravity it whichever way you like it so let's check out our player once again and we can see that the capsule collider is now way too small so we're gonna just need to edit the capsule collider and let's actually do that on the prefab so clicking on the prefab arrow and the hierarchy this will just make sure that all of the edits propagate across all copies of the character so let's go ahead and set these bounds here so left bound bottom bound and top bound the one that's probably going to be most important is the bottom bound we're going to want to make sure this lines up really nicely with our actual pixels so something like that and i might manually adjust the sizes here as well so this is almost negative point two six so let's put it at that this is one point seven and we're going to have the offset of x be 0 of course and then the y 1.48 and i think it's just a little better to have more precise numbers like that so it's a little more readable okay so now we can go back to the scene we can see our capsule collider fits our character properly and if we hit play he should fall to the ground smoothly and land right on top of it and that's what we want to see okay so i think the last thing we need to do for this video is to actually add left and right movement to our player now we could write all that into the player import script but as we build a platformer controller with many different states if we try to cram all of our logic code into one player import or player movement script it's going to get kind of messy so what i like to do is let's open the uh window animation animator here is for the states or sub state machines sub state machines being a state machine within a state machine you can actually add behavior scripts to those states so what you can do is only allow the character to move when it's in the run state or any state that has the same script attached to it so you don't need to do logic checking directly in these scripts for whether it's on the ground or not because you would assume that by entering that state and being in that state that your other code has already determined that it should be in the correct state so all you need to do is assume it's in the run state so it should be able to have these behaviors and by separating it into these little scripts i think it's just a little bit easier to go through your code and figure out where your problems might be for instance if you're trying to figure out why there's some weird behavior in the run state you just need to go to the run state and look at all the behaviors that are attached there and look through that rather than all of the code that applies to your player so let's go over to the player script though and we'll add a little bit more into the player endpoint so i'm going to edit this script here now of course there's going to be many different ways that you can do this precisely but what i'm going to do is have the behaviors on the state machine edit the values the parameters of that animator and then in this import script i'll just take those values that the behavior scripts manipulated take them and apply them as a force to the player so the forces will still apply here but the logic on how we get to the values which should be applied as a force exist within those behavior states now once again i'm not sure if that's the perfect way to do it but it's been working for me so uh we'll go with that for now so if we're going to want to do anything physics based we're going to want to do that on fixed update instead of just a normal update function so fixed update works a certain number of times per second i think it's set to 50 per second by default though that is an editable value and the idea is all of your physics updates are going to be around the same number of times and uh this helps to make them more consistent and it's recommended that all of your physics processes uh apply the same number of times per second and having everything that is physics-based being fixed update is how you guarantee that because fixed update will run as fixed number of times per second okay so what we'll do in void fixed update is get values back from the animator parameters so i'll do git flow and i guess we'll call it uh force x so this will be the amount of force that we should apply to a character over one second of time uh of course when we're applying this in fixed update we'll do it multiplied by time dot delta time and we'll also get another value called impulse y so this will be for jumping when we want to apply a force as an impulse everything gets applied at once and time is independent of that so that's why i'm going to call this impulse and that force x so you might notice we're getting a lot of string values here and these string values do need to be precisely consistent across our scripts so what i found is a pretty handy idea is to actually store these string values in a separate static class and then reference that same static class from both our player import and all of the behavior scripts that we're going to attach to this different states in the state machine so let's go ahead and do that so i'm going to open up assets and i'll just put this in the default directory for right now right click new file and then i'll call this pap player animation parameters you can call it whatever you want it's just going to be an easier acronym to reference than uh typing out the full text at once so pip.cs and in here i'm going to give it public static class pap then give it the brackets so i'll write it a little comment here player animation parameters so for any parameter that we're going to put into the animator here we're going to want the name stored as a value here and then if you need to make sure that the value in here is the same as here you only need to check one file rather than every single file so let's start writing down some variables i'll do public uh constant move x and then we'll give that the name move x and then we'll do public oh well we also need to give them a type so public constant string public constant string is moving equals is moving and then let's grab the other values from here so we could make this a string the axis name so i guess i'll call it axis x input and that'll be the horizontal parameter so let's see anything else we can rename uh we have move x we have is moving so let's add in force x and impulse y so public constant string force x equals force x and then public constant string impulse y is impulse y so now what we can do is reference this class so i'm just going to replace all of these hard-coded string values with our new class okay so i want to make sure that this is actually picked up by the unity project as well so let's click back into the project we should see the asset database refresh here and make sure that the file is in here pap so let's go back into player input and see if we can reference that okay so pip and now we just need to put the variable name and anytime we change the variable inside that player animation parameters class it's going to be updated across anywhere we reference it so change once fixed for everything so let's see player player animation pap dot axis x input and then here we'll have p a p dot move x p a p dot is moving p a p dot force x and then p i p dot impulse y okay and now we've cleaned up all of our hard-coded strings and we only need to edit it here if we ever need to edit it again so in fixed update we're going to get the force x we need to set that to a variable so i'll just call it float force x equals that and then we'll do float impulse y equals animator dot get float and pulse y so i guess we'll say if impulse y does not equal zero then we'll apply it to the rigid body so to do that we need to get the rigid body of course let's do a void start and then up here we'll do private rigid body 2d rigid body 2d rb for rigid body semicolon and then rb and then down in start rb equals git component rigid body 2d so as long as there's a rigid body attached to the character which this should always be then we'll get that here and we'll use it in our code down here so we need to apply the impulse y to the rigid body so we do rigidbody.addforce and it's a vector2 so we're creating a vector2 with the flow in the y so it's going to be 0 for x and then impulse y and then we need to add comma and change the force mode to d to impulse okay and then semicolon at the end there so very similarly for force x pretty much the same thing we can do if force x does not equal zero then rb add force and then we'll have a new vector two here with force x and zero for impulse y and it defaults to force mode force so we don't actually need to have that extra parameter there though you could put it there if you want now if in the script we ever want to get a y force that isn't a jump then we could basically do the same thing animator.getfloat and then add that to the vector here as it adds to the character on every frame but in this series i don't think we're going to actually have a constantly applied force y our jumping is handled by impulse and i think that's all we need but what we do need here for the add force is to actually multiply it by time dot delta time this force is being applied over time so we need to apply the right amount of force for the duration since the last frame of time just in case they're inconsistent and in fixed update yeah it should be consistent they should all have the same frame time but just in case they're not uh this guarantees it so that's going to be it for our movement we just need a script that's going to set this force x value properly and then this will pick it up from the animator so let's close out of this and go over to our animator window now we need to add in the extra parameters that we created so i'm going to add a new float and this float is going to be force x and then add a new float impulse y and we can also just verify that those are the correct names by going over to the pap file once just make sure that they're the same here that's the only verification you'll need to do okay so now i guess we just need a behavior script that depending on the import which we feed in which we've already done move x set here then we can set a force that the character should apply in the x direction over time so let's add a new behavior script because we might reuse this for other states that aren't run i'll call it player horizontal movement and maybe behavior at the end to specify that it's meant to be in these state machines as a behavior file and we'll create a new script for it so let's create an ad and now we can edit the script so inside of a state machine behavior you're going to get a lot of these overridden functions that may look a little different from your standard monobehaviour script so these are really handy because you can have certain things happen as the character enters the state leaves the state or stays consistently within the state so for instance if you had a state where you wanted to stop movement you could do that with on state enter so in this case what we're going to need to do is to control the force x that should be applied to the character i think we're going to need it to set to force x equals zero at the end here on state exit so on state exit what we can do is set the force x equals to zero so that once it exits this state uh the force should no longer apply to the object so let's say animator dot set per set float rather and we'll give it rather than the string name we can actually use p ap here so force x and then we'll set the value for that to zero okay so you can see the handiness of having your strings in another file like this we don't need to remember what we called it because we can just reference the variable rather than the exact string okay now let's do on state update so on state update we're going to want to get the import movex that the player imports set on the animator and then we just pull the value for that so let's do animator dot get float and we'll do pap.movex and we're going to set that to a variable value we might actually need to reference it outside of the function later so let's do float move x and then we can set that to the value we get back from the animator next we need to figure out the amount of force that we're going to be applying so let's go ahead and make a public so let's go ahead and make a public speed variable for the characters run so public public float run speed and i don't know how it's going to turn out let's just default it to 10 and then we'll edit it as we need so what we're going to do is to set the new force x value okay so the move x value can be anywhere from negative 1 to 1 here because in the player input we did get access raw the value should immediately jump from negative one to one on a keyboard as soon as we press the key down if we did get access it would accelerate to those values over time um but we can just change this to get axis if we ever want an acceleration style movement rather than a constant movement speed so let's actually um just multiply it in here by the value it's actually set and then store that as the force x so let's do animator dot set float and we'll do p i p dot force x is going to be move x times the run speed and semicolon i think that might actually be it okay and then let's move x we're going to pull that in here git flow force x and then of course the code we created is only going to run when it's in the play run state now we don't have to put it directly onto player run we could also have like a ground state for instance okay so let's go ahead and test it now so play mode we hit left and right so i think what might be happening here is that the run speed is set way too low so i'm going to try bumping that up to 200 or so and let's see what happens so hit play okay and now we can see the characters actually moving but very very very slowly so let's make that a thousand the numbers are pretty much arbitrary so let's go to play here so that's probably a lot closer to what we want though i would say the character is sliding around way too much so there's a couple areas we can change things for where a character should um slow down as it stops moving one is linear drag and then the other is physics materials so in physics materials you can add friction and that can be on the grid as well as the player with linear drag however if you increase it it will in fact drastically increase the rate at which the character slows down as well as reducing the impact that the force has on the character to begin with but that also applies when it's in the air so that might not be what we're looking for so i'm going to exit play mode there and what we'll do is try adding some friction to the tile map so physics materials are really simple we can uh create one inside of the root of our project i'll do it in a folder i'll just do create folder and let's just call it physics materials why not enter the folder let's right click create and then let's do physics material 2d so you can see by default friction of 0.4 bounciness of 0. we don't need bounciness because the character isn't going to bounce around like a ball so let's uh see what happens when we actually add the physics material to our character and we can just call this player physics material okay and also right click and apply it to the prefab so let's hit play and see how that changes things okay so not too much yet let's go to the tile map and let's also add in a new physics material here so physics material 2d and i'll call this standard ground and let's go to the tile map and we'll add in the physics material so this also has a friction of 0.4 let's hit play and see what happens okay so we can see still very sliding let's go to the standard ground material and make it much higher so let's try 0.9 now and hit play can also make the player 0.9 so this is the bit where you're going to have some fine tuning of the numbers we could add a little bit of linear drag here though that's also going to affect the air movement so i don't want to have too much of that let's hit play and this should slow the character down a little bit as well as the amount of force that really gets applied to it should slow down as well but it's still very slidy so maybe i'll just take the friction of the ground and make that much higher let's try a value of two and we're getting much closer to the amount of sliding that we'd actually want maybe we could even go a little bit further than that but uh one thing i do want to change before the video is over is add a little script so that depending on the direction the character is traveling uh we're actually gonna flip the direction which the character is displaying around so in animator i'm going to left click here so on the base layer i want to add a behavior and i'll call this player flip new script create an ad let's edit the script here and as long as it is in this state machine what we're going to do is uh i guess we'll use the move x value for this so we'll do animator dot get then pap.movex and then we'll have this assigned to a move x float and if it's positive then we're going to have the character facing to the right if if it's negative then it's going to be facing to the left and so how we can flip the character is by doing animator.transform.localscale and we're going to set this to a new vector3 and we'll do one one one else if movex is less than zero then we'll do animator.transform.localscale equals new vector3 negative one one one and uh before all that will actually do if move x equals zero then we'll just do nothing so this is actually going to become a else if and we'll move it up there so uh we'll just check if move x is zero so there may be a lot of times when a character's just idling there so i guess it makes sense to put that check first and then just ignore the rest of the code if that's the case so if i'm right i guess that's gonna work so as long as the move x value is being set then the character should flip around depending on if it's moving to the left or moving to the right so let's go ahead and test that here play mode okay so we have moving to the right and then left we move to the left so the local scale is being set correctly and our character flips perfectly and doing it this way is also good because if you flip the transform then that's also going to apply anything that's based off of that transform such as if you create a projectile that's launching from the character well if you flip the transform now it's going to be coming out of the left side rather than the right side so that's the advantage of actually controlling the transform rather than just flipping the sprite renderer which obviously would work visually but not when other things depend on the transform so at this point we have a character that can run around inside of our game he's a little bit slighty but that is just a matter of changing the numbers maybe adding more friction or linear drag overall our character works pretty good and is affected by gravity so that's cool so i hope you guys are still following along well and i will see you all in my next video so in this video we're going to be taking our run in idle states grouping them into a ground state layer and then we'll also be adding in the aerial states which are going to include jumping and falling as well as double jumping and then in the following video we'll add wall sliding as well so inside of our animator window we have player idle and player run so what we want to do now is to combine these into one group and the advantage of doing that is going to be that if we want to add a animation behavior to all states that are concerned with the ground or all states concerned with the air so we're going to want to take our idle and run layer and group them inside of a sub state machine to create that we right click on the node graph and go to create substate machine so i'm going to select this and call it ground so with the substate machine we can double click into it and you end up with a state machine inside of a state machine so just like on the outer state machine we can add animation behaviors like player flip behavior here we can also double click into ground and add behaviors at this level so if there's an animation behavior at this ground level it applies to every state inside of the sub state machine so i'm going to click on the base layer to go back out and i'm going to take the player idle on player run i'm going to control c go into the ground layer and control v paste it in so now these states exist inside of the substate machine i'm going to take the entry point right click on it and make the state machine default state to idle it probably doesn't matter because the uh state machine is automatically going to be switching between idle and move whether it's moving or not already but this is generally how i prefer to set it up so now i'm going to go back to the base layer now we're going to take the entry point for the overall state machine and set ground as the default and within the ground state machine we choose player idle so when we hit play on the game idle is going to be the default state so now we can get rid of the original play run and player idle we don't need those anymore because they exist within this ground state so we can still double click and see that so in order to make it so that the player can move as long as it's within this ground substate machine and not need to add it to player idle and play run individually you can see that compared to the previous video i already have the player horizontal movement behavior script removed here instead of adding it to each item here individually we can just go to the base layer and add it to the substate machine the ground layer so i'm going to add the behavior here and we're going to do player horizontal movement behavior so let's take the script's default run speed and boost it up to a thousand so that our character can actually move properly i'm going to go ahead and hit play here and we can see that we can move left and right pretty well once again and whether we are in idle or the run state we still have that movement script active so it allows us to move as long as we're within the ground substate machine okay so now we need to set up a way for our character to be able to enter the air so there's going to be two ways to do that one is basically falling off a cliff which is going to go right into a falling state or we can hit a jump key on our keyboard or we can hit a jump button which will allow our character to move upwards so let's go ahead and create a air substate machine to handle all of those falling and jumping states i'm going to create a substate machine here and i'm going to call this air let's start by double clicking into air and we can create a couple new states so let's right click and create a new empty state and i'm going to call this playerunderscore falling and let's create a new state so let's call this one player jump and then after we have jump working we'll also want to create a double jump state which is going to have some different variables set maybe you want to play a different animation on the double jump or maybe you want the double jump to have different values and how much you can jump on the second jump so in any case it's not a bad idea to create a second jump state rather than just allowing the character to jump twice within the normal jump state so let's pull these down and i'll right click add a new state and i'm going to call this player double jump so now we need to go back into the ground sub state machine i'm going to double click in there and we need to set some exit points for these states in here so one way that we would want to enter the air is if the character basically walks off the edge so it would not be on the ground anymore so i'm going to take player idle here right click make a transition we're going to go to the exit here and the condition on this exit is if the player is not on the ground so is on ground false so i already have all of the other variables pre-created over here so if i talk about one and you don't have it already just go ahead and add it as a parameter using the same name so is on ground and we want that to be false so if the character is not standing on ground then it's going to be falling now let's do the same thing with player run so i'm going to make a transition exit here and that's going to be is on ground set to false okay now let's click back onto the base layer now we need to tell the substate machine how once it's exited from the ground substate machine how it can move over to air so we're just going to set another transition here if it's not on the ground then we're just going to go straight into falling so states player falling and as the condition here i will set is on ground set to false so for the falling sprite we're just going to be using this fall 32 by 32 sprite and we'll have a little animation created from that so back in my characters folder we can see i have player fall as an animation so let's click on the character and then we'll go to window animation uh let's see animation window and we can't see it in here because it's actually not assigned to the animation state node yet so let's actually move this down here so it's kind of out of the way go back to the animator and for player falling i'm going to set that animation motion to player fall so now if we go to animation we should see it pop in here so player fall just a single sprite the one i was talking about if we hit play well that's what it's going to look like so i've gone ahead and added some extra terrain here i'm just going to move this character over here to the left so that we have somewhere for it to fall off of okay so let's go ahead and test the following animation i'm going to move our character up here to the top left so that we can fall to the ground and then go over to the left some more so i'm going to play here character is going to be on the ground and we go off the edge and we do get to that falling state but there's an exit time associated with that and we probably don't want that so let's go back to the animator window go to the ground state and take a look at these exits and make sure that the exit time is toggled off so that the transition can be instant when it starts falling so let's go ahead and hit play now and this time the character is going to immediately transition into the falling state but we have another problem which is now there's no way for it to exit when the character is on the ground again so we need to basically do the same thing in reverse so going back to the base layer and then air we're going to want to show the animator how it can land and then transition back to the ground so basically as long as it's in the air if the character ends up on the ground at any point in time we don't really care what state it is we want it to land so we can use this any state node over here in order to make that transition into landing and then to the exit so i'm going to create a new state here i'm going to tell any state to go here and this is under the condition that is on ground is true so is on ground is true so it can enter this state and we're going to call it playerunderscore landing and then this is going to go to the exit i don't think we need to add an extra condition here for the exit because um is on ground has already been checked so after the player is done landing i don't think we need to check for it again so we'll leave it like that for right now so now we need to give this a motion so depending on how your sprite character was animated there may actually be a motion for the player landing a few frames of animation to make that transition look a little smoother in this case this character does not have one so we can actually just have the landing state exist without having an extra motion here so for right now we might not need to really do anything with the landing other than allow it to exit back to the ground but for now let's actually go ahead and add a player landing behavior so i'm not going to do anything with this yet but i think we're going to need it later on so just for now we'll just have it kind of blink there so at this point from any state as long as the character enters the ground then the player landing behavior can allow it to transition outwards so let's go back to the base layer so from the air we want to go to the ground let's just say state machine ground don't think we need to be more specific than that really with this transition we might as well just tell the ground to go to the air and then from air we can actually pick out what the correct entry point should be so i'm going to change this to be ground to air and let's do state machine air instead of ground straight into falling and the conditions here let's just set is on ground is false once again so the top transition is is on ground true and the bottom one from ground to air is is on ground false so now when the character is back on the ground it should transition into the player idle here but we have the ability to change this little entry point if for some reason we ever wanted to have a different default so let's go back out and see if we can kind of test that out so when we hit play the character goes back to the ground here let's see where we actually at so we're getting stuck on the player landing here the issue is that any state can transition into player landing and the only condition is that is on ground is true so technically player landing is just looping back into player landing so we'll need an extra condition for this to work so that uh once it enters player landing that it can't enter player landing again until it comes back into this cycle of being in the air so let's set up that in the code so for this bit we're going to be using a trigger and in order to enter the landing state we're going to need this trigger to be set so as soon as we enter the landing state we reset this trigger so it won't go back into here so presumably you don't already have this so back in the pap file you can create a string for this so public const string landed on ground equals landed on ground and we'll use that as the trigger name so if this code is going to reset the trigger then we need a place where the trigger is going to be set so back on player input we need to have a few checks in order to set that landing condition the landed on ground trigger so we're going to be checking for two things so the first condition we're going to check is whether on the last update cycle the character was on the ground and we do that by using animator.gitbullpap.onground essentially checking if it was already on the ground when we go through this update function and then we need to check if on this update cycle if the character is already on the ground so in the last videos we should have already had this bit so now we just come in here we take those conditions and we determine whether or not it qualifies as the character having landed on the ground so if it wasn't on the ground before and now it is on the ground then presumably we're in the air and then we hit the ground so we're landing so we have to set that trigger and since we're using parameters of the animator we have to make sure that that parameter is once again set on the animator parameters down here we have landed on ground as a trigger so this is going to be when the character hits the ground and that's going to be unset as soon as the landing consumes that trigger the last thing we need for all that to work is just to add a secondary condition from any state to player landing so we're going to be checking for that landed on ground trigger the is on ground check here might actually be redundant uh landed on ground kind of already implies that but um let's just leave it there for right now and let's make sure this works so we should be able to now transition back on to the ground okay so let's go ahead and hit play and it should be working now so let's go ahead and hit play real quick it's going to start in the falling state since the character is above ground and then it's going to transition into landing and then back to the ground so now you can see that the landing only happens once because that landed on ground trigger is required in order to enter the player landing site so we exit the air properly and now we can move around left to and right as we desire if we go off the edge you may notice that our character can't control its movement anymore so we have the option of adding the player horizontal movement behavior to the air as well so this is going to be kind of more of a preference point do you want the character to be able to control its direction watts and the air so if you do then we just go out to the base layer click on the air layer and let's add a behavior play a horizontal movement behavior so on the ground we have it set to a thousand but in the air we may only need it to be something like 300 so our character has friction with the ground when it's not in this dynamic rigid body mode so in order to move the character you need more movement power on the ground than you would in the air because the air is not going to have any friction or air resistance by default so let's go ahead and hit play we might just need it to be at 300 or perhaps even less than that so if we fall off the edge here we're in the air but we can still move left and right if we want to control our character so maybe we want a little more than that could set it to 500 okay and then we go left and right so so you can kind of determine for yourself how much run speed you need in the air you can also rename the variable if it doesn't make any sense for it to be run speed when you actually are in the air as well but you can reuse the same script and multiple states or multiple sub-state machines and just change the values on it if you want it to behave similarly just with different values in terms of its power okay now we need a rising state and we need to have scripts for the jump and double jump so let's do the simplest one first which is going to be creating player rising so i'm going to right click on the graph in air so create an empty and we're going to call it player rising so when you would want to play the rising animation is when the character's velocity is going upwards and it should be falling when it's going downwards due to whatever forces are acting on it so gravity would be the obvious one but in your game you might make it so that there's other actors that could change its velocity such as running into a projectile and it actually affects your character's movement as well so with player rising here we need emotion so i am going to use player jump here so if we take a look at the character art let's go to virtual guide here so we can see that the jump animation is actually just a single frame of the character moving upwards so we can use that for the jump motion but also for the rising motion so with player rising we're gonna assign player jump as the motion here if we click on our character and we change to player jump we can see it's just simply setting that single frame if we hit play we can see our character showing the rising state or the jump state so now we just need the conditions for when it should switch between rising and falling super simple just going to be looking at the velocity y here so i'm going to make the transition to player falling and then play falling to player rising so we're going to have no exit time on both of these and we need to add the condition checking for velocity y so off the top of my head i'm not 100 sure if uh positive y is going up or down on the screen so we'll just try one way and then if that doesn't work we just flip it so let's see if the player is falling well we would presume that that would be uh below zero velocity as in it's going downwards so then let's put the opposite over here plus sign velocity y and greater than zero would be rising i i could very easily have that mixed up but it's just a simple test this should be all we need to test it for right now so let's just keep this open here down here and then we'll see if we enter the player rising properly okay so we should stay in player falling here and the velocity is definitely negative there okay so i do have it right so in this case negative and unity is going to be going down so the player jump and player double jump are going to need behaviors so i'm going to add a behavior over here let's call it player jump behavior and then i'm actually just going to add another player jump behavior for the top script as well and for player double jump you could write a completely different behavior script but i'm going to see if we can just reuse player jump behavior and then change the values if we need to so for you just go ahead and create the player jump behavior and we'll get into the contents of the script in a second here and for motion we're going to set player jump here and then at the top we're gonna have player double jump so the double jump motion we can see in the virtual guy our assets there's actually a separate jump for here so that's why we're using a separate motion so just one motion for this jump down here and then one motion for the double jump play a different animation so before we dive into the player jump behavior script here let's set up the graph for how we can transition into player jump so for this character how i'm going to set it up is that the player can only enter the normal jump if it is coming from an outside state like the ground so i'm going to set up this character is that he can only do a normal jump if he is on the ground so that means that the entry point for this player jump is actually going to be coming from outside of the aerial graph and then after the jump animation is done playing we're just going to transition back into player rising so that the animator can go between player rising and player falling as the velocity is above or below zero so let's make the transition to player rising here so this is going to be pretty simple so for this transition because our animation is a single frame we might as well just transition to player rising immediately so i'm going to uncheck the exit time on the transition there and that should be all we need now if you have a jump that has multiple frames of animation you might actually want to set it exit time so that most or all of those animation frames of the jump have already occurred before you go enter play rising but in this case it's a single frame so we're just moving straight into this state now we just need to set the outside conditions for how we can enter player jump so i'm going to go back to the base layer and then to ground and from player run or player idle we're going to set the option to jump so i'm going to right click here make a transition we're going to target up base layer and then states air and then jump and then the same thing with player idle make a transition up layer states air jump and the condition for this is going to be that the jump key has been pressed uh so this is a trigger and we can do it whether the character is running or idling so now if we go back to base layer we can see that the transition already comes here from the ground back into player jump and we can see that the condition here is jump so i think we actually want to uncheck the exit time for both of these transitions so that the jumping can be immediate so you can be running on one frame and then immediately jump into the air so you end up with an instant response time so now we have the condition for how to enter player jump and player jump will immediately go to rising after it runs this little player jump behavior now let's go ahead and take a look at the player jump behavior so i'm going to edit the script here and we have a few variables in here so jump impulse is going to be the force of the jump so this bit here about the wall push impulse we'll talk about that more in the next video about wall jumping so what we need to be concerned about here is on state enter we set the jump impulse variable impulse y and the animator and that is going to be consumed in the movement script the player import script in order to make the jump actually occur and then this bit is also related to the wall jumping so really all we need for this video is the jump impulse and setting the animator value for the player input to consume so back in player import let's see if we can find the jump bit so in order for the character to jump we need to check if the jump key is down so in this case the name of the key is jump j-u-m-p and you can set that up if you haven't already by going up to edit and then project settings so we go down here to import manager and we can see that the jump key name is called jump as well so that's where we get the variable name from so we check if jump is down if jump is down then we set the trigger for the jump so the jump trigger name is jump lowercase and if it's not then we reset the trigger so we unset the jump trigger so that it can't be consumed as a jump so a character will only jump on the frames where you are pressing the jump button down so the jump trigger and therefore the jump will only occur on frames where you press the import button down now that also doesn't include holds it's only on the frames where you press the button down hence using input.getbuttondown so it's just at that single frame instant then down here in the physics script we get the impulse y from the animator so we set it in the jump behavior script and then we pour it back in in this fixed update and then that impulse y if there's any it gets included in the impulse vector for moving the character after consuming the impulse y we set the animator value for that back to zero so it doesn't get consumed again until another script sets it up and then right above that we add the impulse vector to the character so this is also going to include any x impulses but for right now we're just concerned about the jumping y impulses so that's basically all the script we need to have the jump move the character so let's go ahead and see if so let's go ahead and test it out so let's see if we can enter that jump state so i'm going to play here okay make sure of course you have the jump trigger and the parameters we hit space and there we get a jump so right now the jump impulse is really really high so we probably want to take that jump impulse and tone it down to something more like two let's go ahead and hit play again okay and that's too little with the gravity so let's go for something in the middle like five so i'm noticing that the player landing takes a long time to exit let's take the exit time here and set it to zero so that it can exit landing immediately after it processes its state entered script and then also taking the player jump impulse and setting it to 10 again we want the jumps to be a little bit better i'm also going to move the character back down here since we've already tested the following states we just need to check the jumping now so let's go ahead and hit space here so so far it's working for the most part we just have a couple little issues to fix so one thing is that player jump to player rising as a transition doesn't have any condition or exit time so that's not going to work we either need to have a condition or an exit time so i'm gonna check exit time and we can just set the exit time to zero and the transition duration to zero which should make it instantaneous and let it work without a condition so let's go ahead and hit play and let's see if we can have this transition back to player rising work again so i'm going to space and it enters player rising and as soon as the velocity starts going negative we start falling so that's making the jump work well there the player landing is still taking too long to transition out so let's fix that as well so maybe what we can set up for the condition here is to just check is on ground still is set to true and i'm gonna uncheck has exit time i think that should work so let's go ahead and hit play okay maybe we also need to take this transition and set the duration to zero let's see if that fixes it okay yeah actually i think that's what we needed yes okay now it seems to be working correctly so for a lot of these transitions for this kind of sprite character we want to make sure that those transitions are zero so that it can move to the right state immediately as a result of that we don't actually need this condition here since it seems like this was the transition that was causing the issue let's just do has exit time zero zero okay so now the movement is working much much better for the character this is how it should be uh now we just need one last thing which is to set up the double jump so the double jump is basically going to be like the player jump except we may want to change the jump impulse if we want the second jump to be weaker so we could say with this second jump impulse we could say eight the main other difference aside from the value there is going to be how the uh substate machine enters the double jump so when we want the double jump to be active is when the player is either rising or falling so the character is already in the aerial states and we want to just check if the jump key is pressed and if the character has already double jumped once or not so the character should only be able to double jump once per aerial cycle so in order to start jumping or double jumping again they're going to need to land back on the ground so that's where this parameter has double jumped occurred is going to be checked or unchecked so we need to make a transition from player rising to player double jump and player falling to player double jump as well so the condition for both of these is going to be has double jumped is set to false and is the jump button and is the jump trigger active so let's set that for both of them and then jump as the trigger and we want this to occur immediately so uncheck has exit time let's add the conditions for flowing back into rising and falling so make transition to rising so the player double jump animation actually has some frames we want to play so this is going to be one of the cases where we don't actually want the exit time to be immediate but rather once the player double jump animation has basically occurred so let's set that same transition up for player double jump to player falling so transition duration all set to zero there for the conditions if the velocity is above zero then we'll enter player rising so play rising uh greater than zero and then player double jump to player falling if it is less than zero so for the double jump we actually need to tell the animator that the double jump has occurred so we'll do that by setting an animated property and we'll change the player jump behavior here remove and we'll set up a different script player double jump behavior so it's essentially going to be the same thing except it has one extra line of code so i'm going to change the jump impulse there to 8 just like we had before let's edit the script so we can see here in this player double jump behavior we have the jump impulse and we set the jump impulse as a animator parameter but we also set the boolean has double jump occurred to true so when we enter the double jump we set that we have already double jumped and by using that we won't be able to double jump again until the character lands back on the ground and we reset that parameter now where are we going to set that parameter well that's going to be in the player landing behavior so the line we need here on state exit when the landing is done we set the parameter has double jumped and we set that to false so this is a boolean and we just need the parameter setup in the animator if we haven't already so has double jumped and that's going to be a boolean parameter so if you haven't added it in here yet then go ahead and add it as a boolean parameter and just make sure that the name matches up what you have in the scripts so save all your scripts and let's go ahead and hit play and see if it works so we hit play let's watch the has double jumped boolean and make sure it gets set properly so i'm going to hit space and then space to double jump okay the double jump does occur and due to the landing script when we land on the ground it's going to be on set which allows us to keep double jumping around the room one other thing we can test if i can get up here is going to be if we fall off the edge we should enter a double jump if we hit the jump button so it shouldn't go into the normal jump it should go into the double jump so i'll just slide off the edge here and hit space for that double jump animation and it works we don't enter the normal jump we enter the second jump but from the ground we can add space for a normal jump and then space again for our double jump so that is working as intended you may decide that you want to tweak the values a little bit if you feel like your character is jumping too high so that's going to be really easy at this point just go in there decrease the jumping pulse a little bit and you'll be good to go so in the next video we'll be adding a little bit more to this air substate machine by adding in wall jumping so there's one animation state we need to add and that is going to be wall sliding so i was thinking that we can add the wall slide state into the air state because we don't really want the character to transition into it when it's on the ground we do want gravity to affect it though we may want to apply a gravity penalty so that it slides slower when it's on the wall and then we can have the character be able to transition back into jump from the wall so that it can still do its double jump before we create the state though let's go ahead and create the animation for it so i'm going to open up project and then find the wall jump sprites inside of the imported pack and let's split it up inside of the sprite editor so let's go ahead and split it up either by cell size of 16 by 16 or cell count so count should be really easy here because it's obviously five so let's go ahead and apply that and now let's take this and put it in an animation so i'm going to click on our character i'm going to hit ctrl 6 to open up the animation window we'll click on the drop down create new clip and let's go ahead and store that in the characters folder since that's where i'm putting everything else so player wall slide and then bring the sprites in and then set the samples to 20. okay now we can click on our character and test the animation okay so it does look a little bit silly when the character is not moving at all but hopefully when we actually have some gravity playing it'll look a little better when it's on the wall so now let's go ahead and bring in the wall slide animation so since we added the clip as a new clip on the character a new state has been created with the motion added on we're gonna copy this into air so control c control v and we'll move it right about here i'll move landing out of the way but we're gonna want any state to be able to transition to this wall slide before we do that though let's delete the copy from the outer base layer go back in here organize things a little bit and now we want to set up the conditions for any state transitioning to wall slide so any state can go to wall slide if the character's on the wall so we're gonna need another boolean variable for that so like is on ground we want is on wall for organization purposes i'll move it up there closer to that first boolean okay and then we'll add that as a condition here so is on wall is equal to true now once the character is on the wall there's three possibilities that'll happen one it slides all the way down until it lands on the ground but that's already set up here with any state to landing with the landed on ground condition the other is that the character slides down until there's no more wall for it to grab on to but it doesn't reach the ground in which case we should have a transition to player fall so i'm going to set up this transition here make transition to player fall and the condition is going to be is set to false we're going to want to exit time for that and no transition duration as well for the i think for the initial transition to the wall we are not going to want any transition duration as well so i'm setting that to zero the third possibility is that the player presses jump while it's on the wall so we're going to make a transition here and the condition is going to be jump so basically if the jump trigger is active then we want to transition into a jump state the third possibility is that the jump button is going to be pressed so we can transition into player jump here when jump is pressed so let's go ahead and set that jump condition here so if jump is triggered then we're going to transition we don't need any exit time or duration as well so there's going to be a few things we need to set up about this jump so one thing is that we're going to need to make sure that the character actually jumps away from the wall not just straight up so that is wall is going to be set to false and the way we can do that is by having an x impulse added with the jump as well so the first thing that we're going to need to set up for this to work is to set the condition for when is on wall is going to be true or false and we'll do that back in the player import script so it's going to be very similar to when we checked is on ground first we're going to need to get the direction that the character is facing and then we're going to need to cast from the collider and see if it connects with anything that would be considered on the ground layer so i went ahead and wrote the script here in advance let's go ahead and walk through with it and then make some changes on the animator so that all of this works correctly okay so first off we're going to check if the character is on the wall and we'll get to that in a second and then if it is on the wall and then we set that boolean into the animator just like we did for is on ground so that is going to be a boolean stored on the animator that we can use in other scripts or transitions and so then we just need to come down here to check if on wall you'll notice that it's very very similar to the check if on ground script the main difference is we take a look at the local scale of the transform to determine which direction the character is facing so you might recall on the base layer of our animator we had a script set up called player flip and that player flip was setting the local scale of the character's transform to either be positive one on the x or negative one to flip the direction uh to face the left so taking those same values we can use that here the local scale and the x value of the local scale is either going to be positive or negative so taking the sign of that which is going to either return one if it's zero or greater or negative one if it's below zero we can multiply that by vector two dot right to rate cast in the right direction so if it's facing right up here this is going to return a value of one and one times a vector is just gonna be that vector and the vector is right direction otherwise if we get negative 1 here the negative 1 times the right vector is going to give us the left vector so aside from that it's the same stuff ground check filter we have wall hits as a list raycast 2d set up at the top just to store the list of hits that we find whenever we do a raycast and then we also have a variable for the raycast distance now i keep saying raycast so so here i'm making the call that it's probably better to do a raycast rather than casting the entire collider so if you do a collider cast what it's going to do is it's going to take the shape of the collider in this case like an oval shape and it's going to bring a copy of that downwards in the amount of distance for the ground check distance but if we do a full collider cast on the rigid body main collider what it's going to do going left and right is come in contact with something that would be the ground and call it a wall in many cases where we wouldn't really consider the character to be on the wall at all for instance if there is a minor slope going up at like a 10 degree angle this would collide with that if it was being cast in the left direction so what we can do instead is take a ray cast from the middle of the character from the middle of the collider rather cast that in the left and right direction and then that's going to mean that basically the character the character's height is split in half and the raycast i think comes from about right here and goes out to the left so much more accurate to where the hands could be in terms of grabbing the wall it wouldn't make sense if the raycast was coming from down here where if it was barely touching the wall only the foot would be touching the wall and the character really doesn't have anything to grab onto so it doesn't really make sense for it to be in a wall slide so that's why we're doing a raycast here rather than a full cast of the entire collider so the difference here is just instead of using dot cast use dot raycast but all of the parameters are otherwise the same so once we get the wall hits back we just check if it's greater than zero and if so then yes it's on the wall otherwise it's not so uh pretty simple but there is one problem here which is that any state actually allows you to pull in from states that would be cons so the problem with doing a any state transition to wall slide here is that any state means any state in the entire state machine including base layers or states coming from ground so when the character is on the ground but also on the wall it can go to the wall slide even with the raycast so let's hit play and see what happens here so hitting the ground it looked fine there and i think the reason for that is because of the switch to the raycast you can still get those cases where if there's a slope that raycast may be considering it to be the wall so you have to be careful there so we have the raycast check of this of 0.6 let's go over to the wall and okay maybe the raycast distance isn't long enough so the raycast is coming from the center of the collider that's why the distance needs to be longer but we get to the wall there with a 0.7 raycast wall distance and maybe we uh need to change the shape of the collider so that the character is closer to actually sticking on the wall so the problem here is that the character can just walk up to the wall and start grabbing it which isn't really standard behavior for platformers but we can fix that still um we just need to add another condition for the any state transition so we'll just add here is on ground is set to false let's go back in here and set the raycast wall distance to 0.7 and i'll apply that to the prefab what we can also do is go into the prefab here and change the shape of this oval so as things are right now the characters hands end up about here but the collider shape is bigger than that so we actually probably want to bring in this collider shape in so that it looks more accurate to our art edit the capsule collider bring in our values a little bit and then let's go ahead and hit play and test so when we get to the wall uh it's not actually finding it so maybe maybe sure maybe shrinking the raycast didn't mean that we need to increase the value here okay so with the 0.8 we can get to the wall but now that the character's on the ground and on the wall it doesn't actually go to this state which is more like what we would want so let's try to jump onto the wall okay so we get to the wall so we get to the wall here the character kind of slides down it due to the gravity though probably faster than we'd want on the wall um one problem is that the character kind of bounces off so what we'll need to do is actually stop the character's velocity when it gets to the wall okay so what we're going to need to do here on state enter is to set a boolean value which the player input can take a look at so we'll call it uh animator dot set boolean so with this the player input can see that stop velocity is set to true and then stop velocity on the rigid body so let's go ahead and take a look at that so we'll check is stop velocity whenever fixed update is run and we'll do animator dot get bool pap dot stop velocity okay so if is stop velocity then we want to take the rigid body and we'll set the velocity to zero or vector2.0 rather and i think that's about all we're going to need for that just make sure that the variable for the string is added to the strings list and that the stop velocity parameter is added to the animator okay let's go ahead and test it if the velocity does stop when the character gets onto the wall okay it does nice and you can see that the gravity already affects the character a lot less because we have the friction coming from the wall so as long as the character is actually hugging the wall it's going to slide down very very slowly okay so let's go ahead and test it and jump onto the wall so the velocity does stop we do have a problem though which is that it's stopping every single frame so stop velocity here is still set to true so we need to actually consume that boolean in a sense i would use triggers but for some reason there's no way to get if a trigger is set or not outside of the animator so let's um let's go to player input and then when this is set here then we also want to do animator dot set bull pap stop velocity so in a sense we created a trigger using booleans um which should work okay okay so let's see what happens now when we actually uh get onto the wall for the first time and we'll see how the gravity affects it okay so the character is sliding down now oh it still it still actually is set to true weird okay so here's actually the problem in the code right now any state can go to wall slide but we don't want wall slide to be able to go into wall slide using this transition so there's actually a setting here luckily that we can check off in order to make sure that if it's in the wall slide state it's not going to go back to the wall slide state over and over again which would be setting stop velocity to true basically on every frame so if we uncheck this then once it's in wall slide it can't make this transition anymore so it should only enter wall slide once until it actually until the wall slide actually leaves the state goes to something else and then the character gets back to the wall says things work right now pretty much it's working well the wall sliding goes to the bottom if you let go though it is possible for the character to fall off the wall that's the nature of the dynamic rigid body so the last thing we need to do is to make it so that when we're jumping from the player wall slide state that it actually launches off the wall and i think what we can do for that is rather than putting script inside the wall slide we'll just check if we're on the wall when we actually do the jump uh for player dot jump rather we can check it's on the wall and also not on the ground because it would be a little weird if it launched over here from the ground but let's go ahead and uh set that up inside of the jump script so in player jump behavior we're just going to check what kind of state the animator is in so animator dot get boolean pap dot is on wall and we want to make sure that's set to true and we'll also want to check get boolean pap is on ground and we want that to be set to false so if both of those conditions are true then we're also going to set a impulse x for the player input to consume so we can call this wall push impulse and let's give it a float value we can just start with uh 20f for now let's go ahead and add in a string for the impulse x and then in the player script we'll get the impulse x as well okay and we can put it or here if impulse x does not equal zero then we'll try to consume that as well add force new vector to oh okay actually rather we don't need that we can just put that into here so we only need to add the force once and so animator.setfloat well we want to do that for the x value as well since we're consuming both of them at this moment in time so impulse x and we'll set that equals to zero and uh that is pretty much all we're going to need there i think so let's go ahead and test it out with this wall push impulse so we hit play we get onto the wall hit spacebar uh well what happened is that the parameter doesn't exist so let's actually add that parameter add a float variable impulse x and move it up here okay let's try one more time okay so let's go ahead and hit play test it one more time jump at the wall hit space and the character goes flying off to the side which is close to what we want but that's probably a little extreme let's drop that wall impulse to something more like five and let's try again okay so character jumps at the wall we hit space to jump and it comes off the wall so what happens if we're holding left really closely to the wall we can still get that jump impulse so this seems to be pretty close to what we want we have our double jumping we can get to the wall jump off the wall do another double jump off the wall so from this point uh all the functionality is pretty much working we just need to perhaps customize the numbers a little bit so that our character moves in the patterns that we want having the right amount of impulse on each jump the right run speed the right amount of friction and also whether we want any linear drag on our character or not okay so one thing i do notice is that sometimes there are these cases where the character lands on the ground but doesn't necessarily actually transition to the landing state quite right so i think what might be the issue there is that the trigger is being reset here so i'm going to try taking this away from the player input script and then we're only going to consume that landed on ground inside of the player landing behavior so let's go ahead and open that up and then when we get to on enter here we'll do animator dots reset trigger pap dot landed on ground okay so now let's go ahead and clear the console and test all of that so i'm not seeing the issue anymore so hopefully that does fix that so here's another minor bug that needs fixing the wall jumping works fine when we do it from a left wall but when we go to a right wall you can see that it doesn't work because the force is being applied in the right direction still so what we need to do is apply the force in the right direction so what we can do here is that we can get the local scale of the transform and then check the direction of the x by using math sign so let's go ahead and get the float and we'll call it x direction sine equals transform.localscale.x and we'll get the math dot sign of that so math dot sign math f dot sign rather put all that in and we'll multiply that by the impulse here okay so this should work just fine uh for the wall jumps if you have any more impulses that would come from your scripts then you might want to change this a little bit but i think this should work fine for now so uh let's go ahead and get in there okay so let's jump onto the wall hit space for the input okay the only problem is that this impulse is positive so it's actually giving it uh in the wrong direction the reverse direction so back in the player jump behavior we can just take this wall push impulse and make it negative by default maybe i'll put in the tooltip generally should be negative so that it pushes in the reverse direction okay now let's go back to our player prefab and just make sure that the wall impulse is negative so okay right it's actually on the animator so player jump and we'll do negative five for the wall push impulse and we can see the little tool tip there so let's hit play and test it out okay so we jump on this wall space to jump off and we can get to this wall space to jump off so let's try wall jumping up here okay so now let's test if we can actually do the wall jumping one more thing i will add is i'm just gonna reset the trigger has double jumped inside of wall slide as well because if we enter the wall slide then we do want to allow the character to do a double jump again so let's reset that trigger p ap dot has double jumped and that should be everything we need there so let's go ahead and hit play and we can test it out again okay so first jump and we get a double jump and our character can double chomp double jump templeton and we can get pretty much all the way up there so that's pretty cool yeah so i think that just about fixes the bug so far one final thing i would recommend is that you tone down the wall raycast distance of your character so i have it at 0.55 here and that allows me to get it very crisp with the actual pixels of the character another thing you can look at doing is making sure that your capsule collider is set to values which are understandable so here i have 0 and 1 for the offset and size of x and then offset y is 0.25 and 1.5 for the y size what's important is to make sure that the bottom pixel aligns up nicely with the bottom of your capsule collider or any other collider that you decide to use for your body so that's pretty much going to wrap it up for the fixes i think need to be made once again if you want you can customize things such as the run force once again if you want you can customize things such as the run speed of your character you can change the friction on the physics materials for both the ground and the air and if you want you can try playing around with linear drag and seeing if that gives you movement that's close to what you're looking for so that's pretty much going to be it about setting up a platformer character inside of unity so thanks for watching this series to the end i've been chris and hopefully i'll see you guys in some of my future content so just a little bit of bonus content here i'm gonna build out a few more spaces for our 2d character to move around on using the pack the pixel adventure pack if we look in the background folder we can see that they actually added in some backgrounds that we can use for our games as well so to add this i'm going to use a 2d sprite and let's go ahead and try this brown one out here so what we're going to need to do is to tile this sprite and it needs to be set to full racked modes so when you click on your sprite that's meant to be a background you want to go to the mesh type and change that to full wrecked also going to go ahead and change the pixels per unit to 16 here since that's what we were setting for the course so let's just make everything consistent now we should be able to tile this background just by stretching it so let's go ahead and try that out here to make it the background we can put its order in layer as negative one or we can put it on a new sorting layer that sits behind everything else maybe we'll do that so let's go ahead and create a sorting layer here so i'll call this background and background is always going to be behind the default layer and everything else so for our new sprite gonna rename that background gonna position this at the top and we can actually just set the sorting layer to zero again as long as it is sorting layer background it's going to still be behind everything on the default layer so let's go ahead and drag this out here if we look in game mode we have the background filling pretty much everything so now let's just go ahead and add some extra tiles so we have the ground the tile palette and we do have some extra stuff we can go ahead and play with you so i'm just going to be placing some extra stuff into the scene and our character will be able to interact with it so let's just create a test box with ceilings and perhaps that's good enough for now so let's uh increase the height of our background let's just make it much much bigger than we need it to be so that the background is always showing and then we can go ahead and hit play and our character is going to be able to move around here now when we hit play in this game world you can see that the camera doesn't follow the player at all this is actually pretty easy to fix inside of unity because there is something called a cinema state machine so if we go up to window and then package manager we can take this drop down from in project to unity registry and put in cinema or just cena and you should be able to find the cinema state machine so what the cinema machine does is sets up a bunch of camera tools that you can use to make the movement of the camera uh smooth and easily controlled with minimum coding if any on your part so for instance one thing we can get is a smooth follow camera so once this is installed here then we'll get the cinema machine menu and what we're going to want is a virtual camera so i'm going to create a virtual camera there if you click back on your main camera you'll notice that a cinema machine brain has been created so the new cinema machine game object is basically going to control that camera in a sense and what we want to do is follow the player so i'm going to follow select the transform of the player and now when we hit play we should get some follow camera movement going on okay so yeah just like that we have a working follow camera how cool is that actually
Info
Channel: Chris' Tutorials
Views: 1,669
Rating: undefined out of 5
Keywords: platformer game, platformer games, pc platformer games, indie platformer game, indie game dev, indie game development, indie game devlog, game dev, game development, indie game developer, unity game dev, unity game devlog, unity game development, unity, unity 2022, unity 2020, unity 2021, 2d unity, programming, c#, pixel art style games, pixel art games, pixel art, indie games, pixel games, free course, free courses, free online courses, free game dev, gamedev, 2022
Id: aTB-5aE0POw
Channel Id: undefined
Length: 124min 50sec (7490 seconds)
Published: Mon Sep 13 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.