Advanced Enemy Pathfinding in Godot! ● Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up guys in this video I'm going to be going over how to make a two-dimensional navigation system in Godot this will kind of be an extension to the previous video I made on this and we'll just go more in depth on how to create like an aggro system and a return system for the enemies so as you can see here I have a really basic World setup we have a tile map with collisions and navigation on the floor and if I go into range of these enemies they will end up chasing me until I leave the aggro range as you can see and now it will return back to where they started which is defined as their like home position so I'm going to start a new project here and in this basic project I'm going to go up to the top left we're going to just add some basic things so we need a world scene we're going to save this in our world folder and then we're going to add a couple nodes in here the first one is going to be a camera the second one is going to be a tile map and then the third one we're going to need is a player which we'll create in a second now for the camera I just want to expand this a bit so inside of the camera 2D we're going to set the zoom to 1.5 just to zoom in a bit we're going to go into the project settings up at the top and the first thing I want to do is under rendering inside of the textures we're going to set the default texture filter to nearest and then inside of the display window tab we're going to go to stretch mode and we're going to set it to viewport I'm going to go ahead and import a few textures which I'll be using for this tutorial so as you can see down here we have an enemy Sprites a player Sprites and a basic tile set which has a floor tile and a wall tile now after we have all that imported we're going to set up the tile map first so click on the tile map we're going to go up to the top right in the tile set click new tile set we're going to click on that inside of the tiles field we're going to import in this texture and it will say the atlas texture was modified we're going to automatically create tiles in the atlas uh zoom in as you can see my tiles are 32 by 32 so we're going to have to change the cell size inside of the texture region size we'll change this to 32 by 32 and then inside of the tile Maps properties on the right and the tile size we're also going to change this to 32 by 32 and we just need to set up the physics and navigation for the tile set so in the physics layer we're going to add an element and make sure it's on the first layer here and then in the navigation layers we're also going to add an element and make sure it's on the first layer now back inside of the tile set editor here we're going to go into the paint Tab and we're going to select our physics layer as the property and this will be where our Collision is so we're going to paint this on the wall and then we're going to change our paint property to the navigation layer and paint this on the floor so that we have a navigation mesh on every floor tile now after we have that set up we need to organize our Collision layers correctly so go up into the project settings and scroll down until you get to two-dimensional physics our first layer name is going to be called world our next one is going to be called player and then we're also going to set up one for the enemy layer close out of this and our world should now be working so we can select the tile map make sure you're in select mode this will not work if you're in move mode for some reason just a glitch I've noticed and then we go to tile map tab down at the bottom and go into the pencil tool here and then if we select a tile we can paint with it so I'm going to use this Square tool and just make a floor quick and then we're going to use the line tool to make some walls for this world and then I'm just going to use the pencil and paint in some basic objects here just to test out our navigation now we need to create a player scene so I'm not going to walk through the really details of setting up the player script but I'll show the code and you can just copy it from there so we're going to make a new scene it's going to be another node we're going to make a character body 2D we can just call this player and then we need to add a collision shape to it so search for Collision shape 2D we're going to say new circle shape 2D and we're also going to add a Sprite to the player this will be for the visuals obviously we're going to drag in my player texture into the Sprite and then make sure the Collision shape is in front of this so we can see how big it is and we're just going to scale this correctly and then inside of the player kinematic body we need to set up the Collision layer so go to Collision it's going to be on the player layer and it's going to mask on the first three layers which are all the layers involved in this game we're going to save this in a new folder called player and then the last important step inside of the player is to set up the aggro activator so we're going to make a new area 2D and inside of here we'll give it a collision shape 2D and we'll just give it a circle we'll make it about as big as the player and then we'll go into the Collision for this area 2D and make sure it's on the player layer and do not mask anything now we need to add a script to this player so we're going to click the new script icon open this up and I'm just going to copy my player script and if you want to pause the video here and copy all the code here this is the entire script you'll need for the player now after you've done that before you run the game you need to set up the input actions for the movement so we just have some basic ones we're going to go into project settings under the input map we'll make a new action called move down move up move left and move right and then for the keys you can assign these I'm just going to put them as wasd and if we instance the player in the world scene here if we run the game select the current expand this you can see that we have some basic player movement working so that's all working correctly and we can collide with the walls and slide along them next up we can start setting up the enemy pathfinding so we're going to make a new scene here it's also going to be a character body 2D and we need to give it a collision shape for the world collisions we're going to make a new circle shape for this and we also need to set up a Sprite again drag this behind the Collision shape so we can see how big it is and we'll assign the enemy texture to this Sprite increase the size of this a bit and then we need to set up some basic nodes for how the navigation will work so we're going to make a new node here this will act as a navigation folder for all of our navigation components and inside of here we want to add a navigation agent 2D and we also want to add a timer node I'm going to rename this timer to recalculate timer and we're going to set it to auto start and we're going to set the wait time to 0.1 we also want to rename this to enemy and save it inside of an enemy folder quick and inside of the character body up at the top we need to set up a couple things so first off in the Collision tab obviously make sure it's on the enemy layer and it's masking all three of the first layers and then for the motion mode we actually need to set this to floating and we'll set the wall minimum slide angle to zero and this will allow the enemy to basically Move Along objects and it will slide around corners and walls and it will prevent it from getting stuck on anything so make sure you set this up and lastly we're going to add two different area 2DS we'll actually put a folder for these as well so make a new node 2D we're going to set this to aggro and then inside of here we need an area 2D and we need a collision shape for this and the Collision shape is just going to be a new Circle we'll make this one about this big this will be the area that you have to enter in order to activate the enemy chasing you and then we'll just duplicate this with control D and this circle will be quite a bit bigger this will be the area that you have to exit in order for the enemy to stop following you so this first one will name aggro range and the second one will be D Agro range and I also messed up these uh these two shapes are currently using the same shape resource so we need to just in one of these make a new circle shape for it so now our aggro range is about here we're going to set the debug color to red and then for our D aggro range it's going to be quite a bit bigger and this will be where you have to exit in order for the enemies to stop chasing you okay and then the last thing we want to do is inside of the navigation agent we're going to go into debug and enable it and this will just show us A visual representation of the path which the enemies are currently using for their pathfinding and we now have our entire enemy scene set up so we can get into the programming side of it so go into the enemy we're going to add a new script here click create and I'm going to walk you through how the code works so at the top first we need an export VAR this will be called speed and we'll set it equal to 50 for now we next need another export variable this one will be called nav agent and we'll just make it a type which will be navigation agent 2D we then need a variable for the Target node this will be the node that the enemy is currently chasing so we'll set it to null for now and then we need one more variable which will be the home position and we'll set it equal to a vector2.0 to start now inside of our enemy we need to remember to assign this navigation agent so click on the enemy up here and in the navigation agent property we'll just select our navigation agent 2D here and make sure that is all set up and now we need to initiate the ready function here so we'll write function underscore ready and the first thing we want to do is set up our home position which is where the enemy will return to when there's nothing to follow so we'll say home position equals self dot Global position we also want to set up a couple properties in the navigation agent which will be the distance it considers complete when it stops calculating the path so I normally just like to set these up so we're going to say navigationagent dot path desired distance and we'll set equal to four and then we'll also say navigation agent dot Target desired distance and we'll set this to four as well next up we need to do the physics process function so we'll write function underscore physics process Delta we can just put an underscore before the Delta for now and we're going to first check if the navigation is finished if it is then we're just going to return right away and this will prevent any jittering so we'll say if navigationagent dot is navigation finished then we're going to return and then we need to make a new variable in here called axis this will be kind of the direction that the enemy will be moving and we'll set it equal to two local and instead of here we'll put navigation agent dot get next PATH position and then after we get this we'll just normalize the whole thing and then next up we set up the velocity so we'll say velocity equals axis and then we'll multiply this by our speed and then the last thing we need to do in the physics process is just move and Slide the enemy and we should be done here now before we set up any of our signals we just need to make one more function and this one will be called recalc path and this will just recalculate the current path which we need to move along so the way I'm going to set this up is we're going to first check if we have a Target node that we're trying to follow if we do we'll calculate the path if we don't then we'll calculate a path back to the home position so how we do that is really simple just say if Target node then navigation agent dot Target position and we'll set this equal to Target node Dot Global position and then we can say else navigation agent dot Target position equals home position and that's the bulk of our script setup we now need to connect some basic signals just to get everything working so the first thing I want to do is go into the timer node we have here inside of the node tab on the right we're going to connect the timeout signal to the enemy script and then inside of the aggro range keep in mind this is where you have to enter to activate the enemy chasing you so inside of this one we're going to connect the area entered signal and then inside of the D aggro range which will be where you have to exit for the enemy to stop chasing you we're gonna set up the area exited signal and we're just going to connect that to the script as well now inside of the timer timeout we're going to make sure to call recalculate path this will recalculate the path every 0.1 seconds in this case you can change this if you want you can make it happen every frame if you'd like I don't recommend that but just depending on your games performance and the amount of enemies or whatever you have in the path finding you'll kind of want to adapt this to that but for this system this will work just fine especially since it can only calculate the path if there is a target that it's trying to calculate to next up on the aggro Range entered we want to assign our Target node as the area's owner so we're going to write area which is the area we entered and say dot owner and this will go get the scene owner of this area which in this case if we interacted with the players area 2D here it would get the main player scene and then it would set our Target to be the position of the player and then lastly on the diagra Range area we want to basically null out the target but we only want to do that if the current Target that we have is the one that exited so we'll say if area dot owner equals Target node then we're just going to say Target node equals null now if you'd want to expand this a bit where you have multiple different entities that the enemy could follow in the world you might want to consider adding a list and then basically what you do is whenever you interact with a new area you'd insert that area at the start of the list and then you'd always be targeting the first item in the list and then when you exit an area you just remove the that one item from the list and start targeting the next item down I'd say that's a pretty rare case in games but that's just an idea of how you'd handle it if you did want to do something like that but we're just going to use this system for this tutorial since that's a bit out of the scope here also I did want to mention that if you wanted to animate your enemies you could just set up a basic blend space 2D and then you could assign different animations on the blend space and then all you'd have to do is use this axis variable which would be the direction that your enemy is moving and then you could link this axis directly to the blend space position and animate them accordingly I'm not going to go into depth with that in this video I do think it's a bit out of the scope of this tutorial if you do want to learn how to set up a blend space for animations I'll probably be recording one of those in the future here so make sure to stay tuned for that but with that being said this is the entire system we'll need for the enemy so we can go back into our main World scene here and inside a 2d view we're just going to instant a couple enemies here just add one here I'm going to move it to the corner and then duplicate it with Ctrl D and move it over here I want to go into debug at the top and we're going to say visible Collision shapes and then we're going to run this again and we should have everything showing so there is a problem uh I forgot to mention if I go into the range of the enemy nothing happens and that's because in the area 2D over here inside of the enemy these aren't actually looking for the correct layer so basically we don't want them to be on any layer but we want the mask to be the player and we want to set that up for both of these so they're not on a layer and set the mask to player and now it should work we can go into the range and you can see they start chasing me if I go into the other side of an object they can still find a way around and they slide around the corners they don't get stuck or anything and then if I exit their range they're going to return back to their home position and I think this works pretty well you can also have multiple enemies Target you at once obviously if I don't get out of range here like this and we have both the enemies chasing me and now they're both going to return to their home position so pretty cool dynamic system um really easy to implement for any of your games I do think it is pretty efficient obviously whenever you update the navigation path for things like this it will take a pretty big hit on performance depending on how many enemies you do have in your scenes so I would recommend figuring out the best intervals to update this at maybe even go up to like one second delays you could also try to figure out something where your grouping navigation for multiple nodes which could be really helpful for certain games where you have like enemy swarms and whatever and maybe I'll make a tutorial for that in the future but just wanted to get this out to you guys since I know some of you have been waiting for this tutorial and I went on vacation and then ended up getting sick so I really haven't been able to record much or do anything so I apologize for that but like always if you have any suggestions for ways to improve the system make sure to leave a comment and let the community know what you optimized and also if you liked the video or learned anything new make sure to hit the Subscribe Button as it would help the channel out quite a bit but with that being said thanks for watching the video hope you learned something new and I'll see you in the next one bye
Info
Channel: Queble
Views: 12,534
Rating: undefined out of 5
Keywords: godot, tutorial, game, engine, howto, video, programming, coding, how to, game development, game design, video game, learn, efficient, description, stats, 4.0, new, logic, objects, pathfinding, enemy, chase
Id: MtEh6vofiqQ
Channel Id: undefined
Length: 18min 53sec (1133 seconds)
Published: Sat Jun 10 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.