WEBVTT

00:07.390 --> 00:08.560
Welcome back.

00:08.590 --> 00:13.900
Now in this video, we're concerned with pressing play and seeing the correct widget here.

00:13.900 --> 00:19.480
Because if I've saved something to disk then we should be loading that up right away.

00:19.480 --> 00:22.720
We should only see new game if this slot is truly empty.

00:22.720 --> 00:26.500
But if I've saved something to disk here, I want to see.

00:28.570 --> 00:30.280
This screen, right?

00:30.280 --> 00:33.220
I want to see the taken slot.

00:33.220 --> 00:38.350
By the way, if you've saved something to disk and you want to delete it, you can always open up your

00:38.350 --> 00:41.590
saved folder and go to save games.

00:41.590 --> 00:45.040
And this is where those slots are saved.

00:45.040 --> 00:49.120
They even have the same name that you gave them, load slot zero and one.

00:49.120 --> 00:51.730
If you delete those, they won't be there anymore.

00:51.730 --> 00:55.180
So just so you know, they go to your saved folder.

00:55.180 --> 01:00.820
Okay, so in order to display the correct widget, widgets need a status.

01:00.820 --> 01:06.310
They need to know whether they're vacant, whether they should show enter name or whether they should

01:06.310 --> 01:07.840
show the take in widget.

01:08.440 --> 01:13.930
So for that reason we're going to create an enum to identify that status.

01:14.140 --> 01:21.070
And I'm going to stick that in my load screen save game object right here I'm going to define an enum

01:21.070 --> 01:26.470
here just a basic enum called E save slot status.

01:26.680 --> 01:29.230
And this can be a u enum.

01:29.860 --> 01:37.240
We can make it blueprint type and save slot status is going to have three enum constants vacant.

01:38.680 --> 01:45.370
Enter name and taken in that order, which means this will have the numerical value of zero.

01:45.400 --> 01:48.730
This one will be one, and this one will be two.

01:48.730 --> 01:55.960
And now that we have a save slot status, our load slot view model should have the status.

01:56.260 --> 01:58.810
So we're going to go to load slot dot h.

01:58.810 --> 01:59.590
Look at my tabs.

01:59.590 --> 02:01.270
They're all over the place aren't they.

02:01.690 --> 02:05.020
I'm going to bring my game mode base all the way to the left.

02:05.170 --> 02:08.680
My load screen save game is here.

02:08.680 --> 02:12.400
My mVVM load screen and load slots are here.

02:12.400 --> 02:13.210
Okay, good.

02:13.210 --> 02:18.520
So now that I have this enum, I'm going to add this to my load slot.

02:18.520 --> 02:20.560
It's going to have a slot status.

02:20.560 --> 02:27.310
Now it's a regular enum, but I'm going to store it as a T enum as byte.

02:27.310 --> 02:31.420
Choosing E save slot status.

02:33.030 --> 02:35.790
Now for that reason I'm going to need that header file here.

02:35.790 --> 02:38.820
So I'm just going to include it right here.

02:41.630 --> 02:44.900
And it's in the game folder.

02:45.320 --> 02:49.850
So game slash load screen save game dot h.

02:50.790 --> 02:55.680
And I'm going to call this variable load slot status.

02:56.250 --> 02:58.080
Or we could just call it slot status.

02:58.080 --> 02:59.070
That's fine too.

02:59.070 --> 03:01.320
And I'm going to make it a U property.

03:02.470 --> 03:04.870
So when do we set the slot status?

03:05.230 --> 03:08.260
Well, we set it as soon as we know what it is.

03:08.260 --> 03:09.010
Right.

03:09.010 --> 03:11.410
Which means we need to load data.

03:11.410 --> 03:15.460
We need to load up from our load screen save game.

03:16.010 --> 03:23.450
So I'm going to make a function on mVVM load screen that can load the data and populate all that we

03:23.450 --> 03:30.560
need to populate in our widgets, and set the properties and the status on our load slot view models.

03:30.680 --> 03:33.920
So I'm going to make a void function called load data.

03:35.030 --> 03:37.730
We'll go ahead and create a definition.

03:38.120 --> 03:46.790
And load data is going to want to load data for each of the pairs in its map.

03:47.590 --> 03:47.920
Because.

03:47.920 --> 03:48.790
Remember.

03:50.080 --> 03:57.820
It has a map called Load slots mapping integers to mVVM load slots.

03:58.180 --> 04:00.100
I'm going to want to loop over this map.

04:00.100 --> 04:05.020
So I'm going to say for I'll do a const t tuple I'll just say what it is.

04:05.020 --> 04:12.610
It's a t tuple mapping int32 s to um VM load slot pointers.

04:13.090 --> 04:15.730
I'm going to call this pair like I usually do.

04:15.730 --> 04:18.610
Or you could just call it slot or load.

04:18.610 --> 04:20.020
Slot doesn't matter.

04:20.020 --> 04:22.630
And we're looping over load slots.

04:22.630 --> 04:23.590
The map.

04:24.220 --> 04:25.630
So what are we going to do.

04:25.630 --> 04:34.120
Well we want to load slot data and we're keeping track of loading and saving on the game mode.

04:34.120 --> 04:37.570
So we're going to go to the game mode or a game mode base.

04:37.570 --> 04:40.930
And we're going to make a function we can call to load data.

04:41.080 --> 04:44.470
We can call it get save slot data for example.

04:44.470 --> 04:46.660
So let's make that function.

04:46.660 --> 04:51.670
So here on the game mode I'm going to create a function to get save slot data.

04:51.670 --> 04:57.190
And I'd like it to return a U load screen save game object.

04:57.190 --> 05:01.960
We'll go ahead and forward declare it here and we'll call this get save slot data.

05:02.380 --> 05:08.320
And this is going to require two pieces of information the slot name and the slot index.

05:08.320 --> 05:16.810
So we'll pass in a const f string by reference const reference called slot name and an int 32 called

05:16.810 --> 05:18.040
slot index.

05:18.550 --> 05:20.410
And this can be a const function.

05:20.830 --> 05:23.050
Let's go ahead and generate this definition.

05:23.050 --> 05:25.150
And it's going to load data.

05:25.750 --> 05:27.610
So how do we load data?

05:28.000 --> 05:32.170
Well, first we check to see if a slot exists.

05:32.740 --> 05:34.030
We can use you.

05:34.060 --> 05:38.350
Gameplay statics does save game exists.

05:38.350 --> 05:42.370
We could check that first with our slot name and our slot index.

05:42.820 --> 05:43.960
Now we can check this.

05:43.960 --> 05:45.340
This returns a boolean.

05:45.340 --> 05:47.350
So we could check it in an if statement.

05:48.520 --> 05:51.040
And if it does exist we can load it.

05:51.040 --> 05:56.290
We can take you gameplay statics and call load game from slot.

05:56.290 --> 05:57.580
That's how we can load it.

05:57.580 --> 06:01.210
And we specify the slot name and the slot index.

06:01.870 --> 06:06.490
Now this returns a you save game a save game object.

06:06.490 --> 06:13.780
So what I'm going to do is create a you save game pointer called save game object and initialize it

06:13.780 --> 06:22.210
to a null pointer here, and then set it here in the if statement to save game object.

06:23.340 --> 06:26.010
But I'm going to have an else case just in case.

06:26.010 --> 06:28.860
This save game doesn't yet exist.

06:28.860 --> 06:30.780
If it doesn't, we need to create one.

06:30.780 --> 06:39.960
In that case, I'm going to take save game object and call you gameplay statics create save game object

06:39.960 --> 06:44.550
passing in our class load screen save game class.

06:45.060 --> 06:48.240
So either way save game object will have a value.

06:48.240 --> 06:54.120
And then we can cast to you load screen save game.

06:54.120 --> 06:56.490
So we'll go ahead and cast to that.

06:59.210 --> 07:01.970
Casting save game object.

07:03.210 --> 07:08.700
And I'll give it a actual variable name load screen save game.

07:08.940 --> 07:11.250
And after the cast, we'll return it.

07:11.430 --> 07:16.800
And if you want you can eliminate that intermediate local variable there.

07:16.830 --> 07:23.790
Now this function is going to return a save game object based on a slot name and a slot index.

07:23.790 --> 07:28.230
So we can go back to our view model load screen to load data here.

07:28.440 --> 07:31.500
And we can load our data but we need our game mode.

07:31.500 --> 07:38.370
So we're going to say A or a game mode base or a game mode.

07:40.620 --> 07:42.510
And we'll cast to it.

07:44.070 --> 07:48.090
A or a game mode base and we'll call you gameplay statics.

07:48.360 --> 07:51.210
Get game mode, not game instance.

07:51.210 --> 07:51.930
Whoops.

07:51.930 --> 07:54.060
Get game mode.

07:54.390 --> 07:59.220
And we have to pass in this as it needs a world context object.

07:59.220 --> 08:05.820
And after we have the game mode, we can loop over each of our load slots and we can load in data we

08:05.820 --> 08:10.110
can take or a game mode and call get save slot data.

08:10.110 --> 08:16.740
And we can pass in the load slot name, which we can get from our load slot.

08:16.770 --> 08:21.150
It's going to be load slot, dot value, load slot name.

08:21.150 --> 08:23.940
And then the slot itself is pair dot key.

08:25.990 --> 08:27.100
Not chaos pair.

08:27.100 --> 08:28.180
That was typo.

08:28.180 --> 08:28.990
Let's see if.

08:28.990 --> 08:31.630
Yeah we got chaos pair on accident there.

08:31.870 --> 08:33.970
It's going to be actually load slot.

08:33.970 --> 08:39.790
I didn't call it pair I called it load slot and key will give me that slot.

08:39.790 --> 08:44.740
So this gives me a load screen save game object.

08:44.740 --> 08:51.250
So I'm going to store that in a you load screen save game called save object.

08:52.780 --> 09:01.060
And now that we've loaded the data, we can now set properties on our load slot and our map.

09:01.090 --> 09:04.630
So I can take load slot dot value.

09:04.630 --> 09:07.540
And I can call the setter like set playername.

09:08.270 --> 09:12.020
I can set that and I can get it from my save game object.

09:12.020 --> 09:21.290
So what I'm going to do is make a const f string called player name and get it from my save object,

09:21.290 --> 09:23.480
save object player name.

09:23.960 --> 09:29.270
And then I'm going to pass that in here just to show that I'm getting it from the save object.

09:29.270 --> 09:31.490
And we're calling set player name here.

09:31.490 --> 09:34.430
Now that's not the only thing I want to do when I load data.

09:34.430 --> 09:38.930
I also want to set the status of this slot.

09:39.200 --> 09:42.020
So I'm going to get this load slot dot value.

09:45.540 --> 09:52.320
And I'm going to set its slot status, and I'm going to get that status from the save object, because

09:52.320 --> 09:54.240
we should save that status.

09:54.660 --> 09:57.780
Now, does the save object have a status?

09:57.990 --> 10:01.110
Well, if we go to load screen save game dot h.

10:01.800 --> 10:02.610
We don't.

10:02.610 --> 10:06.870
We have the enum defined here, but the save game object doesn't have a status.

10:06.870 --> 10:07.890
It should.

10:07.890 --> 10:12.270
We should use enum as byte because that's how we can save enums.

10:12.270 --> 10:15.000
So t enum as byte.

10:17.490 --> 10:24.360
Of type E save slot status and we'll call this save slot status, and we'll give it a default value.

10:24.360 --> 10:27.480
We'll give it vacant and it gets a new property.

10:28.920 --> 10:33.570
And when we save, we should save this slot status as well.

10:33.570 --> 10:40.140
So in or a game mode base, when we save slot data, we know that we're saving data.

10:40.140 --> 10:49.350
So the slot status has to be taken so we can before we save game to slot, we can take load screen save

10:49.350 --> 10:54.900
game and set its save slot status to taken.

10:55.260 --> 10:56.250
We know it's taken.

10:56.250 --> 10:57.810
We're just now saving to it.

10:57.810 --> 10:58.440
Right.

10:58.440 --> 11:04.980
And now back in our load screen mVVM, we can get that status.

11:04.980 --> 11:06.120
We can get it right here.

11:06.120 --> 11:08.400
We can make a T enum as byte.

11:10.730 --> 11:14.390
E save slot status.

11:16.140 --> 11:18.930
We'll call it save slot status.

11:21.130 --> 11:22.840
We'll get our save object.

11:24.580 --> 11:26.110
Save slot status.

11:27.030 --> 11:28.650
And then we'll take our load slot.

11:28.650 --> 11:33.180
Since we're loading data, we'll set its slot status to save slot status.

11:34.740 --> 11:37.320
So now we're setting that slot status as well.

11:37.320 --> 11:42.780
Now as soon as we set the slot status, we can tell that load slot to initialize slot.

11:42.780 --> 11:43.020
Why?

11:43.050 --> 11:46.290
Because that is where it broadcasts its data.

11:46.290 --> 11:49.560
And now it doesn't have to broadcast a hardcoded value anymore.

11:49.560 --> 11:51.780
It now has its own slot status.

11:51.780 --> 11:53.940
So let's tell it to broadcast that.

11:53.940 --> 11:59.760
We're going to take the load slot dot value and tell it to initialize slot.

11:59.970 --> 12:06.960
Once it does, that load slot is going to initialize it and it can broadcast its status.

12:06.960 --> 12:11.550
Now yes, its status is an enum, but that's okay.

12:11.550 --> 12:13.500
We can get an integer from an enum.

12:13.500 --> 12:15.780
We can say const int 32.

12:17.710 --> 12:19.090
This will be widget switcher.

12:19.090 --> 12:19.930
Index.

12:21.560 --> 12:26.480
And we want the widget switcher index, which is an integer associated with the slot status.

12:26.480 --> 12:31.280
We could take slot status and we can call get value on it.

12:31.670 --> 12:33.770
That'll give us the integer value.

12:34.130 --> 12:35.930
And what value will it be.

12:35.930 --> 12:40.400
Well let's look at load screen Savegame vacant will be zero.

12:40.400 --> 12:43.010
Enter name will be one, taken will be two.

12:43.370 --> 12:50.120
So now that we have widget Switcher index, we can broadcast that index based on the status.

12:50.120 --> 12:53.960
And our widget switcher will switch widgets based on that status.

12:54.470 --> 12:54.920
Brilliant.

12:54.920 --> 12:55.460
Right.

12:55.460 --> 12:58.940
So the question is when do we load the data.

12:59.330 --> 13:00.710
Well we can do it right away.

13:00.710 --> 13:02.300
We can do it from our HUD.

13:02.960 --> 13:04.160
Let's go into our HUD.

13:04.160 --> 13:10.850
We'll go into let's go to the private UI, HUD, load screen HUD.

13:11.270 --> 13:16.790
And after we've created our widget added it to the viewport called blueprint initialize widget.

13:16.790 --> 13:22.820
After all that we should take our load screen view model and we can call load.

13:25.520 --> 13:26.330
Data.

13:27.410 --> 13:34.130
And now we should start off showing the correct widget based on its status that we've saved.

13:34.580 --> 13:41.960
So just to recap on everything, we start off here after we've created our widgets we call load data.

13:41.990 --> 13:45.980
Load data in our view model is right here.

13:46.830 --> 13:48.810
Where we loop over our map.

13:48.810 --> 13:53.520
There should only be three pairs in here and we call get save slot data.

13:53.820 --> 13:55.500
Get save slot data.

13:55.920 --> 13:58.020
It checks to see if the slot exists.

13:58.020 --> 13:59.700
If it does, it loads it.

13:59.700 --> 14:06.810
If not, it creates a save game object and simply casts that to a load screen save game.

14:06.810 --> 14:10.140
So either way it returns a load screen save game.

14:10.770 --> 14:12.750
So back to load data.

14:12.750 --> 14:19.830
Once we have that save object, we set the player name here equal to the player name on the save object.

14:19.830 --> 14:24.090
We set the status and by default that's vacant.

14:24.390 --> 14:28.500
And then we set those properties on our load slot ViewModel.

14:28.710 --> 14:33.870
Setting the player name is setting a bound variable a field notify.

14:33.960 --> 14:35.670
And then we call initialize slot.

14:35.670 --> 14:38.850
And that's going to make our load slot.

14:38.850 --> 14:45.600
View models broadcast this delegate with their widget switcher index which is based on their slot status.

14:46.220 --> 14:52.430
Let's compile and let's just see what happens when we load into our load menu.

14:52.430 --> 14:57.590
And after saving data and then loading back in, let's try it out.

15:00.450 --> 15:03.000
Okay, so back into load menu.

15:03.990 --> 15:05.310
We'll press play.

15:05.640 --> 15:07.170
We'll click new game.

15:07.350 --> 15:11.220
And this time we should be saving to disk.

15:11.220 --> 15:14.520
So I should type in my name click new slot.

15:14.940 --> 15:17.370
And it looks like I went back to the vacant.

15:18.090 --> 15:19.290
Status.

15:19.530 --> 15:20.850
So let's debug this.

15:20.880 --> 15:25.410
We'll go to load screen and VM load screen.

15:25.590 --> 15:27.390
We clicked on new slot.

15:27.390 --> 15:30.090
We called set player name on that slot.

15:30.570 --> 15:31.800
That worked.

15:31.800 --> 15:38.160
We called save slot data for this slot in this index and then called initialize slot.

15:38.520 --> 15:43.800
Now what we should have done is also updated the status for this.

15:43.800 --> 15:46.080
We should have set it to taken at this point.

15:46.080 --> 15:51.960
So what we're going to do at this point before saving the slot data is right after setting the player

15:51.960 --> 15:54.990
name, we're going to set its status to.

15:54.990 --> 15:58.500
So load slots of slot.

15:59.430 --> 16:03.720
We're going to set slot status to take in.

16:05.020 --> 16:06.640
Okay, let's try that again.

16:06.640 --> 16:08.410
I'm going to hit rerun.

16:09.530 --> 16:12.980
And we'll go into load menu.

16:12.980 --> 16:14.150
We'll press play.

16:14.810 --> 16:17.930
And now it's loading in with the correct status.

16:17.930 --> 16:18.890
It should be taken.

16:18.890 --> 16:20.090
Now it's taken.

16:20.570 --> 16:23.660
Now if we click on select slot, that still isn't functional.

16:23.660 --> 16:25.820
But now we can click on new game.

16:25.820 --> 16:28.010
We can enter another name.

16:29.030 --> 16:31.940
I'm going to enter Druid click new slot.

16:31.940 --> 16:33.530
And now it shows Druid.

16:33.530 --> 16:37.490
And if we close and open again now that one loads up.

16:37.640 --> 16:43.280
So testing these things you're very quickly going to find that you want to clear that data.

16:43.280 --> 16:50.120
And that's why I pointed out that you can go into the saved folder and find save games.

16:50.120 --> 16:51.500
And there are those slots.

16:51.500 --> 16:56.180
And if I go in and save to this slot I'll just put an X.

16:56.630 --> 16:57.770
There it is.

16:58.070 --> 17:00.260
Now in my saved games I have all three.

17:00.260 --> 17:05.240
And of course you can just delete them there and come back and they're gone.

17:05.240 --> 17:08.420
So now our status is updating correctly.

17:08.420 --> 17:09.590
Perfect.

17:09.980 --> 17:10.760
Excellent job.

17:10.760 --> 17:18.620
This is coming along and not too many steps left until our save and load system is finished.

17:18.770 --> 17:19.730
I'll see you soon.
