2D Top Down Pixel Art RPG Game Dev in Unity 2022 ~ Crash Course Tutorial for Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody chris here and in this video i'm going to be giving all of you a quick crash course on unity2d for building a top-down style game so in this video i'm going to be using this asset pack mystic awards which you can find out it's io i'll put the link in the description at uh game dash endeavor dot h dot io slash mystic dash wards so there's a free version of this and that's what i'll be using for this little demo and you can just click on the download button to go ahead and grab that so once you have this or any other asset that you want to use for this project let's go ahead and create a new project in the unity hub so you can see here i'm using the 2022.1 version of unity if you're using a different version it probably won't matter too much but just be aware that's the version i'm on so let's go ahead and click on a new project here and then i'm going to be creating a new 2d project just using the standard built-in vendor to keep things simple for now so we got to choose a storage location for where we're going to save our project i'll go ahead and navigate to that so i have a little folder here called tutorials i'm going to select this folder i'm going to rename the project so i'll call it top down 2d crash course and let's go ahead and hit create project so it'll take a minute but go ahead and wait for this loader icon to complete and then we'll get started so our project is opened up the first thing i'm actually going to do here is create an art folder and i'm just going to bring the art assets that we talked about earlier into this project so i'm going to right click down here in the project window over here and then do create and then folder so i'll call this art i'll double click into it and now in your file explorer go ahead and extract and find the sprites from your our asset pack the mystic words so i'm going to bring these sprites into the art project right here also rename this to be mystic woods just make it a little bit more clear what it actually comes from and now we can go ahead and explore the folders and see the characters which we have brought into the project so for any sprites that you're going to be using for a pixel art game the settings you're going to want is going to be to take the filter mode and turn that down to point filter and then the compression down to none that'll make it so that the pixel art looks crisp and that there's no anti-aliasing or anything like that so the next thing you'll notice if you look at these sprite sheets and i'll go ahead and expand them with this zoom bar in the bottom right is that there are multiple sprites inside of one sprite sheet which means that you need to take the sprite mode over here and change it from single to multiple so that you can split the sprite sheet into individual frames so let's go ahead and click on the sprite editor now i'll hit apply to apply any unsaved settings over here now you can see the sprites for our character and the game so we need to slice this based on either the number of rows and columns or the size of each individual frame so i'm going to slice based on let's go to cell count because i don't actually know exactly how big these frames are but we can pretty easily count how many rows and columns there are so let's see one two three four five six so we have six columns and then we have one two three four five rows so let's go ahead and grab that hit slice and get out of that editor so you notice that the areas that don't have any actual sprites are excluded from here so when we hit apply we're only going to get frames that properly have a sprite which is what we would want anyway so let's go ahead and hit apply here and close this out now you'll notice that you can expand this player sprite sheet by clicking over here now and you'll see all of the frames individually numbered for our sprite sheet now let's do the same thing with the slime so i'm going to change sprite mode from single to multiple filter mode from bilinear to point and compression to none and hit apply okay now let's open up the sprite editor and do basically the same thing so let's slice based on number of columns so i count seven and then five rows going downwards so if we do seven columns here and you can of course see these red lines and just kind of confirm that it looks correct let's hit slice and apply close out the sprite editor and now you can expand the sprite sheet and see all of your animation frames so let's go ahead and take our first animation frame player 0 and bring it into the scene so this will create a new game object inside of our scene so so this will create a new game object inside of our scene so a game object is going to be built out of multiple components components like the transform component you see over here or the sprite renderer which is automatically created for us when we bring a sprite image into our scene window over here so despite this being rendered if we zoom in here is of course that player zero frame as you might imagine a sprite renderer and a transform is not really enough to create a moving working game character but it is the start and in the newer version of unity when you click on a sprite in your scene it's going to be glowing orange so you know which one is selected it doesn't actually have that orange around the border in the actual game you can see how it looks if we go over to game view so let's go ahead and turn this player game object and the scene into a prefab a prefab is just a reusable game object that all the data for is stored in your project so you have your core template the prefab and then you can create instances of that game object any way you need it so you might spawn a player into multiple levels but you only have to have the base data for that player stored into one prefab it's really useful if you're doing things like monsters which of course you would have more than one of inside of your game so first let's change the name of this game object and inspector in the top right make sure it's selected in the hierarchy on the left so let's go ahead and change some stuff about the game object in the left for the hierarchy make sure that you click on player 0 and that your character is highlighted here now let's go to the inspector on the right so we can edit the details i'm going to change the name of the character to player the tag i will change to player as well so the tag is just a descriptive string that can describe what type of object it is so the built in for player is perfect here so if we ever needed to identify that a character that was doing an action was of a player tag then we can use that string and check against it the transform because we're going to turn it into a prefab i'm going to change the position here to 0 and 0 which will put us in the center of our scene that's important for prefabs because for prefabs you don't want to kind of predefine its location because you don't know where you're going to put it on your scene so anything you don't know you don't want to have customized for sprite renderer that's fine as it is so let's turn this into a prefab now so on the project window bottom left i'm going to create a new folder here right click create folder i'm going to call it characters i'm going to jump into here and maybe we'll separate each character into its own folder because when you're building a character like an enemy or player they're going to actually have many different things that actually build that game object so you'll have animated components uh you might have custom scripts that define how the character works and you'd have the prefab itself so having separate folders makes sense so i'm going to right click here create a new folder and i'm going to call it player let's jump into that folder and i'm going to drag the player game object into this project so just left click hold drag and drop drop it in here and now we have a prefab so we know that this character now is linked to a prefab because it is blue in our scene and we can click in here to open the prefab so the difference between editing the prefab and editing the character in your scene is that when you edit the prefab it affects every character that is instanced from this prefab but if you change a detail about the character in the scene like let's say the position this is only going to affect this individual copy of that characters so although the position here is set to 2 if i click on the prefab you can see the prefab's default is 0 for the x position so now that we have our prefab another problem in terms of seeing the game if we go over to game view at the top is that the characters are way too small so our camera is set up for bigger graphics than this so what i can do is click on the main camera in our scene and change the size to one that will be a huge start on getting things to be more in line let's click on player again and i'm going to change the position to zero kind of center it in our scene so one setting i generally change when i'm looking at the game view is for pixel art game i would change it from free aspect to something like 16 by nine if i plan for my game to be always in 16 by nine resolution of some kind then this will help me make sure that it looks correct whenever i'm building the game so we can switch between scene view and game view and it's important to make sure that our character looks correct here so another thing you're going to want on your camera for pixel art games to make sure that all the pixels always look smooth is to add a component and then choose pixel perfect camera so pop that in there and then i'm also going to check upscale render texture so if we actually display the game at a higher resolution than what it was built for we just want to take our characters and scale them up to the actual screen size so let's go ahead and check that there and if you don't like this blue background in your game view you can of course change the background to a different color so i've been liking to make it something like a gray for right now of course we're going to be taking the tiles from the art pack and using it to actually build a proper background so we can go ahead and play on so let's kind of work on that now so back in the scene view let's go to our scene hierarchy i'm going to right click over here and i'm going to choose 2d object tile map and we want rectangular so this will create a grid with a tile map underneath it so in your game scenes you can have multiple tile maps which is often needed if you need to have different tiles render with different settings such as their sorting position or whether they have a tile map collider attached to them or not so the colliders will allow tiles to participate in collisions and if you don't have the tilemap collider then your character would be able to walk right through it sometimes you want that and sometimes you don't so one thing you can tell is that there's now a grid and the grid is probably way too big for this our asset pack so i'm going to click on grid and i'm going to change the cell size to 0.16 and then 0.16 for y as well i think that's probably what this pack was built with so we'll try that for right now and now we need to create a tile set from our art that we can use to draw the tiles into these squares so open up window go down to 2d and then choose tile palette here so this window will pop up i like to put it over by the inspector so as a different tab you can switch between you can just drag and drop your windows and we need to create a palette from the artwork so let's open the artwork and make sure the settings is correct first so all right and then mystic woods let's go to the tile sets and let's start with these planes tiles so i'm going to go back to the inspector in the top right i'm going to change sprite mode to multiple filter mode point compression none and apply and now let's edit this sprite so let's slice it and this time i'm going to do grid by cell size i'm going to try 16 by 16 since i think that's the size of these sprites and as far as i can tell that is correct so i'm going to slice now and just like before areas where you don't have any information are going to be ignored so let's apply the slicing here and now we have the individual tiles but we need to put those on the palette so that we can actually use them so in the top right tile palette editor click on new palette and i am just going to call this mystic woods because i will bring multiple of these images into the same palette to use to draw from and then let's click on create okay don't think we need to change anything else there so this is going to default creating the palette into the folder where the our asset is into so i am actually okay with putting it in here so i'll click choose so here is our tile palette prefab the next thing that's going to be happening is creating a bunch of tiles that exist within this tile palette so i want to put those into a separate folder because this is a lot of tiles and i don't want them to flood this folder so i'm going to right click and create a new folder i will call this tiles and now to create the tiles let's drag the planes image into the tile palette on the right you can place it anywhere and if you use middle mouse scroll out you can see a little better the grid that you're putting it all on and let's let go and now it's going to generate tiles into a folder so i'm going to choose this tiles folder choose and just give it a second to create the tile assets for all of those tiles so now if we click into here we can see the tiles assets but what we really care about is the tile palette that exists over here in this window so now you can click on any of these tiles and use it to start drawing on your tile map so if we look at here you can see that we are missing the grass tile so i'm also going to grab the grass the fences the decor 16 by 16 but maybe not the eight by eight since this is a 16 by 16 tile palette i might want this on its own separate palette but let's grab these three after changing the import settings and put them into the tile palette so i'm going to click on grass well actually really if we want to save time let's select all three of these so i'm going to left click on grass hold shift down click on fences and decor and now we can change the settings for all of these at once so let's change filter mode to point compression to none and i'll choose a sprite mode to multiple though for the graphs that should technically be single so i'm going to hit apply here and now i'll click on grass and change that back to single as well so because this is a single tile we just need to go to the tile palette and put this in somewhere so i'll put this right here and let's save this grass tile into the tiles folder next let's click on fences go to inspector and let's slice this sprite sheet so i'm going to go to slice let's do 16 by 16 again hit apply so now we have individual squares for each of those tiles let's click on decor 16 by 16 and let's slice this as well okay as you can see only the top and the bottom actually have information here so those are the tiles we're going to get okay now let's click on tile palette let's bring the fence in anywhere that is blank so i'll put that in there save the tiles into the tiles folder so now let's take the fences image and bring all the tiles over here to the mystic words tile palette drag them in there okay and let's go ahead and okay tile sets i'm gonna choose this tiles folder so you may have to go back and then back in but yeah choose the folder generate the assets okay we can see them all pop in here and now to finish things off let's take the decor 16x16 and let's pop it in right over here to the right and then choose the tiles folder to generate the tiles so now we have all of the ground art assets that we're going to need inside of this so we can basically start drawing our grid so i'm just going to start with the grass tile so i'm going to click on the grass tile it's going to be in paint mode over here i'm going to left click somewhere on the grid and add these tiles in if i drag a box kind of like this you can fill it in quite easily by using the paint bucket tool so that's g on the keyboard or you can click over here and then fill that in we'll see one problem immediately which is that our character is now rendering under the tile map so there's different ways to handle that one way that i think is pretty easy to understand is to click on your tile map and then change the order and layer and give it a negative value so your player is currently set to a zero order in layer so if we change the tile map to be a negative five then the player is going to render on top of that okay now let's click back on the tile palette and let's draw a little more so let's add some sand tiles in i'll just kind of create some random regions where we want things to be a little bit different and then you can add the tiles which would serve as the border between the grass and the sand so i'll add that in there so let's start with the easy ones like up here at the top and then these tiles let's also add in the corner okay the corner would go here and then this is a top piece then we can go down here okay so let's just get these corner pieces in as well we'll just keep it kind of simple here for now then we need side pieces bottom piece top piece and you can kind of do the same thing over here so let's go down okay and then on up here let's kind of curve around a little bit maybe we can make something a little more interesting okay and then let's use this corner piece so that we can curve around here and continue going down so i think we're gonna need this one okay we're gonna end up with some more sand over here now let's curve the grass around again okay i'm gonna make grass over here and let's keep going with that so grass grass grass okay on the right side we'll go back down with some dirt go along the bottom grab this piece let's go one more with that actually and then let's go up this side curve it around again and then finish up with those and then this piece of course we're just going to change that back into this tile here the important thing when you're laying down your tiles is just to look at it visually and see that everything matches up correctly and that you get the transition right between two different uh set and you get the transition right between two different types of terrain so another thing we're going to want to make our grass look less boring here is to differentiate it a bit so that every grass tile is not just a simple green tile and we can use these variation tiles over here to do that so you can see these tiles will fit inside of the grass anywhere but because they have some little decals inside of it if we start putting them down like this it's going to change up our grass and make it generally more interesting so i would take a few of each of these and kind of put them around our scene and just make it a little bit more varied than it otherwise would be by default so now if we look out a little bit it makes it a bit more interesting so i think that in the case of these little dirt plouches these are meant to layer on top of the dirt ground tile here so in this case what you would actually need is a different layer for your tile map so let's go up here to the grid and the scene hierarchy right click and create another tile map so let's call it rectangular and i will call this ground top so now if we click on ground top and we go and start drawing with the same tile palette onto this layer you'll see that when we kind of pop that in it's going to create it's going to create the tile here but it's layered against the background so we end up creating kind of a combination tile in a sense so let's just add a few of these spotches to various places and that might actually be enough already okay and now if we kind of zoom out uh deselect everything we can see that that adds a little bit more detail to our areas if we wanted we could even take these same things and kind of maybe pop them into the grass layered on top of it kind of more of a artistic decision at that point so this ground top layer we are going to want to make it above the base tile map which i'm going to rename to ground right now but we don't want it to be above the player so if we put a decal right there on ground top we don't want the player to render on top of that so once again i'm going to take ground top i'm going to give it a value of let's say negative 3 in the sorting layer so that if we put anything like right here that the player is going to render on top of this ground spot okay now let's create another layer so that we can add some fence into our scene so i'm going to go to the grid right click do 2d tile map rectangular and i will call this collision objects i guess let's go to the inspector and let's add a tilemap collider here so tilemap collider 2d so what this will do is automatically generate collision shapes around any of the tiles placed on this map so i'm not actually 100 sure for the fences whether we want that to be above or below the player let's go ahead and change the tile palette and let's take some fence tiles and just add them into the scene so i'm going to grab these three all at once by left click holding and dragging across to get these three tiles and place them on the collision objects layer we can also add in a random stumpy post and hit there and then i guess i will take the bottom left hand corner and let's add another fence here as well so this first piece is going to kind of face upwards so i'll take these other pieces and go to the right and this piece to extend uh that one that faces up as well so that we have a corner fence and let's cap it off with those end pieces like so okay the next thing we want to be able to do is to make it so that when we actually hit play on our game that our player can move so now let's add in the new unity import system package let's go to window and unity and then go down to package manager inside of here we're going to want to go to packages in project and then change it to unity registry i'm going to type in import here so we want the import system and install it to the game so the new input system replaces the old default one so if you're okay with doing that just go ahead and hit yes it disables it so you can always go back the idea is that the code between default unity and the import system is going to look different so once you start writing for one you would have to adjust the code for it to work for the other so if we go to player here we can now add a component to the player which is going to be let's see input and then player endpoint so first off let's take this gizmo and shrink it way down so i think you click over here for that and and let's change the 3d icon size to be something way smaller than that you can also see this plus sign to the component we just added because i added it onto the instanced game object not the original prefab it doesn't exist on the prefab so if i click on the prefab and i'll inspect you can see it does not have that component but once you've added it to one you can apply it to the prefab as well by clicking on these three dots on the right doing added component and then doing apply to prefab player that also works if you change a setting like the scale and you want it to apply to the prefab as well you can just right click on it usually let's mess with the scale and then right click and you do apply to prefab so i'm going to change that back to one okay so our player has this player input component which is how the player game object is going to receive the import events such as keyboard controller whatever have you for controlling the character but in order for things to happen for the game character we have to create a bunch of actions that will take that keyboard import and turn it into something that actually happens on the player so you can do that by clicking on this create actions button so let's do that so we're going to have this import actions asset so i'll call it something practical player import actions and i'm going to actually save this in the characters folder so i'm going to click down here to expand the folders let's do characters and then player and we'll just save it straight into here so now it's going to pop open the asset and you can see it has three default actions move which has multiple types of input that it can work with so if you plugged in a game pad like a xbox controller you'd be able to use the left stick to move around or wasd on the keyboard so for right now we're not really going to be messing with this but just know that this is how you take the input on your keyboard and you turn it into actions with these key bindings so let's close that out the behavior i'm going to use as uh send messages by default which means that in order for the script to do something we need to implement these functions down below so you can see on move here on look on fire so we just need to make on move in order to make our character move so let's add a new component this is going to be our custom script so add component going to type in the name that we want to give the script here so i like to go with player controller and then you click on the new script link and we'll create and add this so this will be a new c-sharp script and you can open it up either in visual studio or i like to use visual studio code since it's a more lightweight editor if you need to select which editor you want to use for editing your code go up to unity preferences then in this window let's see general okay and then in the preferences menu you go down to external tools external script editor you select from whichever one you want to use here i'm using visual studio code so down here at the bottom the plus icon implies that the prefab doesn't have this yet so i'm going to click over here add component apply to prefab now i'm going to click on the three dots and then choose edit script so now our project's going to be opened up in our editor of choice it might look a little different if you're using a different editor of course and now we're going to start coding out our character so the purpose of this script is going to be to take the import and handle movement for the player character so we need to implement that void on move function so we're going to need to respond to this on move message and code so we do that by adding in a on move function so let's do void on move and so this is going to receive an argument from the message which is going to be the xy direction that our player is trying to move when he presses the keys down or the left stick so we get that as a input value and i could call this movement value if i want here okay and what i'm going to do is i'm just going to take the import value and i'm going to store it to a variable so that when we are doing our physics updates we can actually move the player according to the direction that the player is trying to move by pressing down the keys so let's create a vector 2 up here vector 2 has two flow variables stored in it in this case it's going to be one for x left and right and one for y up and down so the vector2 movement input then in this on move we want to take the movement input and we want to set it to the value that we're going to get back from the input value so you do that by doing movement value dot get and we're getting a vector 2. so get vector 2 and then we're going to store that into movement input so when we have this movement input we're going to want to multiply it by a speed and time of sorts in order to figure out how fast our character is moving and in what direction and so we're not going to be calculating that and update which is called once per frame but we're going to be doing it using fixed update which is called a certain number of times per second and is recommended when you're doing anything that concerns physics so down here i'm going to type in fixed update auto complete that so private forward fixed update and actually for now i'm just going to cut away this void update we might not even need it so for this character there's not going to be any acceleration he's either just going to be moving or he's not going to be moving so if there's no input we're just gonna idle so we don't even need to try to move you don't need to do any raycasts to check for calculations or anything like that so i'm just gonna do if movement import does not equal vector2.0 then we'll try to actually do something here so if the player is trying to move then we're gonna have to do a raycast check in order to see if uh the player can move in a certain direction so if the player is trying to move then we're going to need to check for collisions but i actually haven't added the rigid body component onto the player so that it can interact with other physics objects in the game world so let's go back to unity for a second here okay scripts compile and i'm going to go into the prefab in the hierarchy so where is this play over here click in here okay so now we're editing the prefab and therefore every object in the game that is based on this let's add component and i'm going to do rigidbody 2d so we want the body type to be kinematic if you want to use forces to move the character then you use dynamic but if you want to move the character in a more classical 2d way where you would say move speed times direction equals how far it moves then you want kinematics so in many cases for these kind of games you would use kinematic bodies that's what we're going to be using here um okay so we have the rigid body we're also going to need a collision shape we might as well add that in now so i'm going to collapse the rigidbody properties and let's add another component i'll do box collider 2d okay so this will be the shape of our physics object let's edit the collider and we can see it is way too big we want it to kind of match our sprite better so i'm going to shrink it to basically where the character's feet are at we'll just make it a little tiny box so the reason we want it to be down here is because that's where our character is standing and that's going to make the most sense visually when our character is bumping into objects if we made it up here then the the head would collide with things but the head isn't where the player is standing so we want to imagine what is the actual base of our character if we were thinking of it in terms of 3d which is going to be the feet in this case so let's finish editing the collider so you can see the little green shape and let's go into code so now that we have these components added we can find them in script and use them in our code so for the rigid body i'm going to do rigid body 2d up here and i'll just call it rb when the game starts we want to get access to that rigid body so i'm going to do rb equals get component rigid body 2d parentheses so git component is going to be looking for a type and this is the type of the component so when it finds a component that has that type it's going to get that and store it into the rigid body and that's basically how you access any components you want that are attached to the same game object okay so before we do the raycasting you might not get the error messages initially when something's wrong with your code so if you're on visual studio code you're going to want the unity tools like unity tools debugger for unity and if you've grabbed all that stuff you can go over to this debug tab and do generate c sharp assets for build and debug and that way you'll be able to see some of the problems you might have here so vector2.0 is actually lowercase and in the case of the input value we need to get reference to the namespace for that input system so i'm going to do command period and then i'm going to get using unity engine input system so this is going to be needed up here at the top using unity import system and that should clear up the error messages here so now we can do a rb.cast so for rigidbodycast there's many different overloads for this function so i'm going to grab one of them and put it here and then we will talk about it so i went ahead and copy-pasted the full call to this cast function using one of the overloads so the parameters are as such so you have the direction here which is actually just going to be the movement input so i will change that there and that clears that one up then we have the movement filter which is a list of settings which will determine uh what this raycast can collide into or what it will just simply ignore and we'll add that up here at the top over here we'll also have a list of collisions where we can store the results of this raycast and then you need basically the length of the ray that you're casting which is going to be based on the time between the frame a offset value to basically go a little bit further than the amount of movement you're going to move and this can help you avoid getting stuck in the wall and then the movement speed so the movement speed will declare up here is a public float variable so let's call it move speed and i am going to just set this to 1f by default so one of the reasons we make it public is it'll actually appear in the unity inspector and so you can change the value inside of the unity editor without touching your code so the other things we're going to need here is a contact filter 2d i believe and we'll call this movement filter then we're going to need a private list of classed collisions so this will be list of collision 2d that's can be called past collisions uh when our script starts we will just initialize that as a new list just like that so this will just create an empty list and whenever this raycast runs it's going to replace all the stuff in the list with the collisions that it finds and then we need a collision offset so i will also make this a public variable in case we need to change it so public float collision offset and uh we will set it as 0.05 for right now and we'll customize this as we find it's either raycasting too far to pick up on a collision or too short but that should be okay for right so we'll try this for right now and we'll customize it later and yeah okay it's not a list of collision 2ds it's actually a list of raycast hit 2d so just change the type in the list to raycast hit 2d and let's copy that over here to the new list being created okay and that should clear up our issues there let's take a look at the unity editor for a second the scripts will compile and now we have our movement filter the layer mask where we're going to be colliding i'm going to change that to let's say default layer for right now but we can change that layer as we need to everything else just going to leave that as the default and we have our move speed and our collision offset so to kind of explain what's going on with the raycast uh if we want to move let's say 50 pixels over here or so in a single frame if we do a raycast we can check to see if there is a object over here that would block the player's movement into that space and then if there is a raycast hit then we can choose to prevent our player from moving in there otherwise if we were to just say okay move the player from here to here and don't check for any raycasts then the character would just pass through everything and it wouldn't interact with the physics at all so we use the raycast to check if a move is valid before we make the move so in this case if we do our cast in the direction where we're trying to move the movement input direction and we get a count of zero then that means there's no collisions and the move should be valid so we're going to go ahead and make the move so to do that we are going to take let's see rigidbody.position is one way to do it or let's do rigidbody.move position actually and so we'll take the position of the rigidbody and then we'll add this to the move speed times the time fixed delta time times the direction so this will give us our magnitude of the vector and then this is going to be the direction of it so we want movement input times move speed times time dot fixed down to time so i don't think i really mentioned much about the fixed out of time so when you have a unity game and you have fixed update your game will have a set setting where every second there will be a fixed number of frames where physics updates take place so this should be consistent between every physics update frame and fixed update and therefore this fixed data time should stay consistent basically and we take the amount of time between frames multiply that by the movement speed to get how far it should move now it's important to have the fixed delta time if there was a difference between the frames for any reason because if your frames are playing faster at one point in time then at another point in time then you would want to move the player less between the frames because the time between the frames is less basically this ensures that the movement is consistent regardless of how long it's actually taking the time between frames to update and then we just multiply that by the movement and this gives us the total amount and direction to add to the player's or the rigid body's current position but this move position we only want to actually run that if the count is zero so let's make that the condition here otherwise if there is a collision we're just not going to allow the player to move at least for right now so let's go back over to unity okay and let's move around our player so left right up down um the import is coming in and we're receiving the on move and we are actually using it right so let's see if the physics here works at all so moving around there doesn't look like it so let's figure out why so if we go to the grid in our scene click on collision objects do we have the tilemap collider here so the reason why these over here don't appear to be colliding but then this stump over here the player is colliding with just fine i believe is simply because these are not on the right layer for the tile maps so if i click up here and let's hide ground top okay we can see that this is actually part of ground top not of collision objects so we need to go to ground top we need to do tile map i'm going to use the eraser tool on these three and let's go to collision objects and then put these three back in wherever we want them and when they're added here you can see that they now have a collision shape automatically generated around them thanks to the tilemap collider 2d okay and i think they were down here actually so i'm going to move them let's go ahead and hit play and let's see if we can collide there so yes we are colliding it doesn't look perfect here because of the order in layer and also uh the position where we're casting from which is going to be probably the center of our object not where our box collider is so let's hit play there and you might notice that when you kind of need to go back into play mode it may take a little bit of time in order to do that so when you're editing your game one trick you can do is to go up to edit project settings and then you go down to editor and if you scroll down here to the bottom you can enable interplay mode options of which is going to disable reloading the domain and reloading the scene so when i'm just editing the game and i need to test really quick i just have the reloading of the domain disabled here but i'll check reload scene because generally the scenes reload very quickly anyway so now if i click play mode you'll see that switching into play to test the game again is almost instantaneous the the drawback of doing this is that by disabling the reloading of the scene and the reloading of the domain it's possible that some things may not perform exactly as they do in the actual published build version of your game so there may be cases where you do not want to enable play mode settings but it does speed up the process when you just need to jump in and out like this so another thing that i want to adjust here is that when we go over here to the fence that the fence is rendering on top of the player so once again we should probably already know how to do that let's exit play mode go to collision objects and i am going to take the order and layer and let's make this negative two here as long as it's lower than the player that should be okay go go to play mode and then walk over to the fence and that is what we're looking for the players try to render on top of the fence so when we're behind the fence this works okay uh because our player is not walking below the fence now when we go up on top of the fence and we try to go down we can see that there's quite a lot of distance here between where the player is and where our collisions start happening when we're trying to go down so to fix that we can kind of shrink that collision offset i'm going to try making that 0.02 let's go into play mode and test that again and now we can see that the spot where our collisions happen with the fence is a lot closer to where the fence actually is so that should work okay for right now another thing we might want to be able to do is to make it so that when we approach a object diagonally kind of like this that rather than completely stopping the movement we'd still be able to slide in one direction so here we could probably move up and if i let go of the left key you can see i can walk up but if you have two keys pressed down at once then you're unable to slide around the object so a pretty easy fix for that is going to be to test um only on the x direction and only on the y direction for movement and then if you can do a x direction movement without collisions then you just move in the x direction and likewise with the y direction but only after checking for the initial movement input and so checking for the x and y separately would happen if this base movement input failed so what we can do since we're going to run this three times is just to cut this out into its own function so this function i'll make it private i'll have it return a boolean which is whether it was successful in moving or not or if it ran into a collision and i can call it try move and this is going to be taking a vector 2 which is the direction which we're going to try to move in this function so i'll paste the code in here and let's adjust the tabs so rather than using movement input for the direction i'm going to be using this direction so let's change that there and i'll change that down here as well since if we check a direction for collisions we want to use that same direction for the direction we're going to move and of course we need to return true or false for this to work so if the movement occurred then we're going to return true otherwise we're going to return false so we can run the try move on the movement input direction and then that will function just like it did before okay so let's save the results of that so bull success equals try move so if it wasn't successful in moving in both directions let's see if it can move in one direction so success equals try move and we'll do movement input dot x and then zero for y okay and we need to actually create that as a vector two so new vector vector2 and we need to wrap that in a vector so vector2 movement import.x and then 0 for the y so success equals try move vector2 okay gotta put the new keyboard there okay so that's gonna try it with the x direction only and i guess we'll check if still not successful then we'll do try move again this time new vector 2 0 for x and then movement input dot y for the y direction so it's going to do a normal movement and if that fails then we're going to try to move only on the x-axis if that move fails if that fails we're going to try to move only on the y-axis and this will let us slide along collision objects that we otherwise couldn't move directly into but we might be able to move around so if we hit play now and let's go at this object with two directions i'm going to press a and w down you can see we kind of slide right there along the left and come out the other side so this just makes the movement a lot smoother and probably what you're actually looking for so next let's set up animations for our character i am going to uh joe i'm going to jump into the prefab for our player i'm going to add a component here which is going to be a animator component and this is going to need a animator controller so in the characters player folder i'm going to right click here and create a animator controller for our player so we'll call this ac underscore player animator controller player and then we take this and we put it into the controller for the animator component uh now we can open up the animator window so go to window animation animation i think we also are going to need the animator window okay so the animation window is going to be where we create the clips i will uh actually put this on the right next to the inspector and then we'll do window animation animator so this will basically be where you put in the animation logic for switching between the different animations that your character can play and in the animation window is where you set up the individual clips the sequence of sprites or images that you want to play for the character running or walking or swinging a sword or whatever so um in the player folder i'm going to right click create a new folder and this is going to be for animations just so it's a little more organized then where it says to begin animating player create an animation clip click on create and let's go into animations here and i'm going to call this player underscore idle and save you can see in the animated window the animation pops in here immediately and we might actually be deleting this in favor of using a blend tree later on but for now it can be just left there so let's go to the scene view click on the player let's set up this idle animation so we need to grab the so we need to grab the frames for the player idling in some cases that is just one frame let's open up the sprite sheet let's look at this and let's see what we've got here so i'm not certain but i think these first five frames may be a idle animation so we'll try that and then after that we have the run animation from player 5 to player 12 and then swinging a sword is 13 14 15 then 16 17 18 is the character's death animation so let's set up those animation clips i'm gonna left click on this first frame hold shift down and then click on the last frame which is player four i'm going to drag these into the animation window this will create the play properties sprite animated and if we zoom in middle mouse wheel we can see all of these frames i definitely think that it's not going to be playing 60 frames per second so i'm going to change the samples here and let's set it to something like 10. that's gonna make it so the timing between our frames is spaced out a lot more let's hit play okay and then we have our uh player idle animation and actually i think that is how it is supposed to look that looks like the right speed so let's do the same thing with uh player walk and player attack so click up here create a new clip player walk now we need to grab the other frames so player five here to i think we're looking at player 11. so i'm going to drag this in here set the samples to 10 to slow down the animation hit play and there's our walk cycle so next create a new clip player attack grab the attack frames so that is player 12 to i think player 14 and let's drag that in there samples to 10 hit play there's our attack animation okay lastly we'll do player death i suppose so let's do player death for the name of the animation grab the last three frames here put it in there and then sample set to 10 and then play so that's the death animation might actually be playing a little too fast but uh basically seems like we got it right the first time okay so if we switch over to the animated window we're gonna see all of these animations pop in here and we need to set up the logic for which animation we're going to be playing so we can do player idle to play a walk first which will be pretty straightforward it's gonna be is the player moving if the player is moving then we're walking so in order for our animation to switch between player idle and player walk we're going to need to set up a parameter in our animator controller so that it knows to switch between those two animations so in the animator switch from layers over here to parameters and then click on the plus button and choose boolean so the boolean i'll call it is moving and then this is moving parameter will be set in code on a script attached to the player so let's make the transition from player idle to play a walk right click make transition and then click on player at walk and then right click on play walk make the transition back to player idle so if uh we click on this transition the little arrow here you can see that it can handle a condition in order to allow automatic switching between player idle and play walk so click on the plus is moving is set to true which is what we want and then for the one up here we want to click the plus is moving but we want to change this to false so when the player stops moving we start idling now the other thing for these kind of animations where we want them to stop immediately at any point in time is that you can want to turn off has exit time and you're going to want to make the transition duration zero this will make it so that when you switch from player idle to play a walk or vice versa that it happens immediately and that will look correct so also click on the top transition here and do the same thing uncheck has exit time and then 0 for the transition duration okay now let's go back to scene view we should open up our player controller script one more time so we can actually set that is moving variable on the animator so let's open it up edit script okay to do that we have to get reference to the animator component so down here i'm gonna do animator animator and just like with the rigid body i would do animator equals get component animator parentheses and now we have our animator component while the script's running so to set that parameter i guess what we'll do is if we're trying to move here we'll take the success and set that to the animator's value so animator dot set boolean and it's going to take the string name which we set to and we can always go double check so in the animator it's is moving needs to be the same name so is moving and we'll set that to success otherwise if we're outside of here the player isn't moving at all or trying to move so we'll just do animator dot set boolean is moving to false and then that should work for right now so let's go back to our game view hit play and let's try walking around so we can see the animation place when we're moving and when we're idling it just does the idle animation the only thing here is that if we're trying to walk to the left it doesn't switch to the left view now depending on your character there would be a few ways of doing that one way would be to have a blend tree for uh the two or four different directions your character can face but even easier way is just to flip the sprite if you need it to face left so you can flip x as a property you can just set when the character is trying to move to the left so what we can do here whenever we try to move on fixed update is that we'll set the direction of sprite to movement direction okay so to do that we need to get access to the sprite renderer you can see how we have to grab a lot of components over time so our sprite renderer here i will just put up here sprite renderer sprite render we'll get this when the script starts let's write renderer equals get component sprite render and now that we have that we can just set the flip direction on it and we'll set this to true under one condition and in another case we'll set this to false so the condition where we would want to set it to true is when the x direction is negative because that's when the character is trying to move to the left so if movement input is less than zero so i'm going to set that here otherwise else if the movement input is greater than zero then we'll do flip x equals false so in the case where it is set exactly equal to zero we don't want to change the flipping uh because we haven't actually put any input onto our character so there's no reason it should flip for one side or the other uh the other thing is we have to change this movement import.x it's a 2d vector so we're only checking one component the x value of that vector so um in some conditions when it's trying to move left we'll flip the direction to the left otherwise we'll flip it to the right so this will actually make it so that with one animation we can have it handle the other direction of the animation so if we need to swing to the left we can do that or swing to the right we can do that as well so let's hit play and see if that's working i'll hit left okay and our character is facing left hit right our character is facing right and we can basically move around the screen and at least as far as moving around this is uh working pretty good so far so although our movement is basically working for the most part one issue i find when we run up here is that the success of a movement is being set to true even if we don't actually move so what's happening right here is i'm pressing w walking into the fence that fails because we have a collision so then we check sideways even though there's no a or d movement and when we do that it's going to have a success because it's going to be trying to move with a vector of 0 0 and there's nothing over here to the side so in order to fix that in our code what we got to do before we try these extra moves that are just on the x-axis and just on the y-axis we should only attempt it if there's actually a movement x value here so i'm going to put and as an extra condition and we're going to do movement import.x is greater than zero i'm going to pull this out of here put this down here as an extra line so if we still haven't had a success whether or not this actually ran we're gonna only check this if movement dot y is greater than zero two so now these try moves shouldn't run and shouldn't have a success unless there's an actual movement input another alternative we could do and i might actually like that more is that uh if we come in here and the direction is 0 0 then we just return false so if direction is is equal to vector 2.0 else we return false because we can't move if there's no direction to move in so these two things will achieve basically the same thing this might actually be the better way to implement it though so let's go back to the game and make sure that when we actually run up here that it's going to stop showing the character is moving because we're not actually moving ah okay i made a mistake here it's supposed to be not equals to zero not equals to zero so now we go back in here we're moving around and let's see when we get up to the fence we stop moving because it's not going to try to do a movement if there's no direction to move in so these a d movements of zero that's not happening uh likewise we go to the side and we just run at the fence it's not going to be checking to see if we move up here because we're not trying to move in that direction so now our movement looks a lot better overall another thing we're probably wanting right about now would be a follow camera so we can add that to our project pretty easily using cinema machine so so let's go up to window package manager and grab that package in the search i'm going to put sign or c-i-n-e get the cinema machine and install this so now to set up center machine so that we can have a follow camera on our player let's go up to game object go down to cinemachine and then we need to choose 2d camera here so this will create another object inside of our scene our cm virtual cam one note that the main camera now has some extra stuff added like a cinemachine brain so we click on our cmvcam1 and we need to give it a target to follow so let's select our player from the list let's just click on that little circle and then choose the player transform now if we go ahead and hit play you'll see that our cinema machine is helping the normal camera to follow our player around the screen with a little bit of lag as you can see this is like the center point for the camera and it doesn't follow the player immediately it takes a second for it to catch up so one thing you might notice when you're using the cinema machine is that your pixels might look a little choppy again so what you can do on your virtual camera is to add an extension to it so i'm going to add the pixel perfect extension so now when we go back into the game and hit play and we walk around it should look correct for how our character animates and walks around the screen there shouldn't be any jarringness or anything like that so uh yeah that's looking better so next let's jump into the animator for the player and then let's create a transition to player attack and then for player attack to go back to player idle okay so for the player idol going to player attack we want that to happen on a trigger so this will be an event that happens and that will send us into the player attack state so i'm going to add a parameter here and this is going to be a trigger and we can call it let's say sword attack i suppose since it's very possible our character might have multiple types of attacks later on that might make the most sense for a name there so now we need a condition where we're going to set this sword attack and transition into the player attack so let's add that condition here idle to attack and we'll do the sword attack trigger so you can see here there's no true or false value a trigger is going to get consumed when we move into the attack state so if we click on our character and we open up the player input we can see that we have the messages which we can respond to like on move on look on fire so if we're just using the default player actions then we can see fire is already set up in this case that is going to be left button on the mouse right trigger on the gamepad and so on and we could use this for an attack you could also of course add in your own custom actions but we'll just keep it really simple for this tutorial so uh fire here we're going to respond to on fire and code so so when we jump into code we can come down here to the bottom and we're going to respond to the on fire message so this is going to happen when our left mouse button is pressed and we're just going to need to put ourselves in the attack state but before that let's just test that this is actually working so i'm going to print fire pressed and now let's go back over to unity and test that that is actually working for us so if i click play and we press the left mouse button down you can see fire pressed okay so now we need to take the animator and set our parameter onto it so animator dot sat let's see trigger and we're going to do the sword attack trigger so let's go into play mode hit play and we can see our attack is actually playing there it seems to double play and not go back to the idle state so quickly so let's see what's going on there so in the transition first off we're gonna want zero for the transition duration and i think also zero for the transition duration at the end there as well uh but i believe uh for going back we want the exit time to possibly be one here as in when the animation is completely finished so if we click play we go back into play mode we left click press we get our sword attack animation and we go back to idle state after that so when our player is walking we can't make that transition into the player attack state because there's no transition here so let's set up the same transition between player walk and player attack with the same condition so sword attack is triggered 0 for the transition duration and turn off has exit time as well okay and this one player idle to player attack should also have has exit time turned off so we hit play let's go back into it okay and now our transition to player attack whether we're walking or just idling around is immediate when our character is attacking though we don't want to be able to move around so let's actually turn off movement during that case so let's create two public functions one to lock movement it's a public void lock movement and then another one to unlock the movement so up here at the top we'll have a boolean so let's say boolean can move and that's going to be set to true by default and lock movement is going to make can move equals false unlock movement is going to make can move equals true so if can move is set to false then we're not going to be able to move so we will basically turn off all of this code temporarily so if can move then we will allow all of this to occur otherwise we can't so when can move is off uh we won't be able to move our character around it'll only be able to play the sword attack animation obviously when we unlock the movement then this will start resuming again so a pretty convenient way to call those functions is going to be in the animation clip for that so let's click on player here let's go to player attack so on frame 0 for this animation i'm going to click let's see over here add an event double click on the event and uh let's temporarily move the animation down here so that we can also see the inspector so we select the event and the event we're going to do is going to be lock movement so now we come to the end over here and let's unlock the movement so add an event select the function unlock movement from the script so now if we hit play i'm going to be moving around let's left-click oh and look at that while we're playing the sword attack animation we can't move which is probably a lot more what you would expect okay so now when our character is swinging we're gonna want there to be a hitbox so that we can hit enemies and deal damage to them and this hitbox will only be active while the attack is actually going on of course so let's dive into our player object and we could add another box collider to the player but i think it would be better to create a child game object so let's right click on this and create a new empty and we can call it sword hitbox i'm going to add a component here we're going to call it a box collider let's shrink the collider down to about 0.18 and 0.2 for the y size okay and now we can change the position of the transform here so let's move this over here to the side let's put the player in his attacks animation by switching to that animation over here and just adjust the position of this sword attack until it kind of makes more sense so we can actually make it a little bit taller 0.25 okay i think that's quite generous there we'll go with that and what we can do when the player is facing right it'll work just fine like this we'll enable the hitbox and when the player is facing left we will just reverse the position to be zero point negative eleven and when the players facing left we'll swap the position of this hitbox to be over here on the left so that the sword is actually swinging to the left so rather than adding the attack directly to the player on a player script it might make sense to actually create another script in here and then the player can tell the sword hitbox script when to be active and what position to be but this will determine um the damage that the player does to an enemy like the slime so let's try creating a new script let's just call it a sword attack yeah sure sword attack new script create an ad okay so let's go ahead and edit our script so in this script let's set up a couple functions for when we're gonna attack to the right and attack to the left so it's the public void attack right and then let's do public void attack left and we want to stop the attack so public void stop attack so this box collider which we should make a trigger because it's not going to partake in any physics we will set this to active when the sword attack is actually triggered so inside of here let's get that collider so i'll say collider 2d i'll say sort and we'll call it sword collider on start we'll get reference to that sword collider so sword collider equals get component the lighter 2d now note that i'm doing collider 2d not a box collider because we may want different shapes that our attack could collide with we may not necessarily use a box collider in the end so this keeps it a little bit more vague so public void attack right the first thing we're going to do is enable the collider that okay i got the parentheses there so sword collider dot enabled equals true and it should be here as well sword collider enabled equals true but down here we're going to disable that collider sword collider dot enabled equals false also something we can get also so that we know the position where we expected to be offset from the player when we're running the game let's get this value and set it to a variable when the game starts so this will be our runtime initial ref so this will be our runtime so this will be the base value which we use to set the new position depending on what direction we're attacking from so edit position [Music] so let's edit the script and i'm going to get a vector 2 and let's call it attack offset so the attack offset is going to be equal to the transform dot position when the script starts so we store this in here because we might change that transform position when we're doing an attack right and at attack left so when we do an attack right we're going to take the transform position and set that equal to the normal attack offset and we could actually call this right attack offset i think that's more clear because that's what we're going to be using as our default value and then for the left attack we're going to take the transformed up position and we're going to set it to a new vector which is going to reverse the x value of the attack so write attack offset dot x times negative one and then we're going to take the right attack offset dot y and we're just going to use that value so the only difference is that when we attack left we are reversing the offset from the player to be from the right side to the left side so now we need a way for the player controller to tell the sword attack whether it should be attacking from the right or attacking from the left i think a good way to do that is going to be to set up a enum variable that the player controller can control so let's go up here and create a public enum which is basically a way of adding a human readable word to an integer value and then we can use it in a switch statement so public enum and i will call it attack direction okay and we'll have two values here left and right so now we'll need a attack direction variable based on that enum that the player controller can set and we will set that to be and i'll just call it lowercase attack direction so the attack right uh we're not going to be calling these in the animator we'll just call a symbol attack function so i'm going to make these private actually stop attack can still be public so our private and so our actual attack that we can visibly see public void attack we'll call it or you could call it swing or whatever um we'll do a switch statement and that switch to so when we go into the attack function we'll do a switch on what attack direction we're supposed to use so if the attack direction case is attack direction dot left if i'm writing this right then we do attack left otherwise attack direction.right as the other case we do attack right and by setting it up with the enum variable we could just add extra possibilities up here like attack up or attack down and we'd just be able to handle the cases pretty simple down here let me go ahead and correct this error could be because i don't have the break yep okay there we go so you gotta add break to the end of your cases to fix those air okay so we'll call attack from the animation and stop attack from the animation uh but and player controller when we set the flip direction of our player let's also get access to the sword attack so i'll just declare public sword attack up here i guess sword attack let's go into unity now and on our player prefab we can just drag and drop the sword hitbox for the sword attack into here okay now it's going to be able to be referenced inside of that script so back in here when we flip to x we're going to set the attack direction of the sword attack to be equal to sword attack attack direction dot left and over here we'll do sword attack dot attack direction equals sword attack dot attack direction dot right and this one should be capital because we're talking about the enum here this is capital as well okay so basically oh and i actually got these backwards um no okay so basically whenever we flip this bright renderer direction we're also setting the attack direction for the sword attack and telling that script to basically change that so now whenever we call the attack it's going to be facing the right direction by default or it should be anyway um so actually i think i have a slightly better way to do this so we have our lock movement function and we have the unlock movement function let's expand that a bit so when we lock movement instead of just locking the movement let's make a player void sword sword attack function and so what we'll do is we'll lock the movement okay so down here when we call the sword attack we can just do sword attack and then do attack left or sword attack dot attack right and we'll do that based on the direction of our sprite flip here so we won't use enums actually at least for right now let's go back in here uh we'll get rid of this attack and let's do public attack right public attack left get rid of the enum okay and now down in here we'll just check if the sprite render dot flip x equals true then we're going to attack left otherwise we're going to attack right so sorry for any confusion there the the enums option you know it would work too but uh i think this is just a little bit more straightforward now so i think that's what we're going to go with so as long as your sword attack script is set here we'll be able to call the attack functions on that and in order to get the sword attack to trigger all we need to do instead of calling lock movement on the animator is sword attack so in unity uh let's go to player attack and this event we're gonna change it to be sword attack and uh to make sure that's working let's go in here and we'll do a print attack right and a print attack left hit play and let's go to the console so let's see if this is working attack left attack right so the last thing we're going to need to do for these animations is to add an enemy and then to try to deal damage to it so for our sword hitbox we have a box collider and it's being set on is trigger mode so that means that there's going to be a message we can respond to which is on trigger enter 2d and if this is the case we want to see if the other collider the thing that this box collider is colliding with is a enemy and if it is then we're going to try to deal damage to it so if other let's say let's say other dot tag equals enemy then we'll try to deal damage to the enemy so let's quickly set up a slime and make it so that we can deal some damage to it so i'm going to right-click in the hierarchy create a new empty object uh we will call it slime i'm gonna tag it immediately as enemy so let's add a new tag i'll add a custom tag here enemy okay if we click on the slime we should be able to set that there okay so we're classifying what this object is let's add a sprite render so that we can see what it looks like and let's go grab the characters the slime let's see let's put slime frame zero into here okay there's our little slime let's also turn this into a prefab object so in characters i'm going to create a new folder we'll call it slime and let's drag the slime into there so the so the slime is going to need a collider probably a rigid body too so the slime is going to need a collider and a rigid body so let's do rigid body and so let's go into the prefab for this i'm going to double click into it let's give it a rigid body 2d and that is going to be of type kinematic if we're going to script its movement it's going to move like the player in a kinematic form not affected by forces necessarily unless we code that in for the kinematic movement and then let's add in a let's say box collider you know what a capsule collider might make more sense sure let's let's do a capsule collider because it fits the shape and let's resize it to be roughly the size of our slime character there okay so let's add a new script we'll call it the enemy script so this will just be a really basic enemy we might build other scripts that build on top of this so this will just be really basic implementation of an enemy and i guess the idea will be that this script could be attached to other enemies as well we'd just be changing out different animations and art for the characters so let's edit the script so i'll keep this really simple let's do public void take damage and let's give it a float and mount or let's call it float damage and then let's give the enemy a health value so public float health equals let's just say one and we'll do health minus equals damage you know it would actually be better to set this as a property so let's do public flow health as a property wrap it in parentheses and let's do a set function so health equals value and if health is less than or equal to zero then then we'll run some kind of defeated function okay let's put that down here so public void defeated so just to keep it really simple down here i think what we'll just do is destroy the game object so we're just removing the character from the scene basically when the health drops to zero and we can also do a get which will return the return the health value so here we do health minus equals damage and since we're setting it as a property whenever we call that satur function here we're already checking to see if we should be defeated so anything that would affect the health as long as we just set the value here from here we can already have those checks included so that can work a little better so now we just need to deal damage to the enemy so let's go back to the sword attack if our character is tagged with an enemy then it should probably be of the type enemy so we'll see if we can get the enemy component on that other collider so let's do enemy enemy equals other dot get component and we're looking for the enemy script and then if we can find that if enemy does not equal no then enemy dot take damage you know what actually let's just do enemy dot health minus equals and let's do damage and okay let's make that damage variable up here at the top so public float damage let's put it at three that's a super strong sword okay so i actually don't need this tape damage function at all we could just affect the health directly so the health is going to be minus equal the damage and if the health drops below zero then the character will be defeated so our character has a collider as a rigid body so that might actually just be all we need we just need to go up to it swing the sword and it might remove it from the scene so let's go ahead and use our sword power okay so so let's hit play and go take a look at this so one issue here um i don't think that we actually want the character to be able to get stuck on the uh body of this character so let's take the capsule collider and set it to is trigger only so i'm going to hit play now now we can walk straight through it and uh clearly this line was destroyed there but the problem is that our box collider should not be enabled yet so on the sword hit box let's turn that box collider off and make sure that it's off by default on the player prefab as well so we will turn that on when we attack so likewise when we unlock the movement we're also going to want to stop so likewise when we unlock the movement on the player controller when our attack's done we're also going to want to tell the sword attack to disable the collider again so let's change this to be public void stop attack or we could call it actually end sword attack okay and we'll unlock the movement here and we'll also tell the sword attack to stop its attack so stop attack function now when we come back into the player for the attack animation we come here to the end let's change unlock movement and let's change it to end sword attack so now we have the start of our sword attack the end of our sword attack but by default the sword hitbox is disabled so let's click play we can walk straight through our enemy there's no attacking going on but if i left click well it should have enabled but did it i got ah okay and i think i know why that is so the collider 2d we don't need to define it as a box collider necessarily but if we're just getting the component collider 2d it's not going to find that specific component so we need to get rid of this and what we'll do is we actually define which collider 2d in the inspector so change collider 2d to public collider 2d and get rid of setting it in the start function so now we go back into the inspector and let's take this box collider 2d and set it there for the sword collider okay so when we go back into play mode uh we can take a look at the sword hitbox and see that when we left click it does enable and disable which is what we're looking for so one bug i think i found is that whenever we left click and we set the new position for the transform it's actually setting the global position because you can see these numbers are all kinds of screw so what we actually need to do when we set the position is to set it to the local position so transform dot local position is going to be relative to the parent so let's set that over there as well set it and now when we actually attack we should be saying 0.11 or negatives 0.11 so let's hit play and go around yep okay now it's working so let's swing and okay well that guy got hit so now that one's also being hit and okay that one as well okay so now the hitboxes seem to be basically working so we swing okay his health gets set to negative two negative two and these print messages are just extra lines i added in to the ontrigger enter we can go ahead and remove those right now as well as printing the value of the health whenever the health is set okay so now we have a way of defeating the enemies we can make the slams a little bit more interesting by adding in animation to them so let's add in a animator for the slime okay and uh let's apply that to the prefab there so right click added component apply to free so click on the three dots added component apply to prefab and let's jump into the slime prefab as well that will make sure that all the changes are actually set here so in our slime character folder let's right click create a animator controller ac slime and let's bring that into the animator for the slime prefab so now we got to open up the animation window for the slime and over here on the right we can create a clip for it so let's do slime idle into a new folder once again we will call this animation for the slime save it in there and let's grab the frames from the character so let's see probably these first five frames again so here i'm thinking this is probably the first three frames let's start with those set the samples to 10 like before and hit play okay possibly four frames i will try to add that fourth one in there i think that's looking a little bit more correct so i think that's our idle if you want you can create the which might be up to slime 16 here let's add those frames set it to 10. let's loop this okay there's our jumping animation let's create slime damage which from 17 to [Music] i think 19. we want to add in those frames hit play do we need the frame 20 here no i don't think i don't think this one is there and we'll add in slime defeated which will be the last five frames slime 20 to slam 24 at 10 samples per second hit play so there's the animation for that so if we want to switch to the defeated death kind of animation we could either set the health float value in the animator and then when it drops below zero we just play the animation or we can have a trigger here whenever we are defeated so let's create another function to finalize after that animation is done i'll call it remove enemy for now but when we're defeated we're going to tell the animator to set a property so let's get that animator component up here at the top animator animator and and then we'll implement the start function so animator equals get component animator and then the animator will do set trigger and let's call it defeated so if we go back over to unity now let's open up the animator uh but for the slime so click on the slime we have move we have damage we have defeated for right now i'm just going to create the link from idle to defeated because we're defeating them in one hit anyway so let's do idle make transition to defeat it and this will happen when our trigger parameter is set so let's add the parameter over here on the left and this is going to be defeated okay click on the transition go to the inspector it should have no exit time from idle to defeated so uncheck that transition duration zero and the condition is just defeated so this should be a one-time deal now uh when we play the slime defeated animation we want to call the removal of the object at the end of that animation so in the animation window click on slime defeated go to the final frame here and add an animation event click on the animation event go to the inspector and find that remove enemy function and add it in there so now if we go ahead and hit play we're gonna deal damage to this line okay at least in theory it's gonna deal damage this time so then we play the animation and after that it's removed from the game now let's see why the sword hitbox may not be actually i'm going to assume that it's not big enough so let's go into the player and let's just make this sword hitbox a little bit bigger i'm going to give it a vertical size of 0.3 pretty huge and let's go back out to the game view hit play and test this so we're going to attack okay that hits attack again hits gaps here we attack and our slimes get defeated okay so in the interest of time i think this is a good stopping point uh obviously next steps would be making it so that when your slime runs into the player you can deal some damage to the player possibly upgrading the health of your slime and then adding in those damaged states whenever it takes damage but not defeated and allowing the slime to move around in some way you could either give it a random pattern or have it try to move towards the player position but of course as a crash course in learning how to create a top-down rpg i think this is a good start so hopefully all of you enjoyed this really long video in uh creating a character allowing it to move around collide with objects deal damage to slimes and setting up the tile map in general so i've been chris thank you for watching especially to the end and hopefully i'll see all of you in my future unity content as well
Info
Channel: Chris' Tutorials
Views: 543,491
Rating: undefined out of 5
Keywords: crash course, crash course unity, unity, game development, unity course, game dev, game dev guide, making games in unity, unity tutorial, gamedev, unity tutorial for beginners, unity tutorials, 2d rpg unity, how to make a unity game, top down rpg, indie games, action rpg, action rpg games, action rpg unity, unity3d, c#, unity 2022, unity 2022 for beginners, unity course 2022, unity guide 2022, unity gamedev 2022, how to make a game 2022, gamedev for beginners
Id: 7iYWpzL9GkM
Channel Id: undefined
Length: 89min 52sec (5392 seconds)
Published: Fri Jan 14 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.