Raycast Weapons in Godot - Make an FPS in Godot Part 2

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Check out GodotWeapons. It's a plugin I wrote to complete a lot of the logic you're implementing here, built with a composable design.

👍︎︎ 3 👤︎︎ u/JarLowrey 📅︎︎ Aug 16 2019 🗫︎ replies
Captions
what's going on guys Tom here and in today's video I'm gonna be teaching you how to create a ray cast weapon system Ingold are complete with clip size firing rate and reloading if you haven't already followed part 1 of this make an FPS in Godot series I'll leave the link in the description below so you can go back and watch that first alternatively you can grab the source code for everything that we covered in part 1 in the description below as well with that being said let's get started ok so as always the first thing we're going to do is we're going to launch go to the FPS tutorial 1 project that we had from the first part of this tutorial you should see it here you should can click on that and press edit now while that's loading if you didn't if you didn't follow through with part 1 of this tutorial series you can grab the source code from the description below you could also just go back and watch that tutorial follow along and then you'll be at the exact same position that we're at right now where you have a player in the middle of the screen which is this capsule Collider here it's got a camera pointing out roughly where the head would be and we have a ground object here which it has a Collider on it which allows our player to land on it if we press play you can see that we have full control with our mouse of looking up down left and right we can use WASD to move forward backwards left and right what else to press space to jump and you'll also notice that we have gravity in place as well so that's where we left off in part one like I say go and grab the source code for that or follow along catches up and then come back to this video ok so what we're gonna do now is we're going to create a ray cast weapon system now in order to do that we're actually going to have to do a couple of things one being added ray cast to the player and to write some scripts to interact with that Ray cast to determine whether or not the raycast actually collided with anything when we fired the weapon so what we're going to do is we're going to come into our player object and click into the player's scene and now we want to click this camera icon here and right click on it add a child node and we're going to add a ray cast to the camera now the reason we're adding a ray cast to the camera is we want the raycast to fire out directly from where the camera is is directly to where the camera is facing so that's the exact center of the players viewport now if we add this ray cast to the camera as a child node it's going to be in that exact position which is great so we're going to click on the ray cast and on the right hand side you can see that we have a few options here the first thing we're going to do is click enabled to make sure that this ray cast is actually going to detect collisions we're going to keep exclude parent on which means that it's basically going to take its parent node and it's going to exclude that from any collision detection and we're going to change the cast to property we're going to change Y to zero and we're going to change Z to negative 100 now you'll notice here that this faint line has appeared directly in the center of the camera and it's shooting off into the horizon they're pretty large distance now that is effectively the distance that we are going to check for collisions in so that is effectively the firing range of the weapon that we create we can modify that obviously by coming into the z axis again and changing it to negative ten obviously that's a little bit short for a projectile weapon so we're going to change that back to negative 100 you could modify this with scripts you know if you had a weapon that say needed a larger firing range or one that had a shorter range such as a shotgun then you could come in and you could tweak that or you could have it done directly by the script of the weapon itself the next thing we're going to do is we are going to create a script which serves as the basis for all weapons now I said we're going to create a ray cast weapon system what I mean by that is we're going to create a generic script that is a ray cast weapon which you're going to be able to then inherit from ngd script to modify some of its parameters such as its firing rate its clip size and its reload time to do that we're going to right click on the player we're going to add a child node and this time it's just going to be a node if we scroll up to the top here choose a node and press create we don't really care where this is in 3d space it doesn't actually need to be in 3d space at all we're just going to create as the base node object we're going to right-click rename it and we're going to call it weapon now we're going to right click on this weapon attach a script leave everything is default we're going to create this weapon Gd script press create what I'm going to do is I'm going to delete all of this and now we're going to set up some variables for the different kinds of parameters that our weapon can actually have there they're going to be export var fire rate and we're going to say that for default firing rate between each shot is gonna be 0.5 of a second so half a second next we're going to export a variable called clip size for this I'm just going to choose 5 we're going to export a variable called reload rate and that's going to be the time it takes between firing the weapon to empty and reloading it to full clip size again so for this I'm going to say one second ok the next thing we're going to do is we're going to keep track of what our current ammunition is and to do that we're going to say var current panel equals and we're just going to initialize this to whatever our clip size was so clip size the next thing we need to do is we need to determine whether or not the user has actually fired the weapon now if you followed the previous tutorial you'll know that to modify the project input map we can go project project settings input map and then we can add a new action here it's what we're going to do is we're going to say primary fire we're going to add that click the little Add button to the right-hand side of it choose mouse button and just leave it as default which is device 0 left button press add and now we can close that so we're going to create the process function so func underscore process and here we're going to say if input dot is action just pressed primary fire primary fire then effectively here what we're going to do is we're going to fire the weapon so there's a few things we need to do to determine whether or not we can fire first of all we need to check whether or not we have any ammunition we also need to check whether or not the firing rate time has elapsed so we're going to need to create sort of a little helper function here or a boolean that can tell us whether or not we're allowed to fire now I'm just going to specify a boolean variable here called var can underscore fire equals true which means that this variable is going to determine whether or not we're allowed to fire and initially we're going to say yes the player can fire the weapon so we're going to add this to the end of the if statement here we're going to say and can underscore fire I'm going to fire the weapon so here I'm just gonna say print fired weapon and we'll save that now we're just going to test this quickly by pressing play we can look around we click the left mouse button and you'll see down here in the output it says fired weapon you'll notice that we can just click click click and it will just say fired weapon over and over again we don't have that fire rate delay in place so what we're gonna do here is we're gonna say as soon as the user has pressed primary fire we're going to say can fire equals false so they fired the weapon now they can no longer fire the weapon until this fire rate has elapsed so let's just put that down just below the print just so that we know this is the start of where we're firing the weapon we're saying we can no longer fire and now what we want to do is elapsed that fire rate time to do that we're going to say yield create underscore or sorry get underscore treat dot create timer and this wants to take a time in seconds so we can pass in fire rate we can close our brackets there comma and now we want to say what event we actually want to wait for and we want to wait for the timeout close the brackets and now after this point after this yield statement it basically means that the fire rate at time has a lap so that that yield statement there is effectively saying I want to wait before I execute any more code in this function I want to wait for the fire rate so we're gonna wait for not 0.5 seconds and then we're going to say can fire equals true we'll save that or press play again and we'll just check that that timer is working so we're just going to keep clicking and you'll notice that that has slowed down significantly just to prove it a bit more easily we're going to say two seconds save that press play we can fire the weapon and you'll now notice that there's a two-second delay between each time we fire the weapon cool okay so let's change that back to not 0.5 the next thing we need to do is we need to decrement the current clip size so here we're going to say current ammo - equals 1 so we're going to reduce 1 from our clip size each time and now what we need to do now is we need to determine whether or not the player actually has any ammunition before we can fire so now before we fire the weapon we actually want to check whether or not we need to reload or fire the weapon depending on what their ammunition stay is so just before this print statement we're going to say if current ammo is greater than zero then we can do all of this we can go ahead and we can fire the weapon otherwise what we want to do is we want to reload the weapon so here we're just gonna say absolutely just gonna say else then we're effectively going to do the same thing here we're going to yield a weight and we're going to reload the weapon so we're going to show you say yield get recreate timer reload rates and after that here we're going to say it current ammo equals clip size we're also just going to put a print statement in here that says print reloading and we're gonna another print statement down here it says reload completes we'll save that we'll press play and now with fire you'll see that we can fire five times and then it starts to reload and then we can fire our weapon again as soon as the reload is complete what we do want to do though is we want to check whether or not the player is already reloaded we don't want to let them reload multiple times because that could start to get out of hand you can start to get some weird race conditions there so we're gonna keep track of whether or not they are currently reloaded to do that will save our reloading equals false we'll do a check here as well just to see whether or not they are currently reloading so we'll say if the current ammunition is greater than zero and they're not reloading then that's fine we can fire the weapon because what we don't want is we don't want the user to start reloading and be firing at the same time here we're going to say L if not reloading just was where you print out our print reloading here we're gonna say reloading equals true and when we're done reloading we're gonna say reloading equals false so let me just run you over that one more time because I realize that is a little bit confusing we've added a few extra and causes to our conditional statements here so we've defined a variable to say whether or not the player is currently reloading we're checking to see whether or not we have fired the well sorry we can fire a weapon and the user has pressed the fire button if that is the case then the first thing we do we check whether or not we have I mean any ammunition left and that we're not currently reloading so we're not currently reloading the weapon we have ammunition and the users press the fire button in that case we want to fire the weapon otherwise we're saying if we're not currently reloading so we're not currently reloading and we don't have any ammunition left because this clause has failed then we're going to reload the weapon we're going to set reloading to true which means that all of this is going to not pass the next time we use it hits the fire button they're not going to be able to fire once we're in the process of reloading it's going to wait for the reload right it's going to reset our clip size I'll current mo to our clip size and then it's going to say okay well no we're no longer reloaded in you can carry on and fire the next time that the user presses the button we're going to press play and now I want you to watch the output screen again we're going to fire five times one two three four five it's going to say we're reloading as soon as it's done we can start firing that weapon again and you'll notice that that is the same it's consistent every single time we get five shots we get reload we wait for a period of one second and then we can fire again at a rate of 0.5 seconds so now we've got our working weapon raycast system with you know the ability to fire the ability to have a fire rate in between those fires have a clip size and a reload rate the next thing we need to do is allow our raycast weapon to actually hit something in order to do that we're going to come back to our world and 3d scene and we're going to add something to the world that just acts as an enemy to do that we're going to right click add a child node we're going to have a static body we will right click we will give it a mesh a mesh instance and we're just going to give it a let's give it a sphere just to differentiate it slightly from the player itself now we will right click on this add a child mode we're gonna give it a collision shape that collision shape again is going to be a sphere shape and we're just gonna call this enemy now the next thing we're going to want to do is we're going to want to assign this enemy into a group now groups are something that's quite useful and good off for allowing collision detection to check whether or not the thing that it collided with is actually part of a set of objects of a part of a group to do that we're going to click on where it says node in the top right we're going to click on groups and here we're just going to type a new group and we're going to call this enemies now if we look over on the left hand side here you can see that next to this enemy it's got this little square icon here and if you click on that you'll notice that it's over here that this is part of the enemies group so this icon here just gives us an indication that this node as it says there on the on the tooltip this node is in a group click to show the group stock so you can do that and you can see what what group a particular node is path now we're going to duplicate this enemy just a couple of times so we will right click and duplicate we're going to move it just a little bit over here or duplicate it one more time with ctrl + D and we will drag it over this way a little bit and we'll save the scene there okay so we're going to go back into our script and back into weapon now what we're going to do here you're going to create a brand new function and this function is just going to be called check underscore collision and we're going to call that just where we fire the weapon so just underneath decrement in the current amount of ammo we're going to say check underscore collision we'll save that and here we're going to say var raycast equals dollar we're going to say double dot slash head slash camera slash recast in fact we can move this to the top here so we can say on ready on ready var raycast so we can get referenced that as soon as the nodes loaded so here back down here in the check collision we can say if recast dot is colliding so if the raycast is currently colliding something with something then what we can do here is we can say if or let's say var Collider equals recast get underscore Collider and then we can say if Collider dots is in group we can give it a name enemies then we're just going to print in fact what we can do is you can say Collider free underscore cube and we can put print killed let's just scroll that down killed Collider dot then save that let's run the game if we fire now you'll see we've fired the weapon if we look at the sphere looking fire and we're getting an error here Q 3 Q is incorrect that I should be Q underscore free play that again by the weapon in space fires nothing click and now you can see we've killed enemy look at this one killed enemy 3 look at this one killed enemy too cool okay so that is basically our ray cast weapon system sorted the next thing we can do now is we can inherit from this weapon and we can just start doing some advanced things here so what we're going to do is we're going to create brand new script inside our player folder we can say new script we're just gonna call this pistol or absolutely let's let's call it shotgun just to be a bit more accurate to what we're going to do so we're going to press create we're going to come into the shotgun dot Gd script delete everything and then we're going to type extends weapon now if we come back into our weapon script you'll notice that we gave it a class name of weapon so we can extend that weapon class and now we have access to everything that the weapon class had itself so if we come into our weapon node on the left-hand side here and change our script from weapon to shotgun you'll notice that we still have access to a fire rate we still have a clip size we still have a reload rate so I'm going to change the clip side here to 2 I'm going to change our fire rate to 1 I'm going to eat a reload rate the same we'll save that and in the shotgun what we're now going to do is we're going to change the length of that ray cast because we're now firing a shotgun it needs to be much closer range this is just a simple example of what you could do with inheritance to create brand-new weapons with different functionality to do that we're going to save func underscore ready and here we're going to do that same thing again where we get an unready reference to the rapist so unready VAR a caste equals dollar dot dot slash head camera rate cast and we're gonna say ray cast dots cast to equals and we're gonna give it a brand new vector3 we're going to call this we're going to say back three zero on the x zero on the Y and actually what we will do is we'll create a new exported variable here just to show you that we can actually have multiple exported variables dependent on our inheritance tree so we can say export var and let's a fire under store range this time we're going to say ten I'm going to say here we're gonna say negative fire range so we will save that and actually it's giving us an error here because on our weapon object we already have access to a recast variable which is great so we can actually delete that save that and now if we press the play button you'll notice that we can fire the weapon we can fire we can kill that enemy but if we try and kill that enemy over there it's not doing it and if we get closer and closer and closer we can now kill the enemy basically the range of our ray casts same to this one we can fire fire nothing happening let's get closer oh we need to reload fire again and now it's killed the enemy so you'll notice there that actually what we did was we took our weapon based script we inherited from it in a shotgun script and we made modifications to the raycast length so that it's now a little bit shorter and you'll notice on the right hand side we've now got this fire range property which is an extra property that we can modify on this shotgun script now you could do this for pistols shotguns machine guns you could create automatic functionality you could have weapons spread you can have a whole bunch of different things on different weapon types maybe you have a weapon that needs to charge up before it fires you can do all of that so this is just a very very simple example of the power and flexibility you've got by having this base class of a weapon and then inheriting from it to do something slightly different for that weapon the final thing I want show you guys is how to create a very very simple little display of how much ammunition we have to do that we're going to come on over to our 3d scene view we're going to go back into the world and here what we're going to do is we're going to say right click on the world we're going to add a child node and here we're going to choose a control we're going to click on that and this is going to open us up in the 2d scene view basically we're going to now create a little bit of user interface I'm gonna rename this to UI at the top here I'm going to press layout and I'm gonna say full rect now you'll see that that has expanded this rectangle here to be the full width of the screen I'm gonna add a new child to this and I'm just gonna have a label control we're gonna just size this a little bit it doesn't need to be precise right now and we're going to put it at the bottom wide or so let's actually say bottom right and here we're just gonna give it some text so we're just going to say ammo and let's just say two out of two and now what we're gonna do is we're gonna go into our player object we're going to go into the script for the weapon now what we're gonna do here is we're gonna get reference to that UI label to do that we're gonna say unready bar i'm or label i'm i underscore label equals and I'm gonna say dollar sign open up our speech marks and to get the root scene what we're gonna do is are going to type forward slash routes now if you come back into the world scene you'll notice that we're in the root then we're in UI and then we're in label so we're gonna say routes slash well sorry we forgot the world so root slash world slash UI slash label so this case is a reference to this mo label we're going to save that and now in the process what we're going to say here is we're just going to update the text of that so mo underscore label set text and now we're going to do some string interpolation what that means is we're going to create a string where some of the values in it are going to be replaced by variable values to do that we're gonna say percent s or 30 percent d / percent D and then after that to provide the parameters for those percentage placeholders we're going to say percent and then we're gonna give it an array we're going to save current ammo and clip size let's close off that and now if I press play you'll notice that we have this label down the bottom right hand side which says five out of two which there's a little bug there actually and that is to do with the fact that we're assigning clip size to our current ammo directly there so what we will do is we'll say the current ammo equals zero I'm allowed a quick ready function here and here we'll just initialize ammo to be our clip size save that press play again and now we have two out of two so that's that problem fixed you'll notice that if we click it goes down to one because again it goes down to zero and we click one more time and after a second or two it reloads back to two which is great that gives us a bit of a visual feedback as to how much ammunition we have and whether or not we're currently loading we could go one step further and we could actually say if we are currently reloading so if we loading then we can basically say an old label box set text change that to reloading dot else we can set it to how much ammunition we have press play again to up to fire fire again fire one more times as reloading and now we've got two out of two again obviously you could do some fancy stuff with sprites and all sorts of other UI elements there but that's just to give you a bit of an indication that you can now present some form of indicate as to how much ammo the player has final final thing that I want to do is I want to break out this reloading script into its own function so I'm gonna create a new function called func reload and I'm just gonna take all of this code here I'm gonna cut it paste it in there take out that whitespace call this reload actually we're going to do the same for firing so we're gonna say func of fire we're gonna put all of this code out here paste it into there clean up some of this white space whole fire there and we're actually going to get rid of this comment this just makes it a little bit easier to see what's going on finally we're going to go into our project project settings input map I'm going to define a new action for reload I'm gonna give it a key of our and we're gonna say now here is if input is action just pressed reload and we're not currently reloading then we're just going to call that reload function again press play I know you'll notice that I can fire once and I can press the our key and we start reloading I can fire twice and press the R key we start reloading and that just gives us a little bit more flexibility about when they can play it when the player can reload their weapon and that's it for today's tutorial so today you've learnt how to create a weapon system with fire rate reload rate and clip size you've learned how to add some UI elements onto the game so you can give it an indication to the player of how much ammunition they have whether or not they're reloading and we've also implemented the ability to actually reload an arbitrary time just in case the player wants to reload when they're a half clip or whatever and I've also shown you how to inherit from that base weapon script that we created to make modifications to how a weapon behaves if you enjoyed this video please leave a comment down below give it a like and consider subscribing if you haven't done already if you want to see more of these tutorials in the future please leave a comment as well let me know what features you'd like to see next I'm looking for some feedback about where we take this series of tutorials so I really really loved hear from you and with that being said I'll see you guys next time [Music]
Info
Channel: Code with Tom
Views: 42,680
Rating: undefined out of 5
Keywords: godot, fps in godot, fps godot, fps godot tutorial, fps tutorial godot, fps tutorial, make a first person shooter in godot, make an fps in godot, make a fps in godot, how to make an fps in godot, how to make an fps game in godot, godot fps weapons, raycast weapons, raycast, godot raycast, godot fps raycast, raycast in godot, how to make a raycast weapon, weapon system, fps weapon system, godot fps tutorial, godot fps
Id: Y_2oiLjOx54
Channel Id: undefined
Length: 28min 59sec (1739 seconds)
Published: Fri Aug 16 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.