Unity Architecture for Noobs - Game Structure

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
merry christmas so when i look at my old projects i pretty much just want to gouge my eyes out and that's not because of the spaghetti code although that is a little part of it it's just because there's no structure and structure is something that as you learn as a developer it will adapt and evolve to your style and it's pretty much always opinionated so something that you think is awesome someone else will think is just dog so what i want to do is show you kind of like what i have evolved over my development career and hopefully save you a few years of trial and error and get you kind of like into a good uh structural workflow so that you can start your projects nice and cleanly so as i said it's very opinionated but let's just jump straight in so just tidy this up a little okay so let's start with the hierarchy here so i like to split mine up into separate groups and i find that no matter what i put here they will always fit into these five groups so the first one is managers and what these are uh scene specific like kind of like orchestrated classes they they control the scene so uh this one will be the flow of the game whereas this one will be you know managing the units i'll get more into those shortly in setup is where i put my camera my lights my my event system uh or like a post-processing volume uh everything goes in setup just kind of keeps it out of the way environment will be where i am spawning for example uh like tiles of a grid or uh terrain or trees or anything like that will go in environment uh sometimes i'll even have a subfolder here that will be like units and that's where i'll spawn my units under that and canvases pretty self-explanatory it's just where i put all my canvases uh usually i have like two or three canvases in a scene systems are the only objects in my scene that are using don't destroy on load so i have this one this main object that's calling don't destroy on load and then i've just got all these sub objects here uh that are just normal uh static instances uh which i'll go into in a moment i like to keep all of my don't destroy unload objects my persistent objects all under one kind of like hierarchy to keep it clean all right so that's the hierarchy let's go over to uh the project which is the meats and potatoes and let's go through this one by one so i prefixed my scripts folder with an underscore and that's just because it puts it up to the top and scripts is my by far my most commonly used folder so it's always nice having it up top easy to find now before we get into looking at the uh code just know that you don't need to understand everything as i'm going through it okay uh i'm just going to quickly go through the base concepts of it you should download the project yourself and look through i've commented pretty much everything so find what you like throw away what you don't like but the hopes of this is just it's going to help you along your way a little bit don't worry if you don't understand it as i'm going through it okay not vital so let's start with the managers we've got the two here game manager and unit manager as you can see these two uh correlate to these so let's pop into the game manager and you can see that it is deriving from a singleton class which i have down here in my utilities if we go into it okay so i'm not going to go through exactly what a single tin is but the base rundown of it is it just allows us to have a single static instance of this class that we can easily access anywhere uh well this here is actually more of a just a static instance of the class it's not exactly a singleton this one here singleton persistent actually is a singleton because we're ensuring that there's only one version of this actual object uh and we're also calling don't destroy unload so persistent as in it's going to persist through sends [Music] but yeah as i said just a quick run run through what it actually is sorry back to our game manager as you can see it's actually inheriting from that singleton class so basically what a game manager is is a way to manage the state like the flow of your game if you can see here we've just got this enum with a with a whole bunch of different states here and we have this function change state which takes in that enum onstart we call with the very first state to get the ball rolling and we we set the state comes down here to this enum all right what state is it is it starting yes it is let's call this handle starting here uh we'll do a bunch of stuff here like set up the environment do some cinematics um and then once we're ready we'll change the state again to the next state in the in the list which will be spawning heroes so we'll do the same thing again come down here to spawning heroes uh for example here i'm calling the unit manager to spawn the heroes once that's done i'll then go to the next one right and then after this it will be like the hero's turn the enemies turn and then we might say all right did we win did we lose if so go to these ones otherwise let's head back to hero turn and repeat until there is a win condition or a lose condition so this is just a nice basic enum based game manager uh which will work for 90 of uh small to medium games if you're deciding to do like a complex game like if you're setting out to make gta please don't uh if you are this will have some scaling issues you might want to look into something like a state machine instead but this is good honestly for 90 of games that you're probably going to set out as as a single or small team dev dev team so a good segue here would probably be get to go to the unit manager so here in our spawning the heroes we actually call the singleton instance of this unit manager so that's how you use the uh singleton uh static instance and we spawn heroes so let's go into there so this is the function and in here we're just going to spawn one unit and we're going to say we want the tarot derb unit so then in this uh function doing a bunch of magic here which i'm not gonna get into yet i'll come back to it uh but then as you can see down here like once that's done we then go to the next state so that's that wraps up the game state manager okay next is the scriptables folder and in here is just uh where i keep my scriptable objects if you don't know what a scriptable object is it's just a class which derives from scriptable objects and that just allows us to create basically these little data objects here just containers to uh kind of like pull a bunch of information uh you can put functions and stuff here but for us we're just using it as a data container so on this i've just got the faction so is this a hero or an enemy i've got stats here so stats is a struct with health attack power and travel distance you might have a whole bunch of different stats depending on what game you're making but the fact that it's a struct is very important and i will touch on that a little bit later the the reason i like to put my stats on the scriptable object and not the object prefab itself like the spawned unit prefab is because you might want to be looking through a menu to select units or like a um what are they called like a monsterpedia or something where where you're looking through all the enemies you might want to see their stats there and if you're holding them on the actual uh monster prefab or the unit prefab you have no way to get the stats in like a proper way right you don't want to spawn the prefab get the stats so now that it's here we've got access to it in the menus and also when we spawn it in game we've also actually got a reference to the prefab uh for the unit which we'll get into a bit later so so that's what we use to actually spawn the prefab into the game that's what a scriptable object is so that's our base unit scriptable object and then we've also got like the actual uh derived class from that so as you can see it's deriving from the unit base and in this we just as this is a hero we've got a hero type enum and a nifty little thing with scriptable objects is you can create asset menu attribute and that what that allows us to do is right click create and we can actually just click this and it will allow us to create a scriptable object so we could like another hero here called snorlax and uh you know fill that out give it some studies but we won't do that right now so that's the scriptable objects then we've got our systems here which is this object down here so we've got our main systems object and this is the only class that i'm going to inherit from singleton persistent and if you remember that's just like a singleton class which uh calls don't destroy unload so that we can put this in the first scene and even after 50 same loads it's still going to be there as well as if you've got if you actually put this prefab in all uh five different scenes that you've got the first one will be the only one that ever lives so in the second scene when it comes around uh it's gonna come down here it's gonna say is is there an instance already available if there is then just destroy this new instance and uh just keep using the old instance so yeah that's just the system and it just sits there uh just acts as our one single don't destroy unload uh kind of like um master object and then underneath there we've got our audio system and our resource system so our audio system is just super simple audio implementation you'll definitely need to expand this but basically it's got uh play music from this music source and then we've also got play sounds from the sound source and it takes in a position so you can just uh so you still have your 3d sound but yeah as i said very simple uh you'll definitely need to expand it and then we've got our resource system sorry this is just like one primary repository where you can keep all the references to your scriptable objects so as you saw here i'm storing my scriptable objects in resources and then here heroes and then i've got my scriptable object here so in our resource system i've got a list of this uh scriptable object type and in a wake i'm calling assemble resources and the re the fact that it's in resources folder means that we can actually use resources load all and we're gonna say all right of this type in this folder which as you can see here and just make a list of them and i also just like to make a dictionary of them uh using the hero type as the key so now i can easily just say get example hero taking the type t and just use the key to quickly look up in this dictionary not too relevant for performance but you might have a list that's got like 10 000 items so it might be nice to just quickly quickly grab an item by key so yeah this is just my uh repository for my scriptable objects and then we've just got these two last folders here so let's just quickly go through so this is actually how i organize my class hierarchy for units and this can be also the same for like tiles or uh weapons or anything you're doing right so first i have a unit base class and this is the class that every unit will inherit from at its core so we know that every unit will need stats uh every unit will take damage right and i've also got this function here set stats so if we go actually go back to our example unit manager i showed you this before and said i would come back to it so what we're doing here is we're calling our resource system and we're using that get example hero function that i made so now we've got a tarot dev scriptable object so i'm spawning it uh just using the prefab from that scriptable object if you remember then i'm grabbing the base stats and as you remember this is a struct so we're actually creating a new copy of uh the stats here because we do not want to change the base stats okay that's like set in stone it's always going to be that way and now that we've got a copy of this stats object uh struct we can now apply specific modifications to it so as i've written here it might be like you've taken a potion before a battle or you're working with a few specific heroes so there's like a good team synergy or something so i'm just modifying the stats here and then i'm finally calling the set stats function on that unit uh which then in turn just sets the actual stats of the unit so that's the unit base then of course we've got our hero base in our enemy base so the enemy base might have some um ai logic in there right like because we're obviously not controlling them so they might have you know do their turn uh that'll be ai then we've got our hero base which obviously there's no ai here so we're actually controlling this so we'll we will be listening to like on mouse down have they clicked us have they selected us uh have they actually executed and tackle or remove so yeah obviously hero needs different logic than enemies and then also i didn't actually mention this but in our game manager we've got these two events here so uh when we change the state i'm saying on before state change uh and i'm firing an event and then i'm actually handling the logic here i've found that sometimes you need it before the state changes and sometimes you need it after the state changes so i've just added them both and the reason that's handy is because in our hero unit we want to allow the unit to move again once it's the hero's turn so we're checking if this new state is in fact hiro's turn if it is let's set can move to true again right and then once we actually do the move we'll say can move false and then this will actually tie in to if you can select the unit again so here as you can see i've got on mouse down is the current game manager state hero turn if it's not well it's not time to move so return has this unit already moved if it already has then return and then if those two checks pass then we can actually like you know start doing the turn so that's the unit uh the hero base and then finally we've got the actual hero class so then that derives from hero bass so then you'll have the actual specific hero logic so if you've got a warrior you might have a charge if you've got a mage you might have like a fireball or something you know and just as a quick example of using uh one of the systems on tarot dev i've got a reference to an audio clip and then in my start method i'm just referencing the audio system and playing that sound so you'll see that if you press play i'll actually do that and also i'm printing out every single time the state changes so that's the structure that i always put my units in there's always a base class and then the faction class basically and then like the specific unit class cool so that wraps up units now we've just got utilities so utilities was just the singleton class as you saw here and also i've got a static class which is helpers and this is where i'll put just like a whole bunch of useful static and extension methods so there's one example here which is destroy children which sounds pretty horrible but we'll give it a transform and then we'll just loop through its children and destroy them all so that's helpers and that's all the scripts so let's just close that and we'll just go through the rest of these folders which is basically nothing audio self-explanatory prefabs i'll organize it with a nice folder structure resources that's where we put anything that we want to actually use resources load with uh so definitely the scriptable objects scenes and uh sprites all right and that's actually it so uh that was a lot to digest i know especially as a new dev uh but i hope it helps you streamline your uh projects and kind of like fill some of the gaps that you weren't too sure on as i said it's very opinionated take the parts that you like and throw the parts that you don't but download the project and just go through it at your own pace and kind of like digest it if you feel like supporting me i've actually just made a patreon i'm currently sitting at zero patrons so if you want to support me just head down there um i will be delighted to uh get pinged that i've got my first patreon so yeah that's it uh i hope you enjoyed it hope you had fun with me merry christmas and i will see you in the next video bye [Music] you
Info
Channel: Tarodev
Views: 170,816
Rating: undefined out of 5
Keywords: unity architecture, unity archetecture, unity structure, unity project structure, unity design, how to organize project, organize project, structure project, project structure in unity, Game Architecture Tips, game development, unity 3d, game programming patterns, game architecture, game design, Unity tutorial
Id: tE1qH8OxO2Y
Channel Id: undefined
Length: 16min 23sec (983 seconds)
Published: Wed Dec 29 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.