Saving and Loading Scenes! | Game Engine series

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys my name is ashana welcome back to my game engine series day 4 of game engine series week here today and today we're going to be doing some pretty exciting work we're going to be adding serialization and deserialization to hazel meaning that we can actually by the end of today save our scenes out into a file and also load them so it's gonna be pretty exciting because at the moment we're creating our entire scene through code and if we do anything if we actually create anything with hazel or with hazelnut which we're able to do now using all the new ui that we've added such as the items here component ui all of that stuff from the previous episode which i will link up there now that we can do all that stuff it would be really nice to be able to save that to a file so that we can save our work because not saving our work obviously is is really really annoying so that is what we're going to be doing today let's dive right into the code we've got a lot of stuff that we need to do um let's take a look at it okay so as always i've got like a you know i've got the code over here and i want to mention that for this episode even though i feel like some people probably won't like this too much i am actually going to be copying and pasting code that i've already written the reason is that the actual serializer code that i've written is like 250 lines that file so i don't want to type it all out in front of you i will incrementally copy and paste it and then explain it as well so that you make the so that it makes sense to you but a lot of it is just normal kind of boring civilization code that we just need to get through every field of like the camera class for example and actually serialize it so hopefully like the important stuff will still be explained and it will make sense so i guess the first question is how are we going to serialize it uh well there's two different i've talked about this before but there's two different ways to serialize there's the kind of text format that we want to use for production so when we're actually working on the on like a game or a project using hazelnut we want to serialize our scene into a text file the reason we don't want to use binary for that and we want to use text for that is because we want it to be human readable and possibly more importantly human mergeable meaning that if two people work on that same kind of scene file and they're both likely to say add one entity each we want to easily be able to merge that together just using like a get like merge tool or something like that right we don't want to actually have to you know create some weird binary tool that's going to map like manually you know merge all those bytes together that's awful we don't want to do anything like that we just want to have normal text file format and we specifically i've i've i've chosen yaml for our text file format because it's really really easy to read and more importantly really easy to merge so if you actually go to the yaml website it's entirely written in yaml this is all yaml compliant where you see all the text here and as you can see it's really easy to read json on the other hand is not that easy to read and it's a lot harder to merge because any time i've had to merge json in the past there's always like some curly bracket that i missed or something is misaligned and because of that it just becomes really really super annoying um because well you know something's gone wrong and now i have to go back and trace all of my it's a disaster this is really easy there's no weird brackets here anywhere you can see that we have like you know um key and value pairs like in a map we've also got arrays which adopt points which is just so easy to read so i really really do like yaml and that's the format that we're going to use and it's used by unity as well so it's obviously not something that's very obscure now as always i've created a little fork of yaml cpp which is the library we're going to use for this i'm not too concerned about performance here because this is just for like loading and saving scene files and possibly any other kind of production like data right this is not something that we kind of use for um this is not something that we kind of use for something serious like runtime code where like you know we want it to be like as fast as possible and we care about performance now this is saving loading scenes right so not too concerned about performance here um there might be a faster yammer library out there i've been using this one for a while in hazel dev and it's fast enough i feel and it's it's easy to use and it's great and more importantly it doesn't have any dependencies really uh it's all kind of like self-contained in here because what i did notice was i think i used another yaml library and it like you know included parts of boost and other libraries and that's just that's just too much like i don't want any of that there's so much extra stuff on it's so heavy i don't really care for that so instead i'm gonna be using um this one here so i've just added a pre-make file to it just like i've done with imgui this is the pre-mag file it's super simple i mean it's very straightforward to compile this you just need to you know include the cpp files for compilation i've also included the header files so they're part of the project and then finally include as an include directory and that's it it's that simple uh the rest is literally copied from the i am gui premake file so to add this as a sub module as always we just have to go to like uh you know the the directory right um i'll open a command prompt here and i'm just going to type in git sub module add uh that's the um link to the sub module and then we want to add it to uh hazel i think slash vendor now this is another thing that um you might want to think about do we want this to be inside hazel or hazelnut well whilst yaml is predominantly going to be probably used by just hazelnut most of the time i still want to make it possible to serialize into yaml for runtime the reason is that is potentially going to be really easy for debugging and it's also going to because remember hazel is not just a game engine it can just be a anything engine really can be used for a lot of different applications uh you know if we're creating a new application that isn't hazelnut we probably want to support yaml serialization and deserialization but more importantly what if we just want to put together a little graphics demo and we want it to be really easy for a person to modify which model file it loads for for example well if we just have like a little model viewer app or something some kind of weird sandbox right that opens a yaml file someone could just open the yaml file inside notepad or visual studio code and change the path to be something else so that might be something that we want to support like we could ultimately use the yaml file as almost a configuration file that's human editable without having to like open hazelnut and that could be useful obviously for a number of cases so that's why i want to make this part of poor cork hazel core hazel um instead of being part of hazelnut just because i think that it definitely has a wider use case so i think that's the syntax github module add that and then the path which is hazelvendor hopefully i'm right um i think it's actually the other way around maybe okay what have i done hazel vender and then i might have to do that yep because that's the actual clone directory my bad okay there we go so it's done it's now a git module it's now in here fantastic now what do we have to do to actually uh get it to be part of our pre-make file not much i mean honestly all we have to do is make sure that we have an include directory for it which is actually in the other um we'll add that in a minute but that's actually in the uh pre-make file it's in the solution directory yaml underscore will have to go with cpp because it can't be a dash in this case um files to there's nothing changes here links we're going to link obviously yaml cpp this time with a dash and i think that's really all we have to do here oh and we want to add it as an include drop we've done directory my bad okay so back here we'll open the printmake file this part of the root directory the solution one that actually sets up the workspace and we'll have to add um yaml underscore cpp here which is just vendor yaml cpp and it's also got an include directory and then finally over here so that it actually shows up as a project under our dependencies filter here we want to have hazel vendor and yaml cpp i think that is it and this will obviously include the actual pre-make script um i think that's it i'm not sure i'm not referring to my diff for this so hopefully this is correct let's go scripts let's rerun this script and then if we reload this not only should we have uh yaml cpp up here which we can now right click and build we should also have excuse me we should also have um it linked to hazel which is great so let's just give that a bill to make sure everything works i mean it's not we're not using the code yet and we can actually start on this serializer so how do we write a serializer well i am the way that i like to do this is of course as as this entire series is completely just my preference you can write your own engine that's what this series is here for just to show you how one might approach writing an engine um i don't like to add serializers to the actual like class that is being serialized so pretty i mean mostly this this is going to be serializing just the same class everything that we need is going to be inside scene but i don't want to add a little serialized function the reason is i picture serialization as an external thing and i like to separate it out into an external serializer class that's usually how i do things it depends on the size and the scope of serialization you can imagine the scene is quite complex right it's quite complicated to serialize it's not that straightforward and because it's so complicated to serialize we might want to separate it out into a new file so that it's actually just you know clean and when we're actually you know caring about the runtime behavior of our scene which is also going to be quite large in the future i don't want to have to be you know stumbling through so much serialization code so because of that i'm going to under scene make a new item here and it's going to be a scene serializer so i'm going to do scene serializer now this is going to support obviously both serialization and deserialization so we'll add that like that will include the pch as well as the scene serializer file like that namespace hazel as always and then over here we can start on actually implementing our seed serializer so i'll include scene because obviously it needs that that's what it's going to be serializing and then we're going to have a pretty simple straightforward class here that much like our pattern of taking in inside the scene hierarchy um is uh how we take in like a context in the scene hierarchy panel we have like a context which is an actual scene that we can set over here the same way we're going to be constructing a scene serializer that takes in a scene right so this will be scene serializer and then we'll do const uh ref scene because we don't need to copy and increment the ref count here um construct scene scene right that's the thing that we're serializing and of course it's going to store it as a member and that's where we're going to copy it and increment the ref count all right and now we just provide some functions so serialize to a file so const std string file path and then serialize and we'll call it serialized runtime so this is the this is the part of the serializer that's going to serialize into binary instead of yaml whereas this will basically serialize kind of i don't know you could call this serialized text serialized binary um but i'm just going to kind of call it like this maybe for now um deserialize uh to deserialize and decelerate runtime again both are going to take in file paths that's the entire api so the idea is this is a very very light stack kind of constructable class here that we provide a context with it stores that context and then you can call these functions um however you like so you could you could store it you don't have to store it you can just you know instantiate a new instance of this class really easily really quickly and then just call a relevant function on it and that way like you know you don't have to have some kind of weird static floating thing that um you know like a static function somewhere that's floating that has to you know take in a scene and then a file path and all that stuff it's really quite simple to work with and i do really like this api okay great so now let's um [Music] create the method implementations and specifically what i'm going to do here is uh immediately for all this to serialize stuff just add a core asset um just add a core assert here that says um that's well i'll just record that false and just add a little comment that says not implemented and in fact i'm one of these i'm going to change the decentralization to be boolean so i might do that i don't know if i'll do that with serialized just yet but um because obviously what this does is it deserializes into this scene that you provide it with so in other words if you were learning a blank scene you would make a new scene object yourself and then pass it in here this is also nice because it means that the deserialized function doesn't also have the job and the responsibility of allocating memory for a scene that can be done externally then you just give it the ref and it will deserialize into that existing scene um which in in in this case if you were learning a blank one it would just be like a new scene that you've just created fresh empty and then you pass it into the deserialize function or rather into the serializer and then you call the deserialize function on that now um so let's return false here for now because it's not implemented so this realize runtime and then serialize runtime as well we'll just make sure that we assert there just in case they're called so that we know that this is not implemented yet okay cool so with the serializer with a constructor all we need to do is set the scene so we've got the context now and then finally we can think about serializing everything so we'll include our yaml file here so uh yaml cpp yaml just like that now i i forgot i forget our convention i think yeah i think we've we've said that um [Music] i guess if it's outside of our current project we use angular brackets like that so i guess this should appear like this because i wasn't sure if we wanted it to be like that if it's outside of our project or outside of the whole solution because obviously this source code is in fact all available to us um inside this yaml cpp um project okay anyway we've included uh yaml so now we need to serialize so as i mentioned i'm going to be copying and pasting some stuff because it's going to be way too long the way that i've implemented this is basically uh like this let's copy the first little bit here um and i will explain it so two quick things um let's go back to the scene class we need to add the serializer as a friend because obviously we need to allow access to serializer to go into our deepest darkest secrets which are like the registry itself and all of that stuff since it needs to actually serialize us um and then also uh we might need to include some other stuff but we'll see okay so what does this do well it's really simple again this whole process is so simple right we create a yaml emitter this is using the yaml cpp library we begin a map because this whole file is really going to be a map right and then i have a key value here which is a scene name now we're not storing a scene name now as far as i'm aware probably something we want to do so i've just put like name goes here kind of here so so this this is going to be like the scene name um so we might even call it something like un named sim okay or maybe like untitled because it's a bit shorter okay so this is where it would go that's our key in value i like to actually write key values like this so you can just keep kind of outputting stuff into there so this is the key this is the value great with entities instead of having the value be like a normal thing in fact i might also collapse this instead of the value being a normal thing the value is actually a sequence right so a sequence is essentially like an array um i think it actually is an array and we'll look at what this looks like in a minute obviously when we actually serialize it but we begin a sequence and now we go through every entity and if it's valid we serialize it uh then we end the sequence we end that array we end the map which is like the whole kind of file right so entities is the key the value is the array uh and then we just output it into the file using of stream right so uh really really simple um i guess i'll just include f stream i'm not sure if we need to we might excuse me we might be including it um from some other uh places as well so serialized entity this can just be a static function doesn't really need to be um a member so we'll do static void serialize entity um we'll take in a yaml emitter right because obviously this is like our output here um and then uh we'll take in the entity that we're trying to serialize and now obviously this function works so how do we serialize an entity well let's begin really simply and then we'll kind of run this and you'll see how it changes so this is the first thing that i did entities should have goods right or uuids right universally unique identifiers the reason is that um there are a lot of reasons why we want to have like a proper id um and this isn't like uh like i'm not going to get into it now but essentially we need and we need to have a proper id per entity so that we can properly identify it and it should be like a globally unique asterisk id because like it's possible that these ids get created like at you know across different like computers and essentially that we don't want like a global authority handing out incrementing ids we want them to be random um because that way they can get created uh wherever whenever and it's obviously extremely unlikely that it will conflict with an existing entity we don't have that yet so that's why we have this random string of numbers here to do entity id goes here okay and as mentioned i worked all this stuff out during the live stream so that's basically so we begin a map called entity that means that we also have to end the map so i like to add a comment here specify specifying which map specifically um it's affecting so that way when we begin and i don't know why i didn't do that it should be like that i guess because a long line but whatever so we have the entity id now and then what we're gonna do is actually uh i guess have um because we've we've begun a map now so the entity is going to be equal to this which is just like the id i could have called this id but entity just makes it a little bit more readable and then we have to go through everything and serialize everything so as an example let's serialize something really simple first the tag component so let's include components because we need to be aware of all of them so if we have a tag component which obviously we should but i've just got an if statement here might as well for safety then we will uh grab our tag component key right so this is like basically saying hey this is a tag component and then i begin a map which stores everything the attack i'm printing it now in this case the tag component is just a tag so i could have just you know essentially made this code look like that right tag component equals tag right but for um consistency's sake because this i'm trying to keep this consistent with other components obviously that will have more than one like uh data field to serialize i've done it a little bit differently okay um well at least i've done it this way even though for this example might be overkill and that's our tag component right and then so what i'll do is obviously end the map which i should have done here uh and i think that's it so that this is a very very simple example of just serializing a single component from an entity but based on this you should be able to implement the rest yourselves obviously i'll do it in this episode as well because i have to but if you want a little bit of an exercise obviously feel free to just do the stuff there's always stuff flying around why anyway sorry um feel free to take this as an exercise and opportunity to maybe uh do some of your own programming if you want and implement the rest of these because there are certain things that are more complicated to serialize that we will have to do right um but that's going to be fine like i uh you know like for example things like um you know vec fours or vec3s or the glm math types we obviously need to provide custom code to serialize that because yaml doesn't know yeah yeah more cpp the library doesn't know how to serialize that stuff but we'll get through that that's it this is as simple as it is so let's see what we end up with with this kind of yaml code um how do we use this well i said it was really simple right so all we have to do is inside editor layer let's include scene uh what is it hazel scene slash scene serializer right we'll make our scene using simple source code which is what we're currently doing um and then maybe like at the bottom i'll do scene serializer serializer right which takes in our scene which is our active scene i believe and then it just does serialize it dot serialize and then let's go to assets scenes uh example dot hazel okay that's it let's run this code and we'll see what we get and it's already an error um let's go back here and return false dc realize we are actually going to implement today so um not too fast about that okay so nothing appears to be different but obviously now what we should have is inside hazelnut we should have a little file um inside the hazelnut directory i should say called uh sorry easter bean assets um [Music] why isn't it here asset scenes example we might need to actually create the directories ourselves um i've forgotten how to do that uh let's see what's happening here um yeah so it definitely should be it should definitely should be written let's just test this out quickly let's add a folder called scenes and see if that works uh yeah there it is all right so we'll we'll need to add some flags probably to the out of stream so that creates all the directories for us but we will do that a bit later so we have example.hazel and if we double click on it this is what our yaml file looks like so we have scene untitled right we could probably get yaml to add a little comment at the top as well that specifies like what kind of file it is we can do that if we want um but then we have the list of entities here the array so we have uh the fcid and then a list of components so we have tag component and then the tag is camera b and we have camera a and then red square and green square so you can see how simple it is to just serialize some data let's go ahead and add in the rest of the components so as i mentioned i've already done this before um during the live stream which you can find on twitter tv such as the journal or on patreon if you want to watch the uh the rerun we'll say the recorded version um but over here if i paste in the rest of this code let's kind of go through it so it's really simple obviously it's the same thing so for the transform component we obviously uh output the transform component as a key then we begin the map we get the transform component and then we just output everything the transform component is so it's a translation rotation scale we simply just output that as translation value rotation and the value and the scale and the value now you'll notice this isn't working because uh we actually need to to add an overload for this operator to take in a vec3 because this is a vec3 and it's a glm type and yaml cpp the library doesn't actually come with operators for glm understandably because it's a different library it comes with a lot of operators for default types but not for this then we have the camera component this is like the big juicy one there's a lot of stuff here so there's actually kind of two things in this camera component there's an actual class called scene camera which contains a whole bunch of data that we need to serialize and then there's also primary and fixed aspect ratio so what i've done is i've actually instead of just outputting them as key and values i will actually begin a map inside this map which is the camera class so the camera class stuff is under its own kind of section and then there's like projection type and everything here and of course this projection type which is actually an enum right i'm just casting it to an int so that it gets serialized um and that's it that's the camera component sprite render component same kind of thing we're just outputting the color because really all it is is a color once we have textures and stuff and assets we'll probably serialize assets by their their ids and their goods um and we'll cross that bridge obviously when we get there that's it so these obviously don't work so how do we make them work well we need to overload the uh the i guess bit shift left operators um so i do that by just going to the top of the file and pasting these two in one for the vector3 one for the vect4 really simple we basically just add the operator with whatever type we want and then we uh in this case i'm using flow which basically means that instead of outputting it as like a key value thing for x y you know z and everything like that it's going to actually output them like this right for a vector or like this for a vector3 which obviously is just going to take up one line it's going to look a lot nicer that's called flow so i'm doing that and then we have the begin and end sequence that's it really simple and now obviously this works so we're running the exact same code again now and opening this we now have a fully serialized scene how simple was that i mean i know i coped and paid i copied and pasted like all of the code but it is really simple right um so yeah uh really really simple okay and then we have everything that we need here obviously so if we go through this loosely just so we see what's here we have a tag component obviously the transform as a flow that's why you see it like this camera component with everything serialized um and then we have our camera a which is in fact our primary camera so it's set to true i think uh yeah we have all the details here and then um our sprite renderer with our kind of red color which is our red square really really really simple okay and now finally um to deserialize this um we need to basically do the reverse of this it's also really easy to deserialize uh and i i will also copy and paste the code but i'll take you guys through it in the same kind of fashion just increment and by the way let me know what you think of this format where i'm incrementally like copying and pasting code um obviously for people who are regulars on twitch they see me go through this for hours and type it out and work out what it's going to be in the first place so they might be fine with it but for those of you who are exclusively watching this series on youtube let me know what you think and if this is like i mean i imagine this is pretty easy to understand i mean i'm going through all the code and not copying 200 lines all at once but if there's any problems let me know obviously this series this series is for you it's not for me um i i know how to do this uh okay so um these serialize so the first step is going to be and i'll actually i've added some logging code here as well just so that we can keep an eye on what's going on but we basically open up an input file stream and then into a string stream i'm passing in the buffer from the uh file stream this is just the complete buffer of all the all the text um and then i'm passing in this string from there into yaml load which is the animal cbp library the function that actually will contain all the data now and then then we have a series of nodes so if the scene node is not present um then i'm just return false because it has to be in the wrong format because we have to have a scene node that's kind of that's what all this is really right if there needs to be a scene node and if there's no scene node then what is going on it's not the right format and then what we're going to do is actually get the scene name which is what we see here and then we need to get the next node which is going to be our entities node so the way that we retrieve a node which is just going to be a yaml node i'm just using auto here right but we basically go to this this is the root node and then that node is going to have a node called entities and you can tell because here it is it's on the root it's not like a child of any other existing nodes and it's called entities so under the entities node we can now check to see if that node is present and if it is then we have entities that we need to deserialize so that's what we do next so how do we loop through all of this pretty simple we just do four auto entity in entities and now we have each entity node here so from here to here basically we have access to entity tag component and transform component camera component and we can just simply get them by just being like hey entity you know camera component is that present and if it's present then well we can do something with it and that's going to be our strategy really really simple and also really kind of um error proof right like as in if the node is not present we don't deserialize it so it's not like it expects something to be present it's very very flexible so the first thing we'll do is try and get the id um the id obviously and i'll copy both this and i guess the tag component as well but um the id is a to do thing at the moment this would be the universal unique identifier the uuid we don't have one at the moment it's just serialized as this blob but i do wanna where is the blob here's the blob but i do want to already kind of just create a place for it because that's important um and then uh [Music] so then we'll try and retrieve the tag component so we'll get the tag component if it's present we'll get the tag as a string and now we've got a name for our entity which is pretty exciting okay so next we probably need to actually create an entity the whole point of this is now we're deserializing a bunch of entities we need to add them to our scene same way as we looped through all of the existing entities by using um the uh registry like each function here right with the entity id over here we need to actually create entities so how do we do that we're going to make an entity called deserialized entity and set it equal to mseen create entity and then the name obviously now that we have a name that's why we want to do this first we can create an entity with that name now eventually we probably also pass in the uuid and do like create an entity uh you know with uuid or something like that um but we don't have one we don't have the function yet and we don't really have ids so we're not gonna we're gonna worry about that just yet so the uh next step is gonna be the transform component i'll just copy and paste it to show an example of a transform component happening uh really simple we just get the transform component same as the tag component if it's present then uh let's uh let's actually set the values now in this case we're doing get component because entities always have transforms we can assume that it's present because when we create an entity we also add a transform component to it right that's what happens here for all of the other components though instead of get we'll have to do add because they're not going to be present it's a brand new entity we could write a function called get or create component or get or add component so what that would do is obviously just in here it would just check to see hey does it have a component if so return get component otherwise return add component easy um translation rotation scale we deserialize them now i think we're going to need if we try and compile this i think it's not going work um because uh there needs to be if you read this properly there needs to be a decode function for each of these types so i've already done that and this is from hazel dev as well but basically what i've done is i've done this for just vec3 and vect4 it looks like inside this but this needs to be inside the yaml namespace and i've just added these conversion functions so encode and decode so this will actually go through these custom types such as a vec3 and actually either push back everything it needs into the node into the node for encoding or retrieve the primitive types from it right so each so this is like the result that we're populating here and then we're just going to basically get node 0 1 and 2 out of the sequence that we've previously encoded here 0 1 and 2 out of the sequence which is essentially an array that's in like a flow format but that's irrelevant and it's going to actually set the vect 3 to those values so just adding some decentralization and civilization code for all of these custom types very simple and now that should work okay um so the last step uh is basically the rest of the components inside these serialized so we've obviously just added the transform one which is over here uh pretty straightforward i think again we're just getting the component setting the fields really easy and then camera component and then the sprite renderer component i'll do them both in one go this is exactly the same as what we had before right uh with the camera we just add a component instead of get it because it's not going to have a camera by default and this is obviously only if it's present inside the yaml file so if it is present we're just going to get the projection type which will be you know so we're inside camera now and then we're going to get the projection type because we're inside the camera node here we'll get it as an ant but then we'll cast it to our enum class and that will of course set it to whatever it needs to be now we do we will have to fix up some stuff here because this won't work as expected potentially and has some bugs with the camera stuff because of our camera code not because of the serialization um because when we actually set the projection type for a new scene it recalculates the projection which relies on the view the aspect ratio being set from the viewport size but the viewport size is well zero by zero because it's a new scene and it may not have had its viewport size set by im gui kind of panel code just yet so we need to make sure that we catch that case as well um anyway very straightforward just right around the component distributize it as a vector and then set it into the component when we add the component really easy i don't know why that code is there i must have copied and pasted the transform component where i was writing it all right um so next step uh if this all succeeds and we're not like returning false or whatever we'll obviously return true and then um that's i think that's it to be honest so now what we should be able to do is uh let's just get rid of we should be able to deserialize our scene so if we just surround all of this by an if zero right i mean we're not doing the script the script stuff yeah we'll talk about that another day um because it's like native script stuff so it has to be handled a bit differently but all of this red square stuff that we used to create if we just um let's not serialize anything so we don't override it but let's just launch this we should get just a blank empty project there we go right now if we actually do d serialize we should hopefully see everything the camera stuff might not work we'll see how that works out oh it did okay there we go so we've got our scene you can see our digitalization code worked and everything is in the right place um so yeah that's that's that um so what we can do to test this out a little bit better and i will uh next episode we'll actually properly write this stuff so for now i'm going to keep it really loose but next time we'll had we'll have like open file save file dialogues and stuff we'll do that in the next episode um but what i'll do for now is maybe uh maybe maybe just under this uh menu bar we might as well do it here so we have the file menu let's add two more things here i won't call them save and load or save and open for now i'll call them serializations because that's literally as simple as it's going to be um so serialize and then deserialize okay and it's just going to be hard-coded to that one path keep stuff really simple so again really easy to construct this stuff right so inside deserialize i will just call this code and then over here a simple construction we'll just call serialize really really simple that's the whole point okay so blank scene file deserialize got a perfect scene let's maybe move this uh green square out of the way so we can see our red square as well and then i'll serialize this and then i'll deserialize it oh this is one one more thing we have to do but this is more um this isn't really uh the serializer's fault it's the editor layers fault but if we open this now and we deserialize it we should see the two squares in their different positions now at the moment if we do serialize many times it's going to keep adding everything into the same scene right so now if we move the green square you'll see there's another green square and that's because obviously we're not actually making a new scene we're just serializing into an existing scene so you would fix that by actually making a new scene but then when you do that you have to reset the context and as i mentioned there's going to be some problems with the camera because if you look at this code over here well as soon as we deserialize it's going to want to set the camera projection but it can't do that just yet because the camera projection is dependent on the um where is that code it's dependent on this viewport code stuff the active scene on viewport resize code that hasn't run yet so we'll run into some problems there but anyway for the most part you can see we can now launch this and actually deserialize an existing scene which is pretty cool and not really that much work okay so that is the end of this episode i hope you guys enjoyed if you did please don't forget to hit the like button and also help support the series by going to patreon.com the channel you'll get access to all the past recorded live streams as well as dev which is where this code has existed for like the last year or half year or whatever um because obviously we've been saving scenes there for a while and that's where everything's kind of coming across too but thank you guys for watching uh next time as i mentioned we're gonna actually add a proper like save and load um save and open file dialogue and all that stuff so that we can actually save this to a custom path and load a custom file and not have to just always obviously read to and write from write to and read from the example.hazelfather we're doing here thank you guys for watching i'll see you next time goodbye [Music] you
Info
Channel: The Cherno
Views: 21,323
Rating: undefined out of 5
Keywords: thecherno, thechernoproject, cherno, c++, programming, gamedev, game development, learn c++, c++ tutorial, game engine, how to make a game engine, game engine series, scene serialization, serialization, saving, loading, writing files, saving scenes
Id: IEiOP7Y-Mbc
Channel Id: undefined
Length: 39min 20sec (2360 seconds)
Published: Fri Oct 23 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.