Welcome back.
Now in this video, we're concerned with pressing play and seeing the correct widget here.
Because if I've saved something to disk then we should be loading that up right away.
We should only see new game if this slot is truly empty.
But if I've saved something to disk here, I want to see.
This screen, right?
I want to see the taken slot.
By the way, if you've saved something to disk and you want to delete it, you can always open up your
saved folder and go to save games.
And this is where those slots are saved.
They even have the same name that you gave them, load slot zero and one.
If you delete those, they won't be there anymore.
So just so you know, they go to your saved folder.
Okay, so in order to display the correct widget, widgets need a status.
They need to know whether they're vacant, whether they should show enter name or whether they should
show the take in widget.
So for that reason we're going to create an enum to identify that status.
And I'm going to stick that in my load screen save game object right here I'm going to define an enum
here just a basic enum called E save slot status.
And this can be a u enum.
We can make it blueprint type and save slot status is going to have three enum constants vacant.
Enter name and taken in that order, which means this will have the numerical value of zero.
This one will be one, and this one will be two.
And now that we have a save slot status, our load slot view model should have the status.
So we're going to go to load slot dot h.
Look at my tabs.
They're all over the place aren't they.
I'm going to bring my game mode base all the way to the left.
My load screen save game is here.
My mVVM load screen and load slots are here.
Okay, good.
So now that I have this enum, I'm going to add this to my load slot.
It's going to have a slot status.
Now it's a regular enum, but I'm going to store it as a T enum as byte.
Choosing E save slot status.
Now for that reason I'm going to need that header file here.
So I'm just going to include it right here.
And it's in the game folder.
So game slash load screen save game dot h.
And I'm going to call this variable load slot status.
Or we could just call it slot status.
That's fine too.
And I'm going to make it a U property.
So when do we set the slot status?
Well, we set it as soon as we know what it is.
Right.
Which means we need to load data.
We need to load up from our load screen save game.
So I'm going to make a function on mVVM load screen that can load the data and populate all that we
need to populate in our widgets, and set the properties and the status on our load slot view models.
So I'm going to make a void function called load data.
We'll go ahead and create a definition.
And load data is going to want to load data for each of the pairs in its map.
Because.
Remember.
It has a map called Load slots mapping integers to mVVM load slots.
I'm going to want to loop over this map.
So I'm going to say for I'll do a const t tuple I'll just say what it is.
It's a t tuple mapping int32 s to um VM load slot pointers.
I'm going to call this pair like I usually do.
Or you could just call it slot or load.
Slot doesn't matter.
And we're looping over load slots.
The map.
So what are we going to do.
Well we want to load slot data and we're keeping track of loading and saving on the game mode.
So we're going to go to the game mode or a game mode base.
And we're going to make a function we can call to load data.
We can call it get save slot data for example.
So let's make that function.
So here on the game mode I'm going to create a function to get save slot data.
And I'd like it to return a U load screen save game object.
We'll go ahead and forward declare it here and we'll call this get save slot data.
And this is going to require two pieces of information the slot name and the slot index.
So we'll pass in a const f string by reference const reference called slot name and an int 32 called
slot index.
And this can be a const function.
Let's go ahead and generate this definition.
And it's going to load data.
So how do we load data?
Well, first we check to see if a slot exists.
We can use you.
Gameplay statics does save game exists.
We could check that first with our slot name and our slot index.
Now we can check this.
This returns a boolean.
So we could check it in an if statement.
And if it does exist we can load it.
We can take you gameplay statics and call load game from slot.
That's how we can load it.
And we specify the slot name and the slot index.
Now this returns a you save game a save game object.
So what I'm going to do is create a you save game pointer called save game object and initialize it
to a null pointer here, and then set it here in the if statement to save game object.
But I'm going to have an else case just in case.
This save game doesn't yet exist.
If it doesn't, we need to create one.
In that case, I'm going to take save game object and call you gameplay statics create save game object
passing in our class load screen save game class.
So either way save game object will have a value.
And then we can cast to you load screen save game.
So we'll go ahead and cast to that.
Casting save game object.
And I'll give it a actual variable name load screen save game.
And after the cast, we'll return it.
And if you want you can eliminate that intermediate local variable there.
Now this function is going to return a save game object based on a slot name and a slot index.
So we can go back to our view model load screen to load data here.
And we can load our data but we need our game mode.
So we're going to say A or a game mode base or a game mode.
And we'll cast to it.
A or a game mode base and we'll call you gameplay statics.
Get game mode, not game instance.
Whoops.
Get game mode.
And we have to pass in this as it needs a world context object.
And after we have the game mode, we can loop over each of our load slots and we can load in data we
can take or a game mode and call get save slot data.
And we can pass in the load slot name, which we can get from our load slot.
It's going to be load slot, dot value, load slot name.
And then the slot itself is pair dot key.
Not chaos pair.
That was typo.
Let's see if.
Yeah we got chaos pair on accident there.
It's going to be actually load slot.
I didn't call it pair I called it load slot and key will give me that slot.
So this gives me a load screen save game object.
So I'm going to store that in a you load screen save game called save object.
And now that we've loaded the data, we can now set properties on our load slot and our map.
So I can take load slot dot value.
And I can call the setter like set playername.
I can set that and I can get it from my save game object.
So what I'm going to do is make a const f string called player name and get it from my save object,
save object player name.
And then I'm going to pass that in here just to show that I'm getting it from the save object.
And we're calling set player name here.
Now that's not the only thing I want to do when I load data.
I also want to set the status of this slot.
So I'm going to get this load slot dot value.
And I'm going to set its slot status, and I'm going to get that status from the save object, because
we should save that status.
Now, does the save object have a status?
Well, if we go to load screen save game dot h.
We don't.
We have the enum defined here, but the save game object doesn't have a status.
It should.
We should use enum as byte because that's how we can save enums.
So t enum as byte.
Of type E save slot status and we'll call this save slot status, and we'll give it a default value.
We'll give it vacant and it gets a new property.
And when we save, we should save this slot status as well.
So in or a game mode base, when we save slot data, we know that we're saving data.
So the slot status has to be taken so we can before we save game to slot, we can take load screen save
game and set its save slot status to taken.
We know it's taken.
We're just now saving to it.
Right.
And now back in our load screen mVVM, we can get that status.
We can get it right here.
We can make a T enum as byte.
E save slot status.
We'll call it save slot status.
We'll get our save object.
Save slot status.
And then we'll take our load slot.
Since we're loading data, we'll set its slot status to save slot status.
So now we're setting that slot status as well.
Now as soon as we set the slot status, we can tell that load slot to initialize slot.
Why?
Because that is where it broadcasts its data.
And now it doesn't have to broadcast a hardcoded value anymore.
It now has its own slot status.
So let's tell it to broadcast that.
We're going to take the load slot dot value and tell it to initialize slot.
Once it does, that load slot is going to initialize it and it can broadcast its status.
Now yes, its status is an enum, but that's okay.
We can get an integer from an enum.
We can say const int 32.
This will be widget switcher.
Index.
And we want the widget switcher index, which is an integer associated with the slot status.
We could take slot status and we can call get value on it.
That'll give us the integer value.
And what value will it be.
Well let's look at load screen Savegame vacant will be zero.
Enter name will be one, taken will be two.
So now that we have widget Switcher index, we can broadcast that index based on the status.
And our widget switcher will switch widgets based on that status.
Brilliant.
Right.
So the question is when do we load the data.
Well we can do it right away.
We can do it from our HUD.
Let's go into our HUD.
We'll go into let's go to the private UI, HUD, load screen HUD.
And after we've created our widget added it to the viewport called blueprint initialize widget.
After all that we should take our load screen view model and we can call load.
Data.
And now we should start off showing the correct widget based on its status that we've saved.
So just to recap on everything, we start off here after we've created our widgets we call load data.
Load data in our view model is right here.
Where we loop over our map.
There should only be three pairs in here and we call get save slot data.
Get save slot data.
It checks to see if the slot exists.
If it does, it loads it.
If not, it creates a save game object and simply casts that to a load screen save game.
So either way it returns a load screen save game.
So back to load data.
Once we have that save object, we set the player name here equal to the player name on the save object.
We set the status and by default that's vacant.
And then we set those properties on our load slot ViewModel.
Setting the player name is setting a bound variable a field notify.
And then we call initialize slot.
And that's going to make our load slot.
View models broadcast this delegate with their widget switcher index which is based on their slot status.
Let's compile and let's just see what happens when we load into our load menu.
And after saving data and then loading back in, let's try it out.
Okay, so back into load menu.
We'll press play.
We'll click new game.
And this time we should be saving to disk.
So I should type in my name click new slot.
And it looks like I went back to the vacant.
Status.
So let's debug this.
We'll go to load screen and VM load screen.
We clicked on new slot.
We called set player name on that slot.
That worked.
We called save slot data for this slot in this index and then called initialize slot.
Now what we should have done is also updated the status for this.
We should have set it to taken at this point.
So what we're going to do at this point before saving the slot data is right after setting the player
name, we're going to set its status to.
So load slots of slot.
We're going to set slot status to take in.
Okay, let's try that again.
I'm going to hit rerun.
And we'll go into load menu.
We'll press play.
And now it's loading in with the correct status.
It should be taken.
Now it's taken.
Now if we click on select slot, that still isn't functional.
But now we can click on new game.
We can enter another name.
I'm going to enter Druid click new slot.
And now it shows Druid.
And if we close and open again now that one loads up.
So testing these things you're very quickly going to find that you want to clear that data.
And that's why I pointed out that you can go into the saved folder and find save games.
And there are those slots.
And if I go in and save to this slot I'll just put an X.
There it is.
Now in my saved games I have all three.
And of course you can just delete them there and come back and they're gone.
So now our status is updating correctly.
Perfect.
Excellent job.
This is coming along and not too many steps left until our save and load system is finished.
I'll see you soon.