Godot Top-down Shooter Tutorial - Part 3 (Shooting and Bullets)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone and welcome to the third video of the top-down shooters tutorial that we're doing in Godot I hope you are very excited for this episode because we are gonna do some fun stuff like adding the ability to shoot and actually spawning bullets so really gonna start to feel you know a little bit more like a game if you were just joining let me show you where we left off last time so in our last video we had added some code that let us actually move our character and rotated it around based on where the mouse is which is cool so we've got a lot of the player movement stuff in place now we just need to actually add some stuff for the player to do like shooting so that's gonna be the main focus of our time today and in order to do that there's gonna be an extra asset pack that we're gonna have to download because the top-down shooter one that can he provides it doesn't actually have any bullets or fire effects or particles and those are things that we're gonna want in our game just to give it kind of a better feel and and really make it clear to the player what's happening right like you one want a game a shooter where when you shot like nothing happened like that would be really terrible it won't feel good and the feedback won't be there so we want to make sure we're kind of adding at least basic versions of that as we go so I'll have the image up on the screen and the link will be in the description below to get the tanks pack from Kenney which is we're gonna use primarily not for the tanks but just for some of the bullets and other effects that he has in there so I downloaded the tanks Redux pack right here and so you can see I've got it in this cannon a top-down thanks etc all this in here and we're gonna get to that in just a second but the first thing we need to do is actually add code that will let us shoot a bullet that'll let us attack and in order to do that we're gonna come back to our project settings and add another input for attacking so there are already inputs here by default that come with a mouse click I believe actually that might not be the case okay well no matter either way we're gonna add anyone I like having explicit inputs for everything I do even if some of those things might be overlapping you know maybe you have answer that does one thing if you're in a menu and one thing somewhere else I like to still make those explicit because then you're the label that you're using when you're actually calling those strings from within your code is very clear like what action you're calling so we're gonna add one here that's just shoot I'm gonna add that and we're just gonna make this be a mouse bun and it'll be left bun so now whenever the player left clicks we will be a shoot event basically will get fired off so now we can actually listen to that in our code and this is where in the previous video when I was talking about different input handling and where he's ways you can do it this is where we're gonna actually start using input handling that is not in our process function so what I want to do is add function unhandled input and you should see this autocomplete because it's a built-in function for any note I believe in Godot and so what this means is that we're not gonna be calling the code in this every single frame like we are in process which gets run every frame for every you know node that has a script attached to it instead this on a handled input function is going to get called whenever there's an input event that happens and it gets to this like it gets to our player and nothing has handled it yet so we're only gonna call this and only gonna process our logic here when do we really need it so for performance sake not that we really have to worry about that right now but just trying to write good code you know as early as we can this is gonna let us write code that is more efficient when we're actually handling inputs so the way that we handle inputs in our unhandled input looks slightly different than it does up here in our process function so instead of looking at our input object we're actually going to look at the specific event that this function is getting called with so on and Olympique gets called once per event so you can actually just listen and work on the event that gets passed in so we can say if event is action released shoot this should just whoops I'm trying to there we go so basically when the shoot button is released and you'll notice that I'm doing it on release and not press it doesn't really matter in this case this just means that you'll shoot when you lift your finger off the left mouse button instead of when you press down on it but we want to do released or pressed not like we don't want it to hold down right now so I'll just do released and then when we do release it we actually want to shoot of course we don't have the functionality to do that yet but what I'm gonna do just to stub that out is just add another function that I'm gonna call shoot okay and there we go alright and now we can actually fill this in with the functionality that we want okay so now that we have our shoot function you can actually call that here so we'll call that every time the player shoots and just for testing purposes we can just add a print statement here saying something like the player's shots real poetry right there and I can run this and if I click we'll see the player shot appeared down below sweet cool alright so now we have just you know our basic shooting functionality there obviously it's not doing anything but before we actually add anything else here to the players script I think we really just need to add you know something to shoot a bullet so what I'm gonna do is select our main node and then I'm gonna add as a child of that an area 2d and what an area 2d is is it's something that can still detect collisions but it doesn't actually cause collisions so I guess a better way to say that is it detects overlaps it detects when other physics bodies or even other areas enter it or exit it but it doesn't actually cause a collision so like if two areas hit each other or you know a kinematic body like our player enters an area it's not gonna stop it like it's not gonna have a hard collision so they're really good if you have you know like a pickup for example like a health pickup or it's good if you want some kind of a trigger where when the player walks here you should do something it really just any I mean infinite amount of cases where you want to be able to detect when a player something has entered a certain space or exited it and so that's what an area 2d is good for so with that let me name this bullet okay and similar to our player we still have to give it a collision shape so I'll do that question check today and let's before we set the collision shape let's also give this a sprite and here's where I'm gonna make use of the tanks pack so I'm gonna grab and Kenny's up don't tangs come over to a spreadsheet and I'll do I think only objects default was the one there we go so I think the one that I want to use typically you want like it's kind of hard to notice bullets if they are really dark you know even though real life like bullets are technically like dark metal typically like bullets are also flying really fast and they're emitting a lot of energy and there's lights and they're they're bright and they're loud and you want it to be something the player notices like there's a bullet you want to give them a chance to dodge it or see where it's coming from so you want to be something noticeable and that emits like some kind of like it's something that you can notice and see and so because of that I think the one I'm going to use now there's a like a light gray one in here somewhere oh this one right here so what I'm gonna do similar as before enable our texture region pop open this texture region button that will appear and zoom in that's very sensitive and so I'm gonna have to bring our step down a little bit because this is a pretty small image and I'll just drag right there perfect cool so that'll be our bullet for now and now I can actually give it a collision shape I'm gonna make this one a rectangle too I'll make this smaller and so you'll see that our current grid step 4 for our main area is also too big so how I can are I can change that up here by hitting this little snapping options button coming and do configure snap and changing our step here I'm just gonna do let's see before I know I had a 2 down below but I think 4 will be okay yeah I think I think that's fine for now to give it a little bit of a leeway and you know we can make it smaller later on if we need you don't want to keep your grid step too small or at least keep it small you know if you have to make it smaller just to adjust something like this that's fine usually you want to bump it back up because if you zoom out you're gonna start getting some significant lag when it has to the editor has to draw so many grid lines but 4 is not really that bad ok so now that we have our bullet what I'm actually gonna do because we don't want you know to have a bullet just sitting here obviously I'm going to save this as its own scene and in order to do that you can right-click on it and then come down to save branch's own scene and what that will do is it will save not just you know your parent node but any child nodes like the entire node tree as its own scene so I'm gonna do this and save it as bullet dot T s CN and now we just have the bullet you know it's like it's become a node basically in itself all those nodes we added still exist under the hood but now you're just interacting with it as a whole and if you ever want to edit the bullet again you can either find it in your project drop-down and your folders over here or you can actually just hit this little scene icon here which will pop it open in the editor and this is one of the best things about Godot is that you can edit individual scenes and you can play them so we're gonna do the same thing with our player here I'm gonna save branch's scene we'll make a player scene and now I can either run our main scene by hitting you know command B or running the whole project but what I can also do is if I go to our players scene you'll see there's a run scene button which is command R and if I do that it's just the player so this is a way that you can test and work with subsets of your you know main scene you can run individual scenes like if you're editing player controls and don't want to start the whole game up you can just run an individual scene which is just a really nice feature of Godot it makes it easy to work on individual parts of your game or scenes at a time so now that we have both of those saved off as their own scene we can come back over here and what we're gonna do is go back into our player scene first I'm gonna delete this because we don't actually want it there you can come into our player scene and what I'm gonna do is save a reference off to our bullet so similar to with our speed variable I'm going to create another export variable export impact scene of our bullets and so what a packed scene is is it's a reference to a scene itself not one that's in-game but it's a reference to like the scene data and what you can then do is instantiate or create individual instances of that pack scene as actual scenes in your game so what we're gonna do is come over to our player and you'll see now that I've got an empty bullet variable here on the right and I can load in a pack scene I can just drag it but I'll load it this bullet that we created and so now like we have this reference to the bullet scene that we created right here and now we can reference that from within our code and create new instances of that bullet scene and that's exactly what we're gonna do so I'll come down here and now in our code when we shoot what I'm actually gonna do is say var bullet instance and I guess the actual GD script formatting is that when you're referencing a packed scene that you uppercase it since it's you know a scene similar to how kinematic body is uppercase for example or vector 2 is like whenever you're referring to a class or a node you uppercases so we'll have a reference to our specific bullets bullets instance excuse me which will be bullet dot instance cool so it doesn't give you autocomplete but this instance is the function you call on any PAC scene to create a version of it so now once this code gets run we're gonna create a new bullet and save it to our bullet instance but if you were to run it right now and you clicked you wouldn't actually see any bullets appear and the reason why is because it's not enough just to create an instance of a bullet you actually have to add it to your scene tree so by default when you create something the like that that a scene is created but it's not actually rendered on to the screen it's not added to the scene tree and in order to do that we just need to do you need to add it as a child of something what you want what we want to do is add it as a child of Maine just for a sake of quickness I'm actually gonna add it to our player so I'm just gonna call it add child from the player and add our bullet instance and now if I run this we should see bullets appear oh whoops appears that I oh you know what it's because I changed the name of bullet and then I have to drag and bullet back in that was my bet so we got that okay now this time when I click you'll see bullets appear and they're appearing on my face which is not ideal but there are bullets that are getting spawned so now what we need to do is actually have those bullets go somewhere and I don't think we're gonna get the full bullet shooting functionality in just because this video is gonna get kind of long but what I want to do is just have it where when we click a bullet is spawned and it moves and that'll be it for now and then in the next video we can worry about actually spawning our bullets as children of our main scene and actually have them you know do some more handling and fun stuff with them so for this video what I want to do as just have our bullets spawn at a given point and go in a certain direction so in order to do that I'm gonna come into our player scene here and I'm gonna add this is this is a really common thing you'll see I'm gonna add a point TD or a position 2d excuse me I'm gonna call this end of God and what I'm gonna do is drag this around so this is our point right here I'm gonna move it I'm gonna turn off good snap for just a second let's just do this manually right there that looks good so here is gonna be like an end of gun in what I want to do is have our bullets spawn here I don't want them to spawn here I don't even really want them to spawn here it doesn't you know it kind of looks weird if they're coming like through the gun you kind of just want them to start and spawn and appear like right at the end of the barrel so I want to do that and so what I can do to reference a node in our scene tree is I can use the unready keyword and say on ready var and gun and I'll set this to be and of gun and so what this line is doing is one we're getting a reference to our end of gun node that's what this is right here if you use the dollar sign it's basically a shortcut for to select nodes within the current tree and so it's just gonna find whichever node is a child of the node that has the script which is our player so it's gonna find the child named end of gun and save that to a reference here and the reason that we use on ready is because we only want to get this reference and use it when our gun is actually ready and what being ready means is that it is in the scene tree it is good to go it's not still initializing I'm sure later on we'll kind of get more into that what it means to be ready but for now this will be good and so what we want to do when we add our bullet instance is we actually want to set our bullet instances position so I'm going to be global position set that equal to and a gun that global position okay and now oops I must have messed something up oh yeah I totally got rid of that parenthesis it's fine can't type today so now we'll see the bullet spawn at the end of our gun which is great so that's working obviously it's still not right or not exactly where we want it to be but the last thing we'll do is just give our bullet some velocity when it spawns so one we shoe we want the bullet to head towards where the mouse is so what we want to do is when we shoot we want to store where a mouse is so for example I can save our target equals and get in global Mouse position we'll use that same function we did before so this will be a vector to position of our mouse and what we can do is say something like our you know direction to Mouse so right here is getting where mouse is but now we actually need to get the direction - and hopefully you are at least familiar with some pretty simple vector math so in order to do that we can just do Target - and or I guess what we really want to do is pull it instance that global position so we're getting basically the position of our mouse and the position of our bullet and then subtracting our bullets position from the targets position to get the angle - like the vector the direction vector towards it actually though the nice thing is that Godot basically gives you a convenience wrapper over this exact thing where we can do bullet instance that direction whoops global position dot direction geez can't type direction - and then we can give it target and this is doing the exact same thing that we just did you're just giving it a vector you're calling it on a vector - so we're taking the global position of bullet and getting the direction to our target which we'll just also return vector which we can then normalize and then so now we have a direction to our mouse and the last thing we need to do is actually give some speed to our bullet and we're not going to be able to do that from our player script so we're gonna need to add a bullet script so if I come over to our bullet scene I'm going to add a script there and here we'll also have similar to our player a export int of our speed you'll set this to be 300 so it's not lightning fast but definitely faster than the player which we used 100 and then what we can do is just do this for now and we'll use our process function i'll uncomment this out and we can just do oh actually I am switch the order that around first we need to expose some kind of a function here that lets us set the direction so it's not enough to just have a speed right we need a direction and so what I'm also gonna do is just say of our direction which is just gonna be a vector - and I'll just say vector - that's zero right now so it'll just start as an empty vector and I'm gonna have a function up here that will just be tonk set direction and this will take direction back - and here you can say self that direction equals direction I'm not really good with names so I usually just you know do this where I just call the parameter the same thing as the actual field we're gonna overwrite and then in order to do that you can just use self to reference the field versus the parameter like the one we have saved on this actual script and so now we have this function where we can call it pass in a direction and set that as our direction and now in our process function what we can do is say if Direction is not equal the vector - that's zero so we only want to move if we actually have a direction right otherwise we there's no point so if we have a direction then we can set our velocity to be her direction vector times our speed and now that we have that we can actually adjust our position so area 2ds don't expose like a moving slide function like kinematic bodies do so we just have to manually add or or change our position so what we can do is just say global position equals or whoops plus equals velocity and then it'll just add this vector into its global position and that's gonna work for us because this direction vector will be negative you know if it's heading left or up or something so adding it will be totally fine because the direction will you know have the right sign it'll be negative or positive and the way we need and then we can just multiply it by our speed so now we have this there's probably some people watching this that are screaming about me doing this in process and I feel you we'll get back to that but right now we just want to make sure we can actually spawn this bullet so we have the ability to set the direction and it should be moving once the direction is set so on our player we can actually now say bullet instance that is set direction and we're gonna give it direction to Mouse and once we do that we should see it moving very quickly okay so you can see I don't even know if you can see that on the screen but you can see it moving in the right direction but it is lightning quick and so one of the big reasons why this is not the whole reason why but one of the big reasons why is because we are doing all this code in our process function so process is really good for things that need to happen every frame like we've talked about but whenever you are moving something that ties into the physics engine somehow you want to do it in a function actually called physics process and the reason why is because process gets called a certain amount of times per second and that value goes up and down that's what your FPS is your frames per second and so if you've got a really high FPS you're gonna call process a lot more and if it's really low you'll only call it a few times a second and what that means is that our bullet is gonna be faster or slower at any given time depending on what your FPS is and we don't want that right we always want our bullets have the exact same speed and so the way we can do that is by changing this to be physics process and what physics process is it's a function that gets called at fixed time interval so only every few seconds rather than a few frames or not every few seconds like milliseconds and it basically ensures that you always have a constant array of things and so whenever you've got something that should be constant and basically anything that involves movement really you want to do it in physics obviously anything that is you know using the physics engine you want to do it in physics process whoops accidentally got rid of this but so now this isn't gonna fix our issue but it should be at least be a little bit okay no it's not better at all it's totally fine but that is still something we needed to change the reason our bullet is lightning quick is because we were giving it this really high value that's gonna be like you know basically every physics tick it's gonna move like 300 units of measurement 300 pixels basically which is a whole lot so let's just try keeping it a 10 and see how that goes and that's a lot better cool okay so we can see we have a bullet it's getting shot we definitely still need to work on actually rotating our bullet but it's getting shot and it's going in the direction of the mouse a really not good thing you might notice is that when I move the mouse all the existing bullets move with it which is very much not what we want and the reason that that is happening is because of the thing I was talking about just a little bit ago because we are setting our bullets to be children of our player so children by default have the same scale and transform as their parents like the same relative transform so that means that whenever we rotate a parent all the children get rotated by that exact same amount and whenever we move a parent you know 10 units up all the children go 10 units up so that's really bad for a bullet because since we're rotating our player to face our mouse it means that our bullets are also going to be rotated to face our mouse which is obviously not conducive to a shooter so that's something we'll tackle in the next video we'll tackle you know changing over a player this also should use our physics process well tackle rotating our bullets will tackle making them children of our main scene and with that we'll start looking at connections and signals and start doing that and then hopefully by the end of it we've got a shooting system that works and bullets that feel good and that are getting recycled after they've been around for a while so anyway whoo what a video this one got packed with a lot more stuff I thought but thanks so much for hanging around and listening and sticking till the end I'll try and keep them a little bit shorter going forward but appreciate your time hope this was helpful take care [Music]
Info
Channel: jmbiv
Views: 12,897
Rating: undefined out of 5
Keywords: godot, godot engine, godot 3.2, godot tutorial, godot top-down, godot 2d, top-down shooter, how to make a game in godot, game development, game development tutorial, game development for beginners, godot for beginners, how to make a top down game in godot, how to make a top down shooting game in godot, game dev, indie game dev, indie game development, how to make video games, how to godot, hobby game development, gamedev, godot game engine
Id: ggt05fCiH7M
Channel Id: undefined
Length: 27min 45sec (1665 seconds)
Published: Sun May 03 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.