How To Make a 3D Space Shooter Game in Unity - Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
join me in this video tutorial series as i teach you how to write a stunning 3d space shooter in unity we're going to start out by creating a blank unity 3d project we're going to import some assets from the unity asset store we're going to lay out our background complete with customizable sky boxes and finally we're going to create a game object prefab for the player ship and we're going to add customizable input controls and we're gonna fly it around in our 3d space environment all that coming up in this very first episode of what should promise to be a very informative unity tutorial series [Music] in order to develop a game in unity you need to install the unity game engine go to unity.com download and i'll provide this link in the description and you can create a unity id login and you can download the unity hub for windows after you install the unity hub you're going to want to install a version of the unity game engine you can have several different versions of the engine if you want for the purpose of this tutorial i'll be using 2022.1.2 f1 okay so now that you've got unity hub and unity installed we're going ahead and create our project so in unity hub you click new project and i'm going to select version 2022.1.2f1 of unity um you if you're following along you might want to go ahead and use this version because it's possible i'm not certain but it's possible i'll use some of the new c-sharp features that were added in 2022 so maybe just in case it'd be good to use the same version so i've selected 3d core as the template that we're going to use because this is going to be a 3d project and i'm going to use the standard render pipeline so we'll give our project a name down here i'm going to call it 3d space shooter tutorial and i'm putting it on my external ssd drive under a folder called dev unity projects you can put it wherever you want click create project and let unity do its thing now this is going to take a little while um so i'm going to stop the recording and i will resume it after it's finished doing all this preparatory work to create the project okay so unity has finished creating the project and this is what it looks like when it first opens up in the unity editor so you'll see we've got a sample scene here that just has a main camera and a light source uh what i'm going to do is a little bit of setup that i find helps me to organize my projects and makes them easier to maintain especially as they grow in size so first of all excuse me under the assets folder i am going to create a new folder so i right click in here and up here i say create folder and i'm going to call this underscore project this is a naming convention i believe i got from jason's story from infallible code which because this has an underscore in front of it it shows up at the top of my hierarchy here and i'm going to drag my scenes folder into there so anything that's specific to this game to this project i'm going to put under this folder and this will help me distinguish it from the other packages and that are built in by unity and also ones that i import from the asset store and keep them separate from my project i'm going to create some other folders in here notably i'm going to create a scripts folder and this is where i will put my c-sharp scripts that are specific to this game um i know i'm eventually going to want some prefabs so we'll create a prefab folder i'm probably going to want materials and i might create some sprites but i'll leave this here for now i think this would be good for now uh in my scripts folder i'm going to create an assembly definition and i'm going to call this 3d space shooter and so all my scripts are now going to be associated with this assembly definition and what that means is if we were to look at this in the um project structure in the editor in the code editor you would see that all the scripts that are specific to this game are grouped under a single assembly and that will help compilation times go faster so when i make changes in scripts that are only in this project it won't be recompiling scripts for all these other things so that's just a thing to make recompilation faster so the next thing we're going to want to do is we're going to import some assets that we're going to need for the project that are specific to 3d space games these are all free assets i've got a little text file here i'm going to include all these links in the description of the video so we've got our unity hub which you've already downloaded you might have to actually go to the unity asset store and search for these and then purchase them and then they will show up under your assets so under my assets i've already purchased these even though they're free but if we look at space skies you'll see space skies free listed here and this is the link in the asset store so i will drag that over here i'm going to copy that link and you can see it's got some really nice um skybox images that will look great in our game and it's free so i'm going to edit my text file that has those links and paste that in there and save that and so i've already purchased this and i've already downloaded it if you hadn't already downloaded it this would be a download button so you'd click that and it will download it and now i'm going to import it into our project and this will take a little while and so after you click import it lets you select what you specifically want to import into your game probably for optimization purposes you would not want to import demo i'm actually i think i'm only going to import the 2k versions of all these images because i think they're going to look good in our game and this will help save some space all right so i will import those and if we go down and take a look under assets you'll see we have space skies free now i'm going to create another folder under assets and i'm going to call this packages or asset store packages and i'm going to drag that into there and unity is smart enough to be able to know where to reference that even though i've moved it into another folder so now let's go back to the package manager and let's look at our little text file here i'm going to want one called hi-res spaceships creator free sample so we will say hi-res hi-res spaceships create a free sample i've already downloaded it i will import it this is a really cool pack because it gives us these modular spaceships where you can mix and match different components and they have them with cockpits well they all have cockpits but they have like some of them have internal information for the cockpit so you can put a camera inside the cockpit and get a cockpit view it's very very cool so i'm going to import that this is a very very nice package and it's free so this developer has tons of other really cool spaceship assets that you can purchase from the asset store and this is basically a free sample so i'm going to go ahead and drag that into our asset store packages folder and we're going to go back to the package manager look at our text file again and i want to download a free sci-fi fighter and i thought i was typing in there and i wasn't three sci-fi fighter i've already downloaded it so i will import it and this i think will make a cool enemy to shoot at that imported quickly and i know looking at my text file that i also wanted to import a 3d games effect pack and it is free so here it is i've downloaded it i will import it so these have some different particle effects that i think might be cool at different stages of the game i'm not sure if i'll use them or not but i'm just going to go ahead and import them okay and it actually overwrote my sample scene with a scene from that pack which is fine because i'm not going to use that sample scene anyway i also know i'm going to want to use cinemachine which is a really cool built-in cinematic camera package for unity so we'll go ahead and install that and there's probably some other packages that we're going to want but we can import then then when we get to start using them i just want to get us up and running as quick as possible in this video okay so let me go back and look at this and i need to drag the sci-fi fighter into our asset store packages folder so that's very nice uh creepy crap cat also this is the one that has those 3d game effects that needs to be dragged in here as well now our sample scene has been overwritten and it's got all this junk in there um if we were to hold down our right mouse button and use the wasd files to fly around you'll see they've got this little what they call a showroom here and if we were to play the scene it would it would basically show us within the scene the different effects but i'm going to go ahead and delete everything from this scene except for the directional light and the main camera okay and so now what do we want to do to actually get i'm going to rename this scene by the way i'm going to rename this main scene and so what are we going to want to do to get our project started and off the ground i think the first thing we're going to want to do is add a really cool sky box background that our ship can fly around in so i think i'm going to go ahead and get rid of this scene and i'm going to create a brand new scene i am going to call this main i'm going to open that up okay so we have a new scene it's called main it's got a main camera and a directional light so i want to create a new empty game object and this is going to be a container for all our background objects i'm going to call this dash dash dash background and you can see that it's an empty game object all it has is a transform and i always like to reset my transform to world what they call world origin which is zero zero zero and we're going to create a new camera in here and i'm going to call this background camera and over here you have clear flags of skybox that's cool i like that um the coloring mask right now is everything and so what we're going to want to do is we're going to create a new layer here and we're going to call this background all right and we're going to go back to our main to our background camera and we're going to change the coloring mask to just be background see nothing background so it's only going to render what's on the background all right and we're going to add a script to this camera and we're going to call it skybox setter so we're going to say create c sharp sharp script sky box setter we're going to select our background camera and we're going to drag that script onto it and we don't want our background camera to have an audio listener so i'm going to remove that i think all of these are fine okay and so let's open up our little script here and see what we've got so you can see we've opened up in the code editor and if you're using visual studio or visual studio code your view may look a little bit different from mine i'm using rider oh and by the way i mentioned that i created that assembly definition for our 3d space shooter project and so you can see that this script is living inside of that assembly and if you want to go and look you can see there is another assembly for all of the asset store packages that i created okay so what are we doing in this script here we're going to want to add a serialized field so a serialized field is basically a property on this game object that can be accessible through the inspector in the unity editor and if you're new to unity every game object class that we create in unity is derived from a class called monobehavior and this model behavior has a number of callbacks that the unity engine will call for instance we have start and update and you can see from the comment here that start is called before the first frame update and then update is called once per frame and so depending on your frame rate this may be called 60 times a second or 120 times a second um you know so based on the speed of your processor and and how resource intensive your game is in your frame right update will be called that many times so we don't need a start so we are going to want a serialized field um and by the way i i want to install another package so i can add another attribute called required that's part of the odin inspector package and that will give us some nice validation in the unity editor and also odin lets you do some really cool code formatting custom editors and stuff which will make it a lot easier to configure our game especially if you have a designer involved you can hand it off to the designer and make it easier for them to configure things for your game but our serialized field is going to be a list of materials and these are going to be our skybox materials that we're going to display in our background and we'll call this underscore sky box materials i want this to be camel case with a underscore prefix that's my naming convention for private variables and i want to have a local variable private variable called skybox and we don't need update but what we will want is an awake method and this will set our sky box by using a function called git component so i'm going to have to add a skybox component to this game object and this function will find a component of that type of in this case type skybox and it will assign it to this variable so i can actually add an attribute to our class called require component and do type of skybox in this will when we run the game if it if i haven't already added a sky box to it it will actually create one and add it to this game object but i'm going to go out to the editor because i want to show you how good component works so if we come into our editor now you should see a property show up here called skybox materials it's currently an empty list now what i'm going to want to do is i'm going to add another component here and i'm going to call it skybox so now this game object this background camera game object this component has on it my skybox setter script and so in the script we're going to look for on that background camera a component of type skybox and i'm going to assign it there now when this component is enabled unity is going to call the on enable callback and so what we want to do in here is i'm going to create a new function called change skybox and i'm going to pass in our first sky box so i'm going to actually pass in an integer and this will be an index into our collection of sky boxes so i'm going to let ryder create the function change skybox for me and i'll rename this to be skybox and if our skybox member is not null and our skybox variable is greater than equal to zero and it's less than or equal to skybox materials dot count so we're not going to go out of our index range then we are going to set the material on our skybox to be our skybox materials indexed by that skybox parameter so this is this is going to be an array of sorts it's a list but you can treat it like an array and you can index into it by an integer index so in on enable we're going to pick the first one and we're just going to assign that material to the material on our skybox component okay so let's go back into the unity editor and we're going to want to populate those skybox materials with some materials so you remember we have in our assets space skies free and so here under sky box 1 we've got that one and then sky box 2 we got that nice green one and then we got a purple one so what i'm gonna do here is you can just drag these right into this list so i'm gonna go up to sky box one and i'm gonna take this pink one i'm going to drag that right in there and then i'm going to go down to sky box 2 and i'm going to grab this green one and just drag that right in there and skyback's box 3 i'm going to grab this purple one and i'm actually going to move these up i like the purple one better i want that to be our default i think let's go look at them again yeah let's go with the purple one first now if i click run boom there is our sky box being displayed in our background and you can see it's it's got this sky box component here and its current sky box is purple 2k resolution which was the first one in our list if we stop playing you see there's nothing there right so we could assign a default you know i could drag this guy in here and that would be our default but when we run the game our code in the skybox setter is setting it to our first one boom and now if we were to actually take our background camera and go to its rotation and rotate that camera around you can see it literally is a 360 degree panoramic sky box so there we've got our dynamic background a 3d skybox background with a beautiful space sky sky box for our ship to fly around in so like i said i want to install the odin package so we come over here to package manager and [Music] my assets so you will have to buy this odin does have a free trial and you don't need to do this i'm just doing this for those that want to see how you can use odin and the benefits that it provides but this is totally optional do not feel like you have to do this so odin inspector and serializer actually i'm going to install it as a custom package you could download it from here um this is actually one that i got from a humble bundle deal and it does not include the validator so i actually have a version with the validator that i got from a game dev conference so i'm going to go to assets import package custom package and odin inspector and this looks a lot like what it would look like with your importing from the package manager and the difference is you will see it's got the odin validator so i'll import that so i don't want to make this an odin tutorial but i do want to really quickly show you some of the benefits that odin gives you okay so if we go back to our background camera and we click on our skybox setter here to go look at the script and i look at my serialize field here i can add a required attribute and ryder is smart enough to know that i need to pull this in from the saranx odin inspector using namespace so it will add this using statement here you can type that manually in visual studio you would probably this would be have an error over it if you hovered over you could right click and say add using so it's similar in visual studio as it is a writer writer just has a little bit better integration and now if i was to go back into the unity editor and depopulate all of these guys and go back into the code [Music] okay so i've added over and i also want to add something called preview field so if we hover over this unity gives us a little pop-up that says it draws a square object field which renders a preview for unity engine object types it also adds support for drag and drop so dragging an object to another square swaps the values so anyway it gives you some samples down there at the bottom of how you can use it so we'll go back into the unity editor and watch what it does to this little section here now we got a preview of those materials and you can also click on here to select from all materials either in the project or in the scene so anyway i think that's kind of cool and then the required attributes would yell at me if i did not have that collection on my object which is nice for validation to help you find errors okay cool so we've got our background working our sky box let's add a ship that can fly around so if we go down to our asset store and we expand this high-res spaceships and look under prefabs and examples you can see there's a number of prefabs we can choose from i'm just going to grab this example one and drag it in and you see we get this really cool modular fighter if we were to expand this out you can see it's got a cockpit with interior and the interior has all the different controls and stuff that we can animate i'll get into that later it's got separate engines that you can turn on and off in fact if we go and look in the back you can see those engines have a thruster on them which if we turn them off looks kind of cool that's something we can maybe interactively turn on and off as the ship is flying around if you engage the thrusters it's got separate missile launchers under each wing and it's got a couple of blasters one on either side so i think this would be a good choice for our player ship and so what i'm going to do is i'm going to go into prefab and say unpack completely so this is no longer associated with that prefab and i'm going to rename this to escort fighter and then i'm going to go back into our prefab folder and i'm going to drag that in there so now if i delete this i can always instantiate an escort fighter from our prefab now i want to use the main camera to track the ship when it's flying there's some things we're going to have to do to change it first of all if we look at the main camera the clear flags is set to sky box which is the same as our background camera we don't want that we want to change that to depth only and then the culling mask we don't want it to show the background we also don't want it to show water because we don't have any water we're just going to turn that off so i think that is good let's switch over to our game view and you can see this is what we see in our game view it's looking at our fighter from behind and that could be kind of cool for a chase camera but i actually want to use a cinemachine virtual camera for that for now let's just take the main camera and let's move it forward into the cockpit and let's move it up oh yeah that looks really cool i'm not sure if i like that hud where it is we may position that later let me go up maybe just a tad more i like that better so that's will be our cockpit view um from inside the fighter well one thing i want to do is i want to drag the camera onto the fighter and make it a child of the fighter so it will move with the fighter when the fighter moves and let's see if nothing i want to do i want to move this directional light into here it doesn't really matter but it's part of the background and i want it there now our background camera is showing up over top of our main camera if we turn it off you can see our main camera view uh i think all i need to do is set the depth to negative one and i'm just going to go ahead and add this to the background layer i don't think that matters so if i hit play all right so we can see the skybox background from our cockpit view uh the next thing i think we want to do is actually have the ship fly around so in order to make our ship fly around we're going to be using physics specifically we're going to be applying force to move the ship forward or backward and torque to do pitch roll and yaw on the ship so in order to do that we're going to add a component that unity provides called a rigid body and a rigid body allows the component to interact with the physics engine and by default here it gives it a mass of one and has gravity turned on now we don't want gravity turned on when we're in space because it's going to make the ship fall in fact i'll demonstrate that if i hit play keep an eye on its position on the y-axis and you can see it's falling so let's go ahead and stop that we're going to turn gravity off and i'm pretty sure that i'm going to want um to change the drag and angular drag because if you think about this if we apply force and there's no drag then whatever force we apply it's just going to keep going as fast as we push it and never slow down and stop so i'm going to give it some arbitrary values here that i think from experience will work so a drag of two and an angular drag that's going to be how much we roll pitch or yaw basically this will slow down torque over time i think those are good for our rigid body now we're going to need a script so if we go in our scripts folder i'm going to create a new folder i'm going to call this ship controls and if we open up that folder i'm going to create a new script and i'm going to call that ship controller and let's just go ahead and open that up in our code editor now i do know that i'm going to ultimately in the future have a scriptable object that i'm going to use for the ship data basically it's going to be the parameters that control what the thrust force is the yaw force pitch force force roll force all that stuff but for now just to get this tutorial moving just so we can have our ship fly around and demonstrate how that will work i'm going to go ahead and put them right here in this class i'm going to use the box group attribute call this ship movement values and this will be a serialized field and it will have a range so i want these to be anywhere between one thousand and ten thousand and uh this is not an odin attribute this is just a straight up unity attribute and this will give us a sliding bar that we can use to adjust this value up and down in the editor so this is going to be called thrust force and i'll give it a default value of 7500 i'm going to copy this attribute actually another way i can do this instead of copying that attribute is i can just put a comma here and i can i can add pitch force and roll force and yaw force and keep them all default values let's see 7 500 let's put them on a new line new lines a pitch force i think i want that to be about 6000 and roll force i think i want that to be about a thousand and i'll probably end up adjusting these in the editor and y'all force will do 2000. let's go see what that looks like if we go back to the unity editor and we have our fighter selected here and we drag our ship control script onto it and there you see all these controls are in a box group called ship movement values and they've all got this little slider right that we can use to adjust them up and down so if i didn't have the box group attribute i'll just show you what that would look like if we took that away we'll go back into the editor so now you can see they look pretty much the same they're just not all boxed together so like i said that odin attribute is totally optional uh it's up to you if you want to have it or not it really doesn't matter um let's see i'm gonna have to have some private variables member variables the rigidbody which i will call underscore rigidbody and we want to have some variables for i'm going to call this thrust amount pitch amount roll amount and yaw amount and i'm gonna add an attribute here this is another odin attribute called show an inspector and you'll see why i'm doing that in a minute and i'm going to give them all a range from [Music] 0 to 1 actually from negative 1 to 1 and i'll give them a default value of zero all right let's go back into the editor and you can see those private members are exposed in the inspector with a slider so i can control them right here in the inspector oops let me drag you back on there all right okay let's go back into our script and in the awake method so if we hover over this unity intellisense will tell us that awake is called when an enabled script instance is being loaded and so what we're going to do in here is we're going to load our rigid body so we'll say a rigid body equals get component rigid body and now we can use that to move our ship around now we're going to do our movement in a callback called fixed update if we look at this an intellisense it says that it's a frame rate independent monobehavior dot fixed update message for physics calculation so essentially anytime your manipulating an object through physics you want to do it in fixed update and it's frame rate independent and so we'll be taking advantage of the time dot fixed delta time to make sure that we smooth any movements that we make out over time independent of the frame rate so what we're going to want to do in here is we want to check and we're going to take advantage of a built-in math f function called approximately and we want to say if the pitch amount is not approximately zero so we are pitching or up or down then we're going to want to add some torque to our rigid body and i want you to think about this so if we're going forward and we want to pitch up or down we want to add the torque on the horizontal axis right so the way you do that is we would take transform dot right so that's our horizontal axis and we're going to multiply that times our pitch force times our pitch amount and we're going to adjust it by dot fixed delta time all right so we should be able to go into the editor and hit play now if you look at our rotation here if i adjust our pitch amount you can see we're rotating up and down on the x-axis now it doesn't look like it except for the light that's changing in the cockpit um and the reason that is is our background is not following the movement of our main camera so we have a background camera that's rendering that star field our skybox we're going to have to add a script to it to match the rotation of this camera so this camera lives on the fighter and as the fighter moves or rotates the camera moves or rotates with it and we're going to want to rotate or move that camera the background camera we want to match its rotation to the rotation of this camera so let's go ahead and do that now go back up to our scripts folder going to create a new script i'm going to call this match rotation open that up in our editor and we're going to have to have a serialized field we'll make this required again this is an odin attribute so you don't need to add this this is oops how do i do that i wish i knew the keystroke i used to do that because that's useful all right require autocomplete is not being very nice to me today okay so required got that and this is going to be a transform and i'm going to call this target so we don't need to do anything and start and i actually think i'm going to do all this in late update so this is another callback that unity gives us so we hover over this and let intellisense tell us what it is it says it's called every frame if the behavior is enabled uh but this will take place after the other update and fixed update and everything else happens so what we're going to do is we're going to say that our transform rotation equals the target's transform well the target is a transform dot rotation and that really should be all we need for the script get rid of those unused using statements go back out to our unity editor pick our background camera i'm going to go ahead and collapse all these guys and i'm going to drag that match rotation on there odin gives us this nice big error message here saying that we don't have a target so for now we're just going to take our main camera and drag that on there so let me hit play i'm going to go back to our fighter and let's adjust our pitch and now as we pitch up and down you can see that the motion is reflected in the background because we're rotating our background camera to match our camera cool so now we'll be able to see our movement actually take effect so let's go ahead and implement the other axes of movement so we've got our pitch let's do the same thing for roll so we're going to do absolute approximately zero roll amount and we're going to add torque now what axis do you think we want to use if we're going to roll left and right i'll give you a second to think about it the answer is forward so again visualize this if we have a a line going through our object from back to front if we add torque along that axis we're going to roll to our left or right which is exactly what we want so we're going to multiply that by our roll force times our roll amount and adjust that by timed up fixed delta time so that's roll do the same thing for y'all i like saying that y'all can you tell them from the south okay transform now for y'all we're going to use the forward axis is that right now we're going to use the up axis so imagine we have a line going up and down through our object if we rotate around that we're going to rotate counterclockwise and clockwise so let's use up multiply that times our yaw amount times our yaw force adjust it by time dot fixed delta time so i will go back into the editor and i will hit play so we got pitch we got roll and we got y'all all right i like it and we are going to wire these up to some input controls um so we can use the keyboard and the mouse to control the movement of our fighter but for now let's go ahead and implement thrust so i'm going to do thrust last after we've done pitch roll and yaw do the same old approximately we'll say [Music] well compare it to zero first thrust amount okay i like that so what do you think we're going to add here we're not going to add torque the answer is force we're going to add force and we're going to apply that on the forward axis of our transform so we'll say transform dot forward get my mouse out of the way and we are going to apply our thrust force times our thrust amount adjust it by time that fixed delta time let's go back into the editor and hit play now i'm going to expand our transform so if i apply thrust you're going to see our trans our position change but it doesn't look like we're moving does it now there's a very good reason for that we are matching our backgrounds rotation to our ship's rotation but that's not going to show us movement forward okay that's not going to so i'm gonna show us if we're pitching rolling or yawning it's not gonna show us if we're actually moving so what we need or we need to add some things to the scene to fly around and until we add things like enemy ships and asteroids and junk like that there's really nothing in the scene relative to show that we're moving but what we can do is we can add a particle system to our ship that will spew out i guess space dust for lack of a better word around the ship that we can fly past to give us the visual indication that we're actually flying so let's take a look at what we can do here we can add a component to our ship i could create a whole separate game object for this and call it something like space dust but for now let's just go ahead and add it to our ship it's going to be a particle system and you can see it's already spewing some stuff out around us if you look at it in the scene view you can see it there now the reason they're pink like that is because there's no material associated with what we're spewing out there we're going to want to adjust several parameters for this particle system first of all we want the duration of the particles to last a while we definitely want it to loop um let's have our start lifetime before i think all that looks good start size let's make them a little bit bigger i don't think we want to do anything with start rotation color should be fine we want it to spew in world space not local space let's keep going let's see max particles i think i want to have about 10 000 of them we definitely want it to play on a wake simulation speed one should be fine all that should be cool let's go look at some of the other settings so we'll expand emission let's take a look at that i think we want to have more of them than 10. all that looks fine the shape i don't think we want a cone let's try a sphere and for our radius now we're starting to look like something interesting make our thickness 0.5 arc 360 is good random is good okay i think all of that is cool um what else we want for the color over lifetime i think what i actually want to do is i want to change the alpha to be something like this so i'm going to add a point and on this one i'm going to turn it all the way down i'm going to add a point and on this one i'm going to turn it all the way down so now we have a fade in and fade out kind of thing going on okay that looks cool um i think the only other thing i want to do is under the renderer we want to assign a material to this guy um i i believe that there are materials included in some of the free packs that i imported that we can use let's try that one okay do i need to change anything else here i think all this stuff looks good all right we switch to our game view doesn't look like anything's happening but let's pick our fighter here and hit play and close that down let's thrust oh yeah now we got some star field stuff some space dust flying by is it starting to look like we're flying through space i like it okay it's time to get the input wired up for this and i'm going to abstract this out in such a way that i can swap out the input controller for various ships so you can have a human-controlled ship and it might be a different type of input depending on whether you're on a mobile device or a web page uh you know a desktop app and i also want to have computer controlled you know bot ai controllers for enemy ships and even allied ships so to do this i'm going to first create an interface and i'm going to call this i movement controls open that up in our editor and this is going to be not a mono behavior and it's not going to be a class it's going to be an interface and i'm going to go ahead and get rid of all those using statements and we won't need these callbacks and the interface is going to be really simple it's going to have y'all amount is that what i want yeah i think i want to name it what i called it in the other class so i'm going to call this yaw amount pitch amount amount thrust amount and since this is just movement controls i'm not going to put the fire i want to have inputs for when you fire primary or secondary weapon but i don't want that to be part of the movement i might have another interface that combines this interface and the fire controls interface but for now i'm going to keep this just movement okay let's uh go back into the unity editor and i'm going to want to add another class and this is going to be an abstract base class from which i can derive other input control classes so i'm going to call this movement controls base if i open that up this will implement the i movement controls interface okay now the only thing i want to do differently here is i want this to be abstract and what abstract means is that you cannot instantiate an instance of this you have to have a derived class that derives from this base class and you can instantiate that so all these functions are going to be abstract as well and actually these aren't functions they're properties okay so go back into the editor and let's go ahead and create a class that derives from that and i'm going to call this desktop movement controls and this will derive from movement controls base and we'll go ahead and get rid of all that and i think i might want this to be serializable i don't know if this is necessary but i think since i want this to show up in the inspector and be editable i'm just going to put that on there just to make sure it can be serialized and we'll create a serialized field so we're going to use the mouse to control our yaw and pitch so when you move the mouse horizontally it will yaw left or right and if you move it vertically it will pitch up and down but i want to have a dead zone so like if this is the center of your screen if the mouse is anywhere in here in this dead zone i don't want it to apply any picture y'all only if you move outside of that dead zone so i'm going to create a floating point variable and i'm going to call it dead zone radius and i'm going to give it a default value i really don't know what i want this to be but we'll just default it to that for now and we want a couple of other private properties since we're going to use the mouse and the mouse is going to determine whether we pitch or yaw based on its position relative to the center of the screen i'm actually going to use a vector a vector 2 because this will give me an x y coordinate and i'm just going to call this screen center and this is going to return a new vector 2 that's composed of screen that i think width would come first with time 0.5 screen height times 0.5 if i remove float okay that was a stupid mistake of mine i started out as a float and then switched to a vector two and i didn't dilute delete the float keyword okay so screen center will give us our the center point of our screen in the x and y direction so screen center dot x screen center dot y will be in the center of the screen all right now we want to implement all of our missing members so what do we want to do on all these so for the yaw amount we're going to get our mouse position which is going to be a vector three and our yaw will be our mouse position dot x so y'all is we're going to rotate left or right on the horizontal plane we're going to subtract the screen center dot x and then we're going to divide that whole result by the screencenter.x and then if that is outside of our dead zone radius then we want to use that value so what we're going to do is we're going to return and we're going to use another math f helper function called abs this is going to give us the absolute value because this can be negative or positive all we care about is this the absolute value of y'all greater than our dead zone radius if it is we want to return that otherwise we're going to return zero so this is what's called a ternary statement so this little question mark here says evaluate this condition and if it's true excuse me if it's true take this value and if it's false take that value so this is shorthand for saying if math abs yaw is greater than a dead zone radius then use y'all else you 0. so that's just a way to kind of simplify and if then else into a single line let's do the same thing for pitch so our pitch amount is going to do the same thing except we're going to take the y position so again we're going to take vector 3 mouse position our pitch value will be mouse position dot y minus screen center dot y divide all that by screen center dot y okay and then we're going to return mathf.abs pitch is greater than dead zone radius pitch or zero so roll is not going to use the mouse for roll we're going to use the keyboard and i'm probably going to add something where i can define what keys let the player define what keys he wants to use for pitch and roll and all that but for now all i'm going to do is say if input.getkey keycode dot q so on your keyboard i'll use q for roll left and e for roll right actually i can use a ternary statement here too turn actually i can't because this is going to have another condition you'll see i'll use a turning statement in the second part of this all right so if that return won so otherwise i'm going to return negative one or zero all right so if we press q we're going to rotate one in the around the forward axis otherwise we're going to roll negative 1 along the forward axis finally thrust you know i can actually make this an expression body method because this is going to be really i'm just going to return input.getaxis so by default axis is going to handle the keys i want for forward and back which are ws a and d so w and s will be the vertical axis and that's what i want to use for forward and that will already be a normalized value of negative one to one okay so i still don't understand why it's telling me that but i'm not going to worry about it let me go back into the editor and i know this is going to be seem kind of convoluted and confusing but it's going to make things a lot simpler when i start adding enemy ships and allied chips and different types of input controls and that sort of thing so let's create a new script here i'm going to call this ship movement input and this will be a mono behavior and i'm going to add a serialized field you know what i think i need another class before i can do this i want to have a ship input manager let me go ahead and create that it's a lot of moving pieces i know but it's going to make things so much simpler down the road okay so our ship input manager i'm going to create an enumeration [Music] called input type and i'm gonna have human desktop human mobile and bot okay i don't think i need start or update but i want to add a static method to this guy i'm movement controls get input controls and put type so basically when i pass in one of these input types this guy is going to instantiate a new input controller for us and return it and this is why i'm using the latest version of unity because this is a new c-sharp feature that's introduced in 2022 so it's actually c-sharp 8 which unity didn't start using until 2022 but i'm going to return input type switch so this is just a new way to do a switch statement and if it's a human desktop then i'm going to return a desktop mobile control and for now since i don't have a human mobile i'm just going to return null same thing for bot and then if you want to have a default value you just put an underscore so what i'm doing here is i'm throwing an exception if i pass in a value that's not one of our enumerations all right so that gets us close to being able to implement our input okay so in ship movement input have a serialized field it's going to take a ship input manager dot input type i'll call that input type and let's give it a default value of human desktop and let's see i have a public variable of eye movement controls and i'm going to give this a public getter and a private setter so i can only set it from within this class but i can get it from anywhere and in start we're going to get it we're going to set it say movement controls equals shift input manager get input controls input type so whatever the input type for the object that this script is sitting on it's going to get me the appropriate controls for it and i don't need update let me get rid of this comment too but i do want an on destroy callback and then on destroy i'm just going to set movement controls to be null garbage collector will clean it up okay so the ship input manager i think that all looks good we got our ship movement input we got our desktop movement controls that all looks good all right so let's go to the ship controller so what do we got here we're going to need to add that movement input so let's add a serialized field and we want that to be required now this is an optional odin parameter so don't add this if you don't have odin and i'm going to call this ship movement input movement input and i'm going to add another optional odin attribute called inline editor and i want to use the boxed format and i'm going to add another variable down here actually a property i movement controls control input expression body method returning movement input dot movement controls and we'll use those in our update method to adjust these pitch amount roll amount yaw amount and thrust amount to control our ship so if we go down here to update i'm just going to say thrust amount equals control input dot thrust amount roll equals control input dot roll amount yaw amount equals control input dot yaw amount and pitch amount so we're getting these values in update and then we're using them in fixed update this is a typical pattern to control objects in a game let's go back out to our editor and let's look at what we need to do to get all this to work see let's give me a syntax error and ship input manager on line 20. okay that's why i had an error over there all right i wonder if any of you all caught that watching the video so you see here it's yelling at me because i have not given it i have not given it any input you know i think we need to create a new game object for our movement input i could add the script directly to this but i think i want to create a game object for it so i'm going to say create empty ship movement input and i'm going to drag that script onto there i'm going to come back here and drag that into here and now because i added that inline editor attribute i could actually drop down here and change what type of input it is directly from this script okay i'm going to save that and hit play um something is not behaving quite right i am pitching uncontrollably and i see i have some errors in the console so this is all coming from our input controls it has to be related to this which is really confusing me let's just bypass that ah did you all see it what i was doing in here was an equal instead of a minus did you all catch that while you're watching let's go back into the editor even i make silly mistakes like this sometimes i'm humble enough to admit it all right so i'm pitching up pitching down yawing left oh i gotta increase that y'all rate that's a little slow what is it set to it's only set to 2000 i think we can crank that up and then roll and thrust i think the pitch amount's too high it just seems to be pitching awful fast why did i set that to 6000 it just seems crazy all right so let me come over here by the way it's given me these errors because i went outside of my window here um i'm going to do another thing before i in this little segment i'm going to hide the mouse cursor and i'm going to add a way to quit the game by pressing escape let's put this down to about 2 000 just edit it here 2 000 actually let's make it 3 000. oops and we'll see if roll looks good all right so there's our pitch i might also give the player the option to invert whether this whether moving the mouse up pitches up or pitches down because if i was actually moving the joystick with my mouse um [Music] it would be the opposite i think i do want to verdict because i'm i'm confusing myself by i'm expecting the pitch the other direction when i move the mouse yeah but that's looking pretty good we're flying around let's go under our desktop movement controls and when we're doing pitch let's try that yeah that that makes a lot more intuitive sense to me but i'd still think i don't know is that y'all amount seem a little slow to y'all i think i'll leave it like that for now but i'm liking that i'm flying around okay real quick now how do i hide the cursor i think i'm going to want to add a game manager to handle that yeah let's go up here in our scripts i'm going to create a folder i'm going to call it managers oops caps lock was on managers and i'm going to create a script called game manager let's create a new empty game object call it managers oops reset the world origin you know there's a setting i can change so this would happen automatically i should do that and i'm going to create another empty game object in here and i'm going to call it game manager and i'm going to create a script to go on the managers group and i'm going to add a static variable and this is going to be a private variable called instance and i'm going to implement what's called a singleton pattern i want to make sure there's only ever one of these so in the awake method i'm going to say if instance is not equal to null and instance is not equal to this then i want to destroy this that game object else i'll assign this to instance and i'm going to call don't destroy on load on the game object so that way this thing will always exist in the scene never be destroyed no there will only ever be one of these and everything that lives underneath of managers will also have inherit don't destroy unload and and live forever until we quit the game so i also want to move this up to the top of my hierarchy and we're going to drag our game manager script onto there and open that up so in start i want to lock the cursor and i want it to be confined to the game window so if you look at that cursor confined cursor to game window and the other thing i want to do is hide the cursor so we don't see the cursor floating around the game window and then an update i'm going to say if should quit game quit game and i'm going to create a property here called should quit gain and i'm just going to check to see just check for get key up key code dot escape so if we press and release the escape key should quit game will be true and then here we're going to check to see if we're in the unity editor so i'm adding what's called a pre-processor directive all right so if unity editor else in if and then inside of this code block okay so we're in the unity editor we will call unity editor editor application is playing equals false otherwise so if this was a i actually should check to see if it's a desktop application because webgl this won't work on a webgl app but for now i'm just going to leave this as it is i'm going to call application.quit and i'm going to put it to do handle webgl get rid of those unused using statements go back into our editor we should as soon as i click play see a don't destroy unload group form over here but we did not and i still see my cursor and it's not confined to the window and escape did quit the game though ah i need to drag my manager script onto there not sure why this did not seem to work let me try running that again so we have don't destroy and load and game managers and game manager live under there but my oh okay i see what was wrong i wasn't focused on the game window so once i focus on the game window my cursor is locked and it's confined to the game window all right cool and if i hit escape it stops playing all right so i think the next thing i'm going to do is i'm going to animate these controls in the cockpit so you can see how they move in relation to the input controls but i think i'm going to save that for the next video in the series so that wraps it up for part one in this series if you found it useful and i hope you did please do me a favor and click that like and subscribe button it really does help me out to grow my channel and i want to get this content in front of as many people as possible to help them on their game development journey so join me in part two of this series as we continue developing out this 3d space shooter and once again thanks so much for watching and have a great day [Music] you
Info
Channel: Midnite Oil Software LLC
Views: 34,938
Rating: undefined out of 5
Keywords: unity, tutorial, games, game development, unity game engine, madewithunity, indiegamedev, indiedev, unity3d, tutorials, 3d space shooter
Id: VW3PkEF1Fzk
Channel Id: undefined
Length: 89min 16sec (5356 seconds)
Published: Thu Jun 23 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.