2D PATHFINDING - Enemy AI in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
at the roundabout take the second exit keep right you have reached your destination in this video we'll try and find our path to some solid 2d path finding in unity now the Unity navigation system doesn't actually support 2d so instead we'll be using the a-star path finding project to quickly and easily set up an enemy that will find the shortest path available to our player the a-star path finding project is of course completely free and the best part is that we'll be able to do it all without writing any code after that we'll have a look at how you can achieve the same thing by writing your own custom script and the cool thing about this is that you'll be able to extend and modify it in any way that you'd like to fit your AI needs but first this video is sponsored by a skill share skill share is an online learning community with more than 28,000 quality classes on game development tech and more if you've always dreamed of making your own mobile game I can definitely recommend this basic unity course on making mobile games for Android and iOS at the end of the course you will be comfortable with mobile setup and input alongside a bunch of other topics like score systems procedural level generation and unity Zaid system join more than 7 million other creators by simply clicking the link in the description and the first 500 people will receive their first 2 months for free all right let's make some enemies please don't hold grudges so as you can see I've created this simple example level with some environment pieces and a main character that we can move around the scene also has this bird here which is basically just the sprite renderer with an idle animation currently it does nothing and will not chase our player at all so let's go ahead and change that with some AI pathfinding first of all we need to visit the website for the a-star pathfinding project I'll of course have a link to this in the description here we'll go to download will navigate to the free version and we'll hit the download button this should download a small zip file that we can then open up and in here should be a folder containing a unity package let's go ahead and double click that and it should load right into unity you can see all the stuff included most of these are scripts that we are going to be using let's just go ahead and import everything and once that's done we are ready to set up pathfinding to this let's go to the hierarchy let's create an empty object and let's rename this to a star you can call it anything you want I'm just gonna place it at the top here and I'm gonna reset the transform this object is going to be the central part of our pathfinding system and it's going to define in what areas are a I can navigate so let's go ahead and add a new component and let's search for Pathfinder let's hit enter and this is going to create the a star path script here we can go under graphs and you can see that we can now create a new graph we're going to create a symbol grid graph which as the name suggests is just going to lay out a grid on top of our level and then check for each grid cell whether or not there's something blocking it of course we are working in 2d so I'm going to go ahead and check the 2d box right here and now if we go into this scene view we should see a very tiny grid graph let's go ahead and make this a lot bigger so I'm gonna switch into my scale tool and I'm just gonna simply click and drag to increase the size of this let's just have it fit pretty much our entire level here we also want to go down here and check use 2d physics and we can leave the collider type at circle but I want to increase the diameter here to something like 1.3 and this basically just means that it will try and overlay a circle on top of each of these nodes to see if it collides with anything in that circle is going to have a diameter of 1.3 we also want to define a layer for all the objects that we don't want our player to be able to pass through we can do this with the obstacle layer mask as you can see by default it's set to nothing let's go ahead and go to our environment I'm just gonna select on my middle tile map here this could also just be a bunch of objects it doesn't have to be a tile map and as you can see I've currently set this to the layer obstacle remember you can always go in and add a new layer test layer and then go back to your object and assign it to that layer I'm just going to leave this one at obstacle then inside of our a-star object we can set the obstacle layer mask to include the obstacle layer and now if we go ahead and hit the Scan button you can see that a star is going to generate a navigation grid for us of course all the areas that are blue are places that our enemy can navigate and places that have red squares are marked as obstacles and our enemy won't be able to move there now with this setup I'm just going to hide the graph here so that it isn't overlaid when we're working with other objects and we are now ready to set up our bird to do this let's go ahead and create an empty object let's call this object enemy and let's parent up bird to that object we can then reset the transform on our bird and you should now have two objects stacked like this the reason why I'm doing this is that I want to separate our graphics which is the bird here let's go ahead and rename it to bird graphics and the logic of our enemy into two different objects this is super cool because it allows us to offset our graphics in any way that we'd like and easily change them out without having to modify our enemy object now it's a quick to get our enemy moving around the scene there's a default script that we can go ahead and use it's called AI path let's select that and as you can see it's going to automatically add a secret script which is something that we'll need for all AI objects as well as the AI path script itself the secret script is responsible for generating a path to the target and the AI path will control the secret script and start moving our object in that direction and we can leave most of the settings here as is I'm just going to go ahead and change the orientation from the axis for 3d games to y axis for 2d games and right away you can see that this circle appears around our enemy I mean of course adjust the radius of this if we want our enemy to be bigger when moving around we'd also adjust the max speed I'm just gonna set that to 3 and finally we can adjust how close our enemies should be to a waypoint on our path before it starts to focus on the next one I'm just gonna set this to something like 1.2 you can see this circle here that should work for now of course I could go ahead and hit play here but you'll see that the only thing that really happens is that our bird flies straight to the ground the reason for this is that it's currently set to use gravity so let's just go ahead and disable that it's also not flying towards our player because we haven't marked our player as a target to do this we want to add a destination setter component this takes in a target let's just drag in the player here and that's pretty much all we need to do if we just hit play now you can see that immediately our bird starts moving towards a player and it's even doing so based on a path you can see that it's flying around objects in order to get to him in fact we can turn on gizmos in the game view and with the drop down button here we can find the seeker script and enable gizmos for that object in particular what this is going to do is it's going to draw the path that an object is taking in order to get to our player really really cool you can also see that our object is currently rotating in a really weird way and we don't want this bird to rotate at all so I'm simply going to go ahead and disable rotation on our object and that should fix it straight away you can also add colliders to your AI to make sure it won't fly through stuff in its path do that let's hit add component and let's add a circle Collider 2d and that already looks pretty good if we now hit play we can see these changes working you can also see that everything looks fine if we stand to the left of our bird but as soon as we go to the right we pretty much want this sprite to flip to a face in this direction similar to what we're doing with the player movement now we could go ahead and create a script from scratch to control our AI and we'll have a look at doing that in a second but if you just want to add this tiny thing to change around your graphics we can add a very small script on top of what we have going on here to do that let's select our bird graphics that's it a component and let's just call this one enemy graphics let's create a new script let's say create an ad let's double click to open it up in visual studio now whenever we're programming something with a star we want to include a specific namespace so we want to be using and the name of this namespace is pathfinding this will allow us to inside of our script here that's the our start function and create a public variable of type AI path remember this is the name of the script that we added to our enemy in order to control it let's just call it AI path with non capital letters then inside of our update method we can check if AI path dot decide velocity and the decide velocity is the velocity that our enemy would like to travel with based on the current path in other words we can take the x value of this so the horizontal movement of our enemy and check that if this is greater to some small value like 0.01 well then we are moving to the right and then we can do transform dot local scale equals a new vector3 and this is going to be negative 1 on the X 1 on the Y and 1 on the Z and if this is not the case we want to check if AI path dot decide with a DX is equal to less than negative 0.01 in which case we are moving to the left and so we want to flip our bird in the opposite direction so we can just cover this here and this is going to be positive and not negative on the X so we're just flipping based on our X speed if it's positive we are traveling to the right and we'll set the scale to this if it's negative we're traveling to the left and we'll set the scale to the opposite on the X so if we save this and go into unity we can select our bird graphics this takes in an AI path we'll drag that in from the enemy and now let's hit play and as you can see as soon as our bird changes direction it's also going to flip the sprite really really cool so that is how you can super easily set up pathfinding using a star however the a star path finding project is crazy powerful and it of course allows us to write our own custom script to control our AI so let's have a look at how we can do that I'm just going to create a backup of our enemy here so I'm gonna duplicate it and I'm gonna disable the old version now for our new enemy we can go ahead and get rid of the AR paths script the AI destination said it and under our graphics we can remove the enemy graphics script instead we're going to handle all of these things that we just removed inside of one master script that will create now called enemy AI this is going to be a new C sub script and before we open this up to edit it we want to add one more component so we have a seeker and circle Collider and our enemy AI we would also like to create a rigidbody 2d now you can pretty much use anything to drive the movement of your enemy it doesn't have to be a rigidbody you could also just use transform to translate or some kind of character controller but in my case I would like to use rigidbody because then we can easily apply other forces to our enemy and it's instantly going to work with the rest of the physics system which is just really nice for now I'm going to leave pretty much all settings as is I'm just going to go ahead and freeze the rotation on the Z and set the gravity scale to zero so if we play it now we can see that our bird is just gently floating in the air so to change this let's open up our enemy AI script now this group does have some links to it so I'm gonna go forward fairly quickly if there's something you don't understand that's totally fine if this is your first time working with AI you might be a tiny bit confused but let's try and take it one step at a time so the first thing that we'll need is some variables of course we'll need a reference to our targets let's create a public transform that will take in our target we also want some control over our speed so we'll create a public float speed and let's just default this to something like 200 next we'll need a public float which is going to store our next Waypoint distance this is the same thing that we adjusted earlier under our previous enemy they just called it pick next Waypoint distance and again it's just how close our enemy needs to be to a waypoint before it moves on to the next one so next Waypoint distance let's just default that to three finally we'll need a few private variables and for these we need to include the pathfinding namespace just like we did before so the first of these variables is going to contain our path this is the current path that we are following we also going to have an int that is going to store the current Waypoint along that path that we're targeting and finally we want to know whether or not we have reached the end of our path so let's create a bull called reached end of path and that's the fold it to false finally we need to be able to reference our CG script as well as our rigidbody 2d let's go ahead and create a seeker variable called seeker and a rigidbody 2d called RB now inside of our start method we can go ahead and find our seeker component so let's go seeker equals gate component of type seeker let's do the same thing for a rigidbody so that said RP equal to get component of type rigidbody 2d this is just going to find the two components on our object and then we're ready to generate a path to do this we access our seeker this is responsible for creating paths and we want to access the function called start path here we first need to define a start point so that's the current position of our enemy which is our beat position next up we give it the end of our path so that's our targets position so target dot position and finally we give it a function this is the function that we would like it to call whenever it's done calculating the path we do it this way because depending on the complexity of your scene generating a path might take a little while and we don't want our game to be hung up with generating a path it should just do this in the background and notify us once it's done so this is just the function that it should call when it is let's just call it on path complete we can then create this function so let's create a void on path complete this is going to take in a path called P and this is the generated path we then check if we got any errors in other words we want to make sure that we didn't get any errors so if we didn't get P error well then we want to set our current path equal to P the newly generated path and we also want to reset our progress along our path so we'll set current Waypoint equal to zero to start at the beginning of our new path awesome so now we should have generated a path and be ready to start following it in fact we can check if this but just saving this going into unity and we now have our target variable where we need to drag in our player and if we then hit play and go to gizmos to make sure our secret is included we can see the generated path we also see that it's not updating to follow our player it's just generated at the very beginning and our bird is also not doing anything to follow it at the moment so let's go ahead and change these two things first of all let's have our bird move to do this we go into our update method and the first thing that we want to make sure is that we have a path so if path is equal to null well then we'll just go ahead and return out of the function we also want to make sure that there are more waypoints in the path and that we haven't reached the end because if we have we want to stop moving so to do this we want to check if our current Waypoint is greater than or equal to path that vector path that count so the total amount of waypoints along our path well then we reached the end of the path so let's go reached end of path equals true and let's just return if a current Waypoint is not greater than or equal to the total amount of waypoints well then we can go ahead and set reached end of path to false and that's it so now we can go ahead and move our bird to do this we want to first of all get the direction to the next Waypoint along our path to do that we create a vector to let's call it direction and we want this to be equal to our path dot vector path and here we want to find our current Waypoint along that path so we'll pass in our current Waypoint so this gives us the precision of our current Waypoint and we'll subtract from that our current position this should give us a vector the points from our position to the next Waypoint we also want to go ahead and mark this as a vector two because our be the position is a vector two and so we need to cast this into one as well and finally we can wrap all of this in parentheses and add a dot normalized in order to make sure that the length of this vector will be one if you haven't worked a lot with vectors before simply think of this like we're pointing an arrow from our composition to the place where we want to be which is our next Waypoint and then making sure the length of that arrow is always 1 and we now get a force that we want to apply to an enemy to make it move in that direction so that's create a vector to its call it force and set it equal to our direction multiplied with our speed multiply it with time.deltatime we multiply it with time that that's a time to make sure it's not going to vary depending on the frame rate I also want to change this from an update to a fixed update fixed update is just like update however it's only called a fixed number of times per second which means that it's ideal whenever you want to work with physics finally we want to figure out the distance to our next Waypoint to do this we will go float distance and set it equal to vector to that distance between our current positions so our bead position and the next Waypoint so path dot vector path and we'll improve the current Waypoint we can then check if that distance is less than our next Waypoint distance well then we've reached the current Waypoint and we're ready to move on to the next one so we'll simply increase current Waypoint by 1 and that should work well then I just forgot the most important part which is actually adding a force to our enemies so let's just go RP dot add force and we'll just import our force vector that's all we need to do but it's quite an important step let's say that going to unity and hit play and as you can see our bird now moves but it does so without stopping the reason is we are applying a lot of force to our bird and it doesn't have anything to stop it again luckily we can easily add some air resistance also called linear drag to slow it down let's just set this to something like 1.5 and it's also increased the speed to something like 400 if we hit play now we can see that our bird indeed comes to a halt much better now we just need the path to update to follow around our player and doing this is actually fairly easy all we need to do is go to the top where we are currently generating our path at the start and stuff just doing this once we need to keep doing it at an interval this is super easy to set up using a function called invoke repeating this allows us to specify a method in our case we can create something like update path then a amount of time we want to wait until we call that method we just want to call it instantly so that set that to zero and then we can give it a repeat rate and this is the awesome part so we can have it update the path every second every other second or every half second which I'm gonna do then all we need to do is take this code that updates our path and put it inside of our own function so we'll create a void update path and we'll paste that code right in we also just want to make sure that we aren't currently updating our path and then begin updating once more so to do that we'll just write if seeker dot is done which means that it isn't currently calculating a path well then we can go ahead and start a new one and with that we can save go back into unity and they play and as you can see our bird is now continuously going to update its path towards our player really really cool now we just need to make our bird actually flip to a point in the direction it's traveling just like we did before with the bird graphics however now I would like to do this within the same script so let's just go to the top here and create a public transform which is going to reference our enemy graphics and then at the bottom here we just need to add some code very similar to what we did inside of our enemy graphics script in fact we can go ahead and copy this and then instead of using a path that decide velocity x-wind simply use RB velocity X and the same thing here RB dot velocity so just the current velocity of a rigidbody and we don't want to adjust transform that local scale instead we want to adjust enemy graphics dot local scale so let's save that go into unity let's drag in our bird graphics and hit play and as you can see our bird is now going to always point in the direction that it's traveling really cool in fact maybe an even better idea is using the force instead of our RB velocity this way it will actually rotate to point in the direction that it wants to travel and not just the result of our velocity so if we say that that should actually look even better yep I definitely like that quite a bit also just if you want to get rid of all these debug logs they might be kind of slowing down your system you can always go to a star and under settings you can go to debug and set path lurking to none that should help get rid of them awesome that's pretty much it for this video if you enjoyed it make sure to subscribe and bring that notification bill so you don't miss the next one also don't forget to check out skills chair simply click the link in the description to get started and the first 500 people we receive the first two months for free on that thanks watching and I hope you'll all find your path to the next video also special thing hey do you want to do it yeah you should do it alright thanks all of the patron supporters who donated April and a special thanks to affinity PBR Sybok mommy Dennis Sullivan Kris Shane Cleveland by basil basil Python Faisal Merrifield Lincoln Chang Lee licit Ronan Daniel - sanic Constantinus clintus nayaki hasaki Gregory Pierce Rob fern dr. poon
Info
Channel: Brackeys
Views: 742,156
Rating: undefined out of 5
Keywords: brackeys, unity, unity3d, how, to, howto, learn, course, tutorial, tutorials, fix, tip, game, development, develop, games, programming, coding, basic, basics, C#, pathfinding, astar, no code, 2D, enemy, enemy AI, AI, ai, path, pathfinder, enemies, intermediate, vector, vectors, without code, beginner, easy, a*, project, navigation, navigate, navmesh, grid, follow
Id: jvtFUfJ6CP8
Channel Id: undefined
Length: 23min 13sec (1393 seconds)
Published: Sun Jun 02 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.