MELEE COMBAT in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
now we've done a lot of different videos on combat like shooting or strategy but one thing that we've never done is melee fighting so in this video we'll have a look at how to implement some solid sword combat in unity even of course adapt this to any kind of melee weapon and we'll be working in 2d but doing this in 3d should have the exact same steps so let's slice up some enemies but first this video is sponsored by North Vee PN Nord VPN has over 5,500 servers in over 60 countries and is one of the fastest and top VPNs out there while using a VPN you strongly increase your internet privacy secure your data while using public Wi-Fi and it protects you from hackers by using a double data encryption another great function of being able to access service all over the globe is that you can access content that might be restricted to certain areas no matter where you are in the world get 81 percent off at Nord VPN that comes as practice or used to code practice to get to gifts included four extra months with the three year plan and the nor past password manager app for free get started by simply clicking the link in the description also special thanks to infinity PPR for his support on patreon and just before we get started I want to mention that Andreas and I were on a podcast it's called duck tapes we had a lot of fun we talked about game dev stories from running the channel and a surprising amount of time was spent on random duck facts so check that out using the link in the description and let's fight so as you can see we have a very simple scene here with just a main camera a ground environment object a player as well as a bandit that is currently just standing around and if we play the game we can see that the player movement and animation has already been set up I did this following our videos on movement and animation so if you don't have that working already definitely check those out and those of course also show how to do jumping and crouching but I chose not to put that in here you also notice that the bandit is currently just playing an idle animation there's no logic on him yet the sprites that I'm using here are free on the asset store will of course have a link to them in the description the only thing that I'd recommend is that you go and find the sprites and change the pixels per unit to 32 since we're working with pixel art but you can of course use any kind of art that you'd like and I think that we are ready to start creating some player combat so let's go to our player object let's hit add component and let's create a player combat script let's set create an ADD and it's open it up in visual studio and we can just go ahead and get rid of the start method here we won't be using that and inside the update method let's go ahead and check for some input so we'll write an if statement and say if input dot get key down and the key that we want to check for is keycode dud space so I'm just going to use the spacebar to attack now remember the input system is currently being rebuilt this should work for a good while but if it's not definitely check out our video on the new input system it should be really easy to simply put that in here alright so whenever we press the spacebar we of course want to go ahead and perform an attack so let's create a separate function for this and call it in here let's just name it attack so we'll create the function down here void attack and in here we basically want to do three things we want to play and attack animation we want to detect all the enemies that are in range of the attack and then we want to apply damage to those enemies so let's go ahead and start with the very first one here which is plane and attack animation so to do this we need to first go into und and under our player of course have an animated component which has an animated controller responsible for choosing which animations to play when again this is all part of the animation video so if this is completely new to you check that out first but as you can see in here we have a very very simple setup we have a default idle animation and we can transition from that to run and back we of course want to add a whole new animation on top of this and attack animation so let's go ahead and find that - under bandits animations and I'm using the light guard as the player here some simply going to take the light guard on the score attack let's select this animation and rename it to player underscore attack and now we want to be able to attack no matter if we are currently playing the idle animation or the run animation in other words we want to be able to transition to the attack from any state so we'll just right-click on this any state note here hit make transition and click on the player attack node and if we then select this transition we can choose when and how we want to go to the attack animation of course we only want to do this if we actually trigger this transition and to do this through code we need to add a parameter that allows us to do that so if we go to the top left corner here under parameters and hit the plus sign we can add a trigger parameter let's call this attack and now on our transition here under conditions we can add a new condition and we want to change this from speed to attack so whenever the attack parameter is triggered we are going to transition from any state to play or attack really cool we also want to make sure that we don't have exit time enabled here and that under settings we set the transition duration to zero and this way the transition will happen instantly and that's actually all we need to do for the animation now inside of our script we just need a reference to this animator so that we can trigger our attack animation so at the very top here let's create a public animator component and let's just call it animator then under attack we can go ahead and call animator dot set trigger and then the name of our trigger which is attack and that's actually all we need to do if we now save this go into unity and select all player we can see that there's now a field for the animator let's just drag our animator in there let's hit play and of course we can move as normal but if we hit the spacebar we perform an attack animation you can also see that we're currently not transitioning back so it just stays in that animation to transition back all we need to do is go into our animator and just right click on a player attack and make a transition right back to player idle and we just want this transition to happen whenever a player attack has finished plane so if we click on this arrow here we don't need any conditions we just want to go straight there however we want to make sure that we have exit time enabled and we want to set that to 1 in order to wait the entire duration of the clip and after that we want the transition itself to be instant so we'll just set the transition duration to zero and as you can see right away our attack animation goes right back to idle when we finish attacking so the next thing that we need to do is of course detect all of the enemies that are in range of our attack to do this we need a few variables the first one is that we need to define an attack point because we don't just want to attack at the center of our sprite we want to attack somewhere out here in range of our sword to do that let's go ahead and create an empty object under the player let's call this the attack point and the cool thing is that we can now take this point here and move it to wherever we want to place the center of our attack so I'm just going to move it kind of outside the player by the sword here then inside of our script we can create a public transform and this is just going to reference that point so we'll call it attack point we also want a range for our attacks let's create a public float attack range and let's just default this to something like point 5 and finally we need to define what objects are enemies and which are the player and other objects in our environment we'll do this using layers so we'll assign all enemies to some kind of enemy layer and then we can make sure that we only detect objects in that enemy layer using a layer mask so we'll create a public layer mask and call it enemy layers now I'm calling this layers because you can definitely have multiple enemy layers and just select all that's totally up to you so now inside of our tack method what we will do is we will go ahead and first of all use a function called physics 2d dot overlap circle all and basically what this function does is that it creates a circle from this point here with the radius that we specify and collects all objects that that circle hips now of course because I'm working in 2d I'm using physics 2d you could easily just change this to physics if you're working in 3d and change the overlap circle to overlap sphere it does the exact same thing now first of all this circle needs a center point so we'll give it our attack point dot position it also needs a radius so we'll give it our attack range and finally we can filter out certain layers so we'll give it our enemy layers awesome so now this circle is being created and it detects all these colliders and we just need to store the colliders so that we can go through them so let's create a Collider 2d array called hit enemies so this is going to store all the enemies that we hit inside of this variable here so now we know all the hit enemies but we still need to loop over them in order to damage them to do that we'll use a for each loop and we'll say for each Collider 2d and we'll call each one enemy in our hit enemies array for each of these enemies we want to go ahead and damage them of course in order to actually damage them we need to first give them some health and all that we'll do that in a sec for now let's just throw out a debug deadlock saying that we hit and then the enemy dot name so again all we're doing here is playing our attack animation recruiting a circle in front of our player to see if he hits anything we're gathering a list of all the enemies that we've had we loop over each enemy and print out their name and if we save this now and go into unity our code should actually be working however as you can see there's really no way for us to see this radius of our attack point and so we might have to do a bunch of adjustment until we find the right values for our attack range and place our attack point in the right place so let's just write a few lines of code that is going to display all this stuff in the editor to do that we create a new function called on draw a gizmo selected this function allows us to draw stuff in the editor whenever the object is selected and we just want to go ahead and draw so gizmos dot draw wire sphere and we'll draw this sphere with a center point of the attack point dot position and a radius of our attack range so just like we did with this overlap circle all only here we're just drawing a sphere so that we can visually see it in the editor and of course in case the attack point hasn't been assigned we just don't want to do this I will write if a tag point is equal to null well then we'll return out before anything happens this way we won't get any errors so if we save this now and go into unity you can see nothing happens right now because our attack point hasn't been assigned but as soon as we drag that in there we go we can see a gizmo now where our attack point is with our attack range and so we can start to adjust our attack to fit our character I'm going to decrease the attack range a tiny bit here and I think that looks pretty good we can also go ahead and assign enemy layers here to do that we first need to select our bandit and as you can see I've already created a layer for this if you don't have this layer you can simply click Add layer go in and type any layer that you'd like and then go back to the bandit and assign that layer and then inside of our player under enemy layers we simply need to check off that layer there we go and as I talked about you can of course have multiple layers here if you want alright let's go ahead and try and play test this so let's hit play and if we now move over to our bandit and use our attack we can see that it says we hid bandit awesome so now we of course need to start damaging our enemies and to do this we first need to give them some HP to do that we'll select our bandit and create a new component and we'll just call this enemy let's say create an ad and open it up I'm gonna get rid of the update method here and at the top I'm gonna create two variables a public int with our max health and we'll set this to hundred and a private int with our current health then inside of our start function we'll set our current health equal to our max hell and what we need here is a function that allows us to damage our enemy which can be called from another script and because we need to call this from inside of our player combat script we need to make sure to mark it as public so a create a public void take damage it's going to take in an amount of damage as an integer and all we need to do in here is simply subtract our current health with that amount of damage we can then play some kind of hurt animation we'll do that soon and then we want to check if our current health is less than or equal to zero well then we have died and so we need to call some kind of die function void die and in here we'll play some kind of Die animation as well as disable the enemy so that he doesn't do things even though he's dead and also let's just do a debug deadlock for now that says enemy died there we go and that's all we need to do for an enemy script right now we can then save that and go into our player combat instead and in here whenever we are attacking and we want to loop over all of our enemies instead of just displaying their name we're simply going to access them so enemy use a get component in order to access the enemy component on those enemies and then call the take damage function we just created and of course this takes in a damage amount we could just put it in here or we could go to the top and create a variable for that so that's clearly public int called attack damage and set it equal to something like 40 and I'm just going to restructure these a tiny bit by the way in order to move around lines like this I'm holding down alt and using arrow up and down it's a really handy shortcut and so we can put our attack damage in here and that should be it if we save that and go into unity we can select our bandit and if we go over here in the inspector we can change to debug mode and what this allows us to do is actually see private variables so we can see our current health here and as you can see when I hit play our current health snaps to our max health which is 100 if I then move over and attack once it goes down to 60 one more time it goes down to 20 and the last time it goes to minus 20 and in the console it says enemy died so now all we need to do is show the enemy being hit and dying using animations and to do that we'll first go back to normal mode in the inspectors that it isn't all crazy and we'll find the animated component here and as you can see I have another animator controller here called enemy and if we double click on that it's really simple it just has a default animation here that plays an idle animation not much to it now what we want to do is be able to go from any state into being hurt and then go from hurt in to dying so to do that let's drag in the two animations so this is the heavy guard I'm using here I'm gonna drag in both the heavy bandage hurt and heavy bandit death animations and let's first of all transition from any state to hurt I'm going to zoom in a bit here that's also transition from hurt to death or we can transition from hurt back to idle so that's kind of the way that it goes we can either be hurt and go back to still being alive or we can be heard enough to go to our death animation and that's kind the end of the road of course we need to add some conditions to these transitions let's create some parameters first of all we create a trigger called hurt and this is of course just going to trigger the hurt animation we also create a boolean and this is going to define if we are dead or not so let's call it is dead and that's going to be false by default then when we go from any state to hurt we only want to do that on the condition that the hurt trigger is happening and again of course we want to go into settings and set the duration to zero we can also go back to idle we want to do that on the condition that is that is false and we first want to do this when we have finished playing our heard animation so we want to have exit time here we want the exit time to be 1 and the transition duration to be 0 and the same thing for our death animation except our condition here is going to be that is dead is true and again 1 on the exit time and 0 on iteration and that should actually be it for our animation controller there we go so now just like we did with our player we need to go into our enemies script and in here we need to reference our animator so we'll create at the top a public animator let's just call it animator and inside of our take damage function will play a hurt animation so we'll go animator dot set trigger hurt and then if we die we can go ahead and play a die animation by going animator dot said boolean is dead to true there we go and also we'll just quickly disable the enemy and to do this we of course need to disable the script itself here the enemy script and we can do that by just going this that enabled equals false that is simply going to uncheck this box here so that our enemy script is disabled but we also want to make sure that we cannot run into the bandit so we'll also disable the box Collider and we'll just do that with a quick get component call so we'll go get component of type Collider 2d dot enabled equals false ass Walt hello of course put this on top so that we disable this component after doing everything else and that should be it if we now save this and go into unity and reference our animator here and hit play we can walk up to a bandit we can hit hit him once and he gets hurt then hit him twice and he gets more hurt and if we hit him a third time he gets hurt and he dies awesome and as you can see the components are indeed getting disabled so we can now walk read over him and we cannot damage him anymore really really cold the final thing that I want to be able to do is just limit the attack rate of a player because right now we can spam this attack animation and that might be a bit too powerful so to do that we'll just go into our player combat script and at the top here where we are triggering our attack we want to add a tiny bit of logic we just want to add an attack rate so we'll create a public float attack rate this is how many times we're gonna attack per second I'm gonna set it to two we'll also create a private float and this is going to store the time where we can attack next so it's going to be our next attack time and we'll default it to zero then inside of our update here before we check for any input we can go if time that time so this basically just keeps track of our current time and if that time is greater than or equal to or next attack time well then we can go ahead and attack and so we can go ahead and put in our if statement and our attack here and if we choose to attack when then we are going to set our next attack time equal to our current time so time that time plus 1 divided by our attack rate in other words if our attack rate is currently 2 we are going to add 1/2 which is 1/2 so we're going to add half a second onto our current time and say that's the next time we'll be able to attack and once we reach that time well we can go in and attack again awesome so if we go ahead and save that now and go into unity and play tests as you can see if I spend my keyboard we can only attack two times per second so that marks the end of our working combat system whoa that's pretty much it for this video if you enjoyed it make sure you subscribe and bring that notification bell so you don't miss the next one also don't forget to check out north VPN simply click the link north VPN dark um slash practice in the description and get 81 percent off and get 2 gifts included by using the curved brackets also remember to listen to duct tapes ooh I guess that means Christmas is closed we'll be taking a break over the holidays but we'll be back with a new video at the first Sunday next year so enjoy Christmas everyone and have a happy new year and we'll see you in January texts of the awesome patreon supporters who donated in November and a special thanks to infinity PPR dentist Sam Sam well loss to violence love forever Chris face Tamara Megan Frazier Lila set Mia Mia pop muhammad yunus Daniel D sonic Jacob Sanford no Kiyosaki marc-antoine Jerrod cracker pierce the mighty Zeus Allison the fierce Gidget kya and Erasmus you guys Rock
Info
Channel: Brackeys
Views: 896,876
Rating: 4.9677653 out of 5
Keywords: brackeys, unity, unity3d, asset, assets, beginner, easy, how, to, howto, learn, course, tutorial, tutorials, game, development, develop, games, programming, coding, basic, basics, C#, sprites, sprite, melee, combat, fight, fighting, 2D, 3D, sword, slash, enemy, hack, input, battle, damage
Id: sPiVz1k-fEs
Channel Id: undefined
Length: 21min 6sec (1266 seconds)
Published: Sun Dec 15 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.