The GameMode and GameState in C++ and Blueprints

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I wanted to take some time to talk about the game mode and the game state and just to help you understand a little bit more about why we would use these and how we can use these how we use them in C++ and how we use them in blueprints now these ideas really come from a design pattern that we call the Model View controller and it's one of those software engineering design patterns that we see repeated throughout successful software project projects and usually we think of this a lot of times in terms of graphical user interfaces but it applies to a lot of different aspects of software so what is the model-view-controller well it looks something like this so the model here in your application is the data so it's the data that your application computes on that it stores that it runs on and all of the operations that happen on the model are built into the controller so the controller is the logic of your application and the controller has functions that sort of help define how that model how you operate on the model and then finally we have the view and you often have multiple views and the views are really exactly sort of what they sound like which is a view into the data okay so that the data if your application now you'll notice that there's arrows between these different components and the reason is is because generally the controller communicates directly with the model and vice versa and the views can communicate directly with the controller and so we don't usually for example have the view connect directly to the model because if you do that you have a view that's dependent on how the model is organized and so it ends up being really hard to change your model and this is why those kind of software products that do that tend to not be very successful because they're hard to change now if there's anything you can learn about software it's that software changes constantly and especially when it comes to games that's definitely the case in terms of a game you know what we're gonna see is that the game mode is the same thing in essence as the controller so the idea here is the game mode is act as the the overall logic and glue in your game for how your game plays out the game state is gonna be the same thing as the model so the game state is gonna have all the state that is shared you know in your game between all the players even if you have one player it's fine it's still the same concept an interview are really all of the graphical user interfaces and the cameras that are looking into the game and if you think about it the model in your game actually includes a lot more than just the like the number of coins in the game but it actually includes a lot of information about the things that are in the game all of the actors in that and so forth and so your view if it's a camera is looking into some particular viewpoint in the world okay but when we use the game state our game state doesn't include specifically those objects that we can make references to them but we're really thinking about the things that that modify I mean that define your game that the state that if you were to save the game this is a good way to think about it actually if you were to save the game what information would you need to store in order to be able to recreate it well that's often the stuff that happens in your game State now these things get broken up individually into smaller components for example you'll see that there's a player state object that's attached to the player controller and the players pawn and the reason is is that you know some information is better stored at a lower level and even though your game state might not have that it might have a reference to your player and then your players can have its own individual state so we'll see this sort of Model View controller you know broken down into smaller versions of itself in various levels of your game let's look now at creating a game mode and understand like how we set this up in unity one of the reasons that you want to set it up is that in unity it uses the game mode to determine which pawn and which controller are going to be used for the players now you might have already put a player in your world outliner and that's fine but if you don't put one and you have a player start object like you'll see here it sort of defaults to we have a some location in your world then when your game is executed it's going to use whatever the default pawn is and create one and located at the player start location and the game mode is going to give it a bunch of settings you know a bunch of classes in essence that are going to fine how that behavior works in order to get to the we should we should point out that there's you know game modes that can be set a different level so if I go to the setting and I go to project settings we can set a game mode for the entire project by coming over here to maps and modes and this default mode is going to be the default mode that's going to be set up with every map that we have okay and there's a lot of other interesting things here if you haven't seen it this will show you which you know map is starting when you first load up your your unreal so the game mode base here this is the base class of all game modes and we can change it if we look here we can find different game modes that we could add there and then wants you to find that it then lets you select different versions of the default pawn class the default HUD class the default player control class the default gamestate class the default player state class and a default spectator class some of these you won't use like you probably won't use a spectator class but these other ones you will probably use as your game gets developed so you could set the game mode there if we go back to our level we can also look at the world settings and my world settings are open in a separate tab over here and here we're doing the same thing this these world settings set it for this specific level so every level can have its own game mode and when your level loads it determines which game mode is supposed to be loaded with it so you could again set your game mode here to any one of these right now it's set to none because we're not overriding it then once you've said it you can then set these now we have two ways to set up the game mode and that is through C++ and blueprints let's begin by setting this up through blueprints so I'm gonna just go over here I'm gonna save my scene really quick and we'll just save it here and we'll call it custom game mode so we have a scene now it's always good to have your scene and set up and save so you're not overriding some other scene that you have for another like sub project and then I'm gonna right click and I'm going to create a new game mode and the way I'm going to do that is by just saying blueprint class and then I can scroll down here and I can see game mode base as the possible base I'm gonna have to name it so I will call it custom game mode BP and I can save it and then once I've done that then I can come over here and I can say custom I can just type it here custom game mode VP and now I'm gonna now I've set this custom mode game blueprint to be the game mode that's gonna be used in my game here you'll notice here that now before these were sort of grayed out and now I can select different ones well I don't really have any other options I mean I have other options from other setups for example you remember that there was like a flying pond that we created in one of the videos so flying pond if I did that then the pond that's gonna get created is gonna be one of those flying ones that we created before and then I could set up the HUD except the player class but most importantly I would probably want to have my own unique game state so again I'm gonna come over here to blueprint class and then I'm gonna scroll down here this says common classes because they're the most common ones you'd create but I'm gonna come down here to all classes and say game state base and we will call this custom game state I'm just using BP at the end that's not something that you have to do sometimes you'll see that and unreal but the reason I'm doing that is just because I'm gonna use sort of similar names when I do this in C++ and I don't want to have to type up my check to things I'm so it's easy for me to remember so this will be my custom game state and then when I come over here instead of using game state base I will use custom game state blueprint so these will be set up now now you might wonder why you know I want to set these up and again the reason is of course that we're gonna use this as the controller in the main state and I can access the game state and the game mode from basically any actor so it's an easy way to have a reference without having to create a specific reference to any of my system so for example let's just add a new let's how about a cube into our scene and then once we have the cube we're gonna go ahead and make it a blueprint can't set anything there because I'm in the world settings so we're gonna add blueprint never thought I was missing the little you know drop-down arrow thing so we're gonna create a new blueprint and we'll put this into the video game mode folder and we'll just call this cube group blueprint that's fine so we're gonna create it and then in my event graph what you'll see is that I can now access things from the game state so if I say for example game mode you'll see that I can get a node called get game mode and this is going to return the current game mode base right and so in my event begin play I can now say cast and my thing was custom game mode blueprint so that I can take my game mode here I can drop it into here and so now this is gonna give me access to anything that is of my game mode blueprint so when you're using blueprints you know you need to do the casting here because otherwise you won't be able to see anything that you create on those objects so let's just say this and compile it for a second and then we're gonna go back let's drag this over to our set of blueprints and I close my project settings and let's go back to the custom game mode blueprint and on this we're going to create a function and the function will be something like [Music] get coin count all right and then it's not going to take any inputs but for the outputs we do need to have a value and we want this to be saying just a regular old integer and it's gonna return whatever the coin count is now where I'm going to get the coin count from well you want to separate out your model and your controller and so I can come back over to my game mode and I mean to my game window and I'm gonna go to my game state blueprint now let's open this up we'll come to the event graph this one we're used to looking at and then we're going to add some variables to it so here I will add coins I'm gonna change its type to be an integer and make it public this will be visible to anything that accesses it and once I have this I then want to set up a default value I have to compile it first because they won't let me set it up without doing that hit compile there we go and so let's say there's five hundreds now from my game mode blueprint I can now say has two game State two custom gamestate apparently i misspelled custom just kind of funny and I'm gonna draw drag my arrow here and the object I'm gonna use I'm gonna say get game state I'm gonna drag it in this will give us the cast worked okay and then out of this we're gonna pull us out and then we're gonna say get coins and then this will return in the coins to our blueprint to our other blueprint so what says this over a little bit just make it a little nicer all right so this is gonna get our current game state and it's going to cast it to the custom game state blueprint it from this custom blueprint I'm going to get the coins variable out of it and I'm gonna return this as coins now this is the name of it which I don't like so I'm just gonna call this coins okay and I can compile this and save it and so that now this gives me a function inside of my custom you know blue my custom game mode so now if I go back to my you know cube blueprint if there's some reason I wanted to get the these coins because I'm gonna set something on it like I'm a player or something to that effect then I can do a similar thing and here I'm just going to print string and out of this custom game mode the blueprint I'm going to call the function get coin count and I'm going to put this you know my execute wire into here actually and then drag this out and then this will do a nice little conversion for me and so I can convert my coins into the string and I can print them on the string on the screen so you know the whole point here is really to give you an idea of how we use our controller our controller really is going to provide functions for manipulating the data and then we sort of leave the the data pure by not you know messing with it or putting a bunch of complicated logic inside of it you can still do that so it's not like against the law to do that but it's just a better design often to have that sort of in a separate function or in a separate class in your controller so that you know where all the game logic is happening and you're not having to hunt it down or you change something and it breaks everything else so so now if we just take our project and we compile it and run it you'll see that I get the 500 which is what I set those game those coins to using the custom blueprint game mode and the custom blueprint game's state now what if we wanted to do all of this inside of C++ instead and there are some actual good reasons to do this primarily because the custom game mode in C++ has different things that are called on it that you don't have access to in the blueprints and the blueprints it just assumes that begin play is going to be called but it turns out that there is a function called start play that gets called automatically by the game engine that happens before any blueprint gets its begin play called so there is some usage to doing that where you might need to have access or initialize things in a certain order and so you can be guaranteed that your game mode is going to call this function called start to play before it ever happens inside of the blueprints so let's look at how we can set that up first we'll go ahead and just say create new C++ class and then we can just scroll down and look for game that's game state base which we went about we like game mode base and then we need to give it a name so we will call this custom game mode no need to call it base and then I'm gonna just put this in a folder so videos game modes and then I'll say create class this is gonna go ahead and add this to my project and then I'm gonna rebuild my project just to make sure that everything works initially from the get-go so we've had that we haven't rebuilt now and if we look over here in C++ classes in my video section here you'll see game modes and you'll see a new game mode here that's based off of C++ if I go over to my project though I can set up things with my game mode now if you notice my game mode is pretty empty it doesn't really give me a whole lot of you know things set up with it so we're gonna have to set up our own you know constructor and things like that I think that often people just aren't setting up their own game modes and C++ I don't know why I mean it's fine place to do it and so we're gonna have to set up our own constructor so custom game mode which will look like that whenever you have anything with virtual functions you always need to make a virtual destructor so a custom oops game mode I always seem to be putting in e after the word custom it's gonna look like that and we'll use a little bit of C++ 11 here which is you know we can set up the default destructor and so so that's our constructor and destructor and then we want to make sure that we define it over here so a oops custom game mode a custom so that's our constructor and really the only thing that you're gonna do in your constructor is set up your default classes so while we're at it we're gonna go ahead and create our default game state because we want to make sure that that gets set up properly too so I'll say new C++ class and here I will look for game state base and we'll call this custom game state create the class and this will take a second to get set up okay so my compile is complete I'm and just to find out something really quick if I come over here to world settings and I change it to custom game mode instead of custom eight game mode VP so custom game mode we're gonna see that these are grayed out again and so what we want to do is be able to set our game state Klatt you know class but I can't set it here I have to do that instead in C++ so let's look at the custom game mode CPP we're going to come back over here and in the constructor what we will say is game state class equals a custom game state static class the static class thing is an unreal an unrealism I guess we might call it and this has to do with their whole object system in the way that they were doing garbage collection and things like that that were created me a long time ago when they were using doing Unreal 3 and probably prior to that so but it's not a C++ specific thing but this is how you can get the static class to be set up here so this is set up now and if I recompile this what we'll see is that custom my gamestate class is gonna be set up properly so I'm gonna go ahead and compile that and then we'll take a look really quick well my build failed and the reason is is because you have to include of course the actual header file so custom game state dot H and then that should build properly ok so now if I come back over to unreal what I'll see is that my you know my custom game mode now has custom game state as the gamestate class it's important because it's gonna get created when the game mode is created and you want to make sure you have the right write state object built so let's go back and add a few things so in our game state we're gonna do a similar thing to what we did before with just something randomly called coins and again you know this this class is very generic there's nothing in here make sure you put make these things public because you'll need these so a custom game state and of course the virtual destructor a custom game state equals default and then on top of that what we want to do is have some coins right and the way we do this is by making a u property so u property will make this edit anywhere blueprint readwrite and this will be an in 32 coin count we'll call it coin count and then in our constructor since we've defined it you actually have to define it here so otherwise you're gonna get an error about probably a bad V table or something to that effect so a custom game state and here we will say well we'll use the C++ style initialization and we'll say coin count 500 a so this will set it to be 500 coins initially so let's go back to the game mode and we want to define a few more functions for our game mode so that we can fire some events to the to our blueprints from here so let's set up a few functions first so the first is if you remember we set up a couple of functions that allowed us to you know modify the state and so we can do that through here we'll do define a u function and these will be the first one will be blueprint pure and we're gonna give it a category we'll just call this coins and this function is going to look like this it's gonna be virtual I'm sorry int 32 get coins and this is gonna be Const and then on this side in the C++ file we're gonna say int 32 a custom game mode get coins Const and this is how we define it now when we define these functions here we can put a comment that will be the tooltip for the the function in blueprints itself so return the number of coins in the game something silly like that now here what we want to do is actually get the game state and we want to just return the coin so that's fairly easy we're just gonna say return get game state now this is a function that lives on the game-mode base and so the type that we want to pass into it is custom game state and then this is going to it's a template function that's going to give us the right type and then we're gonna call it coin count all right then we will save this we'll compile it to make sure that it works and then we can add some more stuff to it so that failed mainly because I didn't put my right name because all of these classes begin with an A so don't forget that little thing so this will allow us to get coins and with this we're gonna define another function under the U function and we will call this blueprint callable and again we'll put it in the category equals coins and this will be a void so it's not gonna return anything and we're gonna call set coins and it's gonna pass in an integer just like that and then on the other side we'll simply do a similar thing so we'll say a custom game mode and we'll say set of coins and thirty two new coins and then we can now do a similar thing that we did before which is get game state a custom game state coin count equals new coins so what's the difference between these two well one is blueprint pure and if you were to look in blueprints what you would see is that there won't be an execute wire for those and that's because we're guaranteeing that we're not going to modify the underlying object and this is just part of one of the designs of certain kinds of visual languages where you'd like to know which things can be sort of executed out of order so for the pure functions these are easy to call it doesn't have to worry about any kind of side effects and it just knows it's going to get something out of that node if we look at and then I think they're colored green if I recall correctly if we look at blueprint callable these are basically making calls into C++ that might have a side effect and so set coins is going to do that because we're going to change the state of something and as you can see here that's what we're doing here we're actually changing the state of the underlying gamestate object so that's mainly the difference between blueprint pure and blueprint callable not much of a performance difference these might be slightly faster and like I said they can be reordered these will have to have an execute wire into them and then you can carry that execute wire out of it now as I said before custom game mode your own custom game mode in C++ will have some functions that are called that you don't have access to in blueprints so I'm going to show you how we can get sort of access to those the first of these is start play start play is called before any function called any-any begin play is called on the objects in the world so it just simply is defined like this it's a virtual function in C++ and so if we override this we're gonna override how start play is called let's go ahead and do that and again we're gonna just use the same name here oops and I'll call it start play and then at some point in start play you and usually what you'll see is that you'll call your parents function in unreal this is not necessarily the design pattern you see everywhere but you do see in some places especially with game engines because there might be some functionality some sort of base functionality that's built into the into the game so here this is the case when start play is called on the game mode base it then will eventually call begin play on everything and so depending on when you call this begin play is going to be fired off on all your objects so if we want to do anything and start play before all of the begin plays are called we had better wait to call our parents version of play so we're gonna put that at the end of our function now we'd like to make an event just like begin play in our game mode called start play this way if we turn this game mode into a blueprint we can then access that that event and the way we do that is by saying you function and we are going to call this a blueprint native event again we're gonna put the category coins and we're gonna set its display name to be equal to start to play and then we're just gonna give it a function type start play event so you'll notice that this one isn't virtual and that's because it's not really allowed to be virtual what's going to happen is that because we've made it a native event we can provide a default implementation for this event if you don't define one in blueprints you know you can you don't have to do this and it's a little bit more expensive to do this but you know start plays and called frequently so it seems fine to me to have the extra cost but you know because blueprints is gonna be calling back into your C++ class for this native event if it doesn't have one it can't be virtual because apparently blueprints doesn't know how to handle virtual functions properly which is fine so just don't make it virtual I know that you can't really then inherit from this and expect this to work it's not gonna work like you expect so let's go back to here and we were gonna call this start play the event and here is the interesting part about defining the start play event and it is that we have to now define this as with a slightly different name and it's gonna be underscore and Boop's argued to the underscore implementation all right so what are we going to do for our default implementation well let's just log something onto the screen so we'll say G engine and on screen debug message and we'll just make this read and then we have to pass in text to it and this text is going to contain something like start play event default implementation all right so that will now you know this implementation version will be called if you don't define your own and so you could also you know just define this as a different kind of blueprint event where it's not gonna do this but we're doing it here just for funsies alright so now that that is created we can then from here call start play event and when you call this it's going to call the implementation of that event and it will you know then do the on-screen debug version and just to be clear we're gonna add one more you know nice little login here and I'm gonna do a similar thing to what I did before and here we're just gonna say start to play called just so that we see what's going on now the point of all this oops I noticed that I didn't actually call this start play which is what it's supposed to be called the point of all this is to allow you to do you know some kind of initialization here this initialize stuff here inside the start play function and then to do any other kind of setups or function calls from your game now one thing to point out is that you know everything that's in your world is made from an actor and because of that if you need to get your game state anywhere it's actually pretty easy you really just have to say get world so every actor has access to the world that it belongs in and then you could say get off game mode and then once you do this this is going to give you the game mode base you know class and then you can cast it to your game mode if you want to access it well I mean we're inside our game mode so there's no point in doing that but let's say I wanted to get the game state at this point then I could say get game state a custom game state and then I can do things with that game state so you know just to point out the reason that we use game mode is that it now gives us an easy way to get the game mode from whatever actor we're in and that's currently active in our world if for some reason your actors not in the world then get world is going to actually return null and then you're gonna throw an exception because you're gonna try to dereference the null pointer which of course crashes your game so you should be a little bit careful to make sure that your object has been created but game mode can't actually exist without being inside a game world I mean I guess you could probably remove it because it is C++ and and unreal so but for the most part this should be fine and anything else is really definitely a bug in something that you've done so this should give you an idea of how to get you know how to set things up and how to start setting things here so let's go ahead and let's go ahead and set something here so coin count equals 115 so in essence I've initialized it by changing whatever its default game state was to now and just be 150 so then when I compile this I should be able to see that all of these changes exist inside of unreal and now I can turn these into blueprints themselves and then that will be really nice because I can extend these and get the events that I can't get off of the regular blueprint version so let's go ahead and compile it and do that so when it finished compiling it gave me an error because I used the dot operator instead of the arrow operator because this is actually returning a pointer to me not a reference and so you want to make sure that you have saved this and that you're going to use the arrow instead in order for this to work very good so it's compiled and if we hit play we should see some messages that pop up so start play called start play and default implementation called so you can see that you know there wasn't something in blueprints so it called the default implementation of that event but what's even better is that we can now take this custom game mode we can right click on it we can say create blueprint class from it and so let's go ahead and put this into game modes and we'll call this my custom game of blueprint I have a lot of classes that are named this very similarly and I'm gonna go ahead and close my other blueprints here since I don't need those and now we'll see that from this event graph there isn't gonna be a new event I can create loops I need to stop my game first if I right click here and I type event start play you'll see that I have a new event to first start play and this start play is going to be called whenever they start play in the game mode is called which is going to happen before any possible begin event happens so let's say print string start play called and then from begin play print string begin play called all right people compiled these and then I need to change my game mode to be my custom game mode blueprint and then we can run this and you'll see that you know my other face didn't last very long with my start plating my begin play we're called if you we're gonna rewind and pause the video you can see them pop up really quick but also from here you know I have access to those functions that I created so you know if I wanted to set the coins saying begin play let me stop this from simulating I can say set coins and you'll see that it is my game mode and I can set it to whatever I want well I don't need it set it in there but I can set it to here so 250 for example and then this will just set the coins value in the game state so hopefully this gives you an idea you know this this work between the C++ game classes game-mode classes the game state and the blueprint versions then it is the case that you know you might create some of these in C++ because you need access to being able to do these things early and then you might extend them because you know with customizing some of these events is a lot easier to do in blueprints especially when there's not a lot of calculations that have to happen or a lot of time-consuming things that might slow down the starting of your game so you know it's a balance between these two things and I encourage you to think about you know what you might need but really the important lesson here is the purpose of the game mode which is to act as the controller or the logic in your game where you create functions that can modify the model which is your game state but also which have functions that define you know how your game plays and how things run and again you know you're going to define because this is an object-oriented language you're gonna define custom functions inside the players directly inside the controllers directly so this doesn't have to all exist inside one game mode but the game mode will have rules or should have rules of how the game actually plays out to determine sort of the end of a level or the end of a game for a win state or or however you want to think about it alright hopefully that helps and please send me any questions that be happening
Info
Channel: ChrisGD
Views: 20,885
Rating: undefined out of 5
Keywords:
Id: dxgGpPTcF4k
Channel Id: undefined
Length: 42min 12sec (2532 seconds)
Published: Sun May 17 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.