WEBVTT

00:07.230 --> 00:08.340
Welcome back.

00:08.340 --> 00:10.560
Now our menu is coming along.

00:10.560 --> 00:12.240
We can create new slots.

00:12.240 --> 00:18.360
We can select slots and delete them and restore things to their original state.

00:18.360 --> 00:19.200
And that's great.

00:19.200 --> 00:24.150
But let's say we create a slot, we give it a name and we select it.

00:24.150 --> 00:30.630
We want to be able to play the slot, but in addition to that we should see something here for the map.

00:30.630 --> 00:32.790
This should be something meaningful.

00:32.790 --> 00:35.700
This is going to be the map that we travel to.

00:35.700 --> 00:42.510
And if we just created this slot like I just did here, this needs to be the starting map.

00:42.510 --> 00:44.310
There needs to be a default map.

00:44.670 --> 00:48.150
Well, I'd like to have that map designated.

00:48.180 --> 00:51.510
I'd like to store that somewhere important, like the game mode.

00:51.510 --> 00:53.550
The game mode can determine that rule.

00:53.550 --> 00:56.370
Where do we start when we first start the game?

00:56.370 --> 00:59.490
Provided we don't give that as a choice to the player.

00:59.970 --> 01:04.110
So the game mode needs some kind of variable for this level.

01:04.110 --> 01:05.910
So that's the first thing I'd like to add.

01:05.910 --> 01:11.100
And in addition to that, the game mode also needs to know all of the maps in the game.

01:11.100 --> 01:18.210
Because if we've saved our slot and we travel to some other map, then when we're loading in here in

01:18.210 --> 01:22.470
the menu and we press play, we need to travel to that other map too.

01:22.500 --> 01:28.920
So the game mode needs to know about all the maps and how to identify them, and I'd like to identify

01:28.920 --> 01:32.310
them with their user facing string.

01:32.310 --> 01:34.950
Now, widgets use f text.

01:34.950 --> 01:37.380
A lot of things in the engine use f name.

01:37.380 --> 01:46.590
I'd like to use an F string to store the maps name and identify each map with its map name.

01:47.130 --> 01:50.970
So I'm going to add a variable and I'd like to add it to the game mode.

01:50.970 --> 01:53.730
But notice we have two game modes, right?

01:53.730 --> 02:00.060
If we go into blueprints game, we have a load screen game mode, and we have an aura game mode and

02:00.060 --> 02:00.900
load screen.

02:00.900 --> 02:08.610
Game mode is based on if we look at its class settings, the aura game mode base, and we can add those

02:08.610 --> 02:13.050
maps to Aura Game Mode base and then set them here in the game mode.

02:13.050 --> 02:20.580
Of course, if we need them, set both in the load screen game mode and or a game mode, then we would

02:20.580 --> 02:23.250
have to go in and set them in both blueprints.

02:23.760 --> 02:31.110
So instead what we can do is have load screen game mode based on the BP or game mode blueprint, and

02:31.110 --> 02:36.780
then we can just set those map names in aura game mode and load screen game mode will inherit that.

02:37.110 --> 02:41.580
So I'm going to take Load screen game mode, go to Class Settings and base this.

02:41.580 --> 02:44.070
Now on BP Aura Game mode.

02:45.260 --> 02:49.310
And now we only need to set those maps in or a game mode.

02:49.340 --> 02:54.200
Now, as soon as we did that, we need to make sure that our class defaults are what we want.

02:54.710 --> 03:00.050
HUD class is load screen HUD, which is good, but we don't need our player state to be or a player

03:00.050 --> 03:00.470
state.

03:00.470 --> 03:02.390
It can just be regular player state.

03:02.390 --> 03:05.960
We don't need our player controller set to or a player controller.

03:05.960 --> 03:11.420
It can just be the regular player controller, and we don't want the default pawn class to be our character.

03:11.420 --> 03:16.400
We want it to be default pawn so we don't spawn in aura in the load screen.

03:17.540 --> 03:23.210
And after making that change, we can press play and make sure that we still get the behavior that we

03:23.210 --> 03:25.280
expect here in the load screen.

03:25.280 --> 03:26.090
And we do.

03:26.480 --> 03:34.220
So now all we need to do is add to our aura game mode base, which both of our game mode blueprints

03:34.220 --> 03:40.850
inherit from a starting map, and of course, a list of all the maps which we'll get to.

03:40.850 --> 03:46.880
But for now, we at least need the starting map, and we want it associated with the starting map name.

03:47.390 --> 03:52.460
So let's go into C plus plus and open our aura game mode base.

03:52.460 --> 03:56.900
We're going to need at least an F string for the starting map name.

03:56.900 --> 04:00.410
So let's make an F string called starting map name.

04:02.200 --> 04:06.970
And this can be added defaults only, so we can set that from within our editor.

04:07.890 --> 04:12.270
And our starting map name should be the name of, of course, the starting map.

04:12.270 --> 04:18.270
But we need to keep track of all the maps in some kind of data structure.

04:18.450 --> 04:20.850
I hate to say it, but a map comes to mind.

04:20.850 --> 04:22.680
So a map of maps?

04:22.680 --> 04:25.410
That's confusing, but let's make a t map.

04:25.410 --> 04:31.050
And the t map can map f strings to the maps themselves.

04:31.050 --> 04:33.870
And so what are the maps themselves going to be?

04:33.900 --> 04:41.520
Well, if we want to set these in the editor and the details panel, we can make these t soft object

04:41.520 --> 04:42.180
pointers.

04:42.180 --> 04:46.320
If we choose T soft object pointer we need to choose the type.

04:46.320 --> 04:47.940
This is a template wrapper.

04:47.940 --> 04:50.760
And for maps we need to choose you world.

04:51.120 --> 04:56.070
And these are soft object pointers which is nice because they're not loaded in memory until they're

04:56.070 --> 04:56.700
used.

04:56.700 --> 04:58.440
They're lazily loaded.

04:58.830 --> 05:02.460
So we won't have all of our maps loaded in all at the same time.

05:02.850 --> 05:08.220
Now we can call this maps or levels or whatever we want to call it.

05:08.220 --> 05:13.710
I'm going to call it maps just because I can, and I'm going to make it edit defaults only.

05:13.710 --> 05:17.640
And we'll make sure to fill this in with all of the maps.

05:18.270 --> 05:22.860
And we have to make sure that the default map, whatever it is, is in here.

05:22.860 --> 05:26.280
And it has the same name as our starting map name.

05:26.340 --> 05:28.320
That way we can travel to it.

05:28.740 --> 05:33.990
Now if we want to be absolutely sure that that's the case, that our maps will contain our default map,

05:33.990 --> 05:40.560
and that it has the correct map name, we could create a t soft object pointer of type u world called

05:40.560 --> 05:41.760
default map.

05:42.060 --> 05:47.250
So we'll do that default map and we can make this edit defaults only as well.

05:48.510 --> 05:54.870
And we can make sure that maps has the default map added to it.

05:55.570 --> 05:58.300
We won't add the default map in the editor.

05:58.300 --> 06:05.440
We'll add the default map here in code, just to make sure that it has the correct name and map association.

06:05.440 --> 06:11.830
So we'll go ahead and do this in the game modes begin play I don't think we're overwriting begin play.

06:12.100 --> 06:14.020
So we'll override begin play.

06:14.020 --> 06:15.760
That's a protected function.

06:18.400 --> 06:19.540
Virtual void.

06:19.540 --> 06:21.310
Begin play override.

06:23.990 --> 06:31.520
And here in begin play, after calling super, we're going to take maps and add the default map name.

06:33.770 --> 06:35.840
Which we called starting map name.

06:35.840 --> 06:39.920
Let's call it default map name so as to avoid confusion.

06:39.920 --> 06:44.930
And we're going to add default map name as the key and default map.

06:47.960 --> 06:49.250
As the value.

06:49.400 --> 06:54.620
So now we just need to go into or a game mode base and set the default map name.

06:54.620 --> 06:57.980
And then later when we create more maps, we'll add them to the maps.

06:58.280 --> 07:03.290
So first things first, let's go in to the editor and set these two properties.

07:06.760 --> 07:08.260
So let's open up.

07:08.260 --> 07:14.320
We have our load screen game mode, but I'm going to go into aura game mode and set them all here.

07:14.320 --> 07:16.150
So we have a default map name.

07:16.150 --> 07:19.780
And I'm just going to call this first dungeon.

07:20.350 --> 07:24.250
And the default map itself is going to be that dungeon level.

07:24.250 --> 07:30.880
And as we compile and go back to load screen game mode and scroll down, we see that that first dungeon

07:30.880 --> 07:32.080
is set to dungeon.

07:32.260 --> 07:33.130
So that's great.

07:33.160 --> 07:34.270
Now our game modes.

07:34.270 --> 07:35.920
No, the default map.

07:37.110 --> 07:44.670
Now, what I'd like to see is when I go into the load menu, pressing play, I want to see the default

07:44.670 --> 07:45.480
map.

07:46.050 --> 07:52.230
The starting dungeon right here for the map, and I want to see that as soon as we create a new slot

07:52.230 --> 07:55.080
here, I want to see that starting map.

07:55.080 --> 07:57.000
And it's called First Dungeon.

07:57.590 --> 08:03.530
So we're going to need a field notify in our load slot view model.

08:03.530 --> 08:04.730
So that's our next step.

08:04.730 --> 08:06.110
Let's go ahead and do that.

08:06.620 --> 08:11.060
So we go to mVVM load slot where we have our player name.

08:11.060 --> 08:15.830
We already have a field notify which we made edit anywhere blueprint read write.

08:15.830 --> 08:18.890
And we also created setters and getters for it.

08:18.890 --> 08:24.890
But the thing is that the setters and getters are important because we don't want to set the player

08:24.890 --> 08:25.790
name directly.

08:25.790 --> 08:32.000
We want to make sure that we broadcast the field notify, but we also have to make this edit anywhere

08:32.000 --> 08:34.790
blueprint read write if we want it to be a field notify.

08:34.790 --> 08:42.350
That's because the field notify needs read write access to it in order to change it and to get information

08:42.350 --> 08:44.420
from it on the blueprint side.

08:44.420 --> 08:50.570
So we're in a peculiar situation where it should be private, but it can't be if it's blueprint read

08:50.570 --> 08:51.140
write.

08:51.140 --> 08:55.670
So for that reason, what we can do is we can move it into a private section.

08:56.610 --> 09:04.170
Bring that player name down into here, and we can use a workaround to make it blueprint rewrite, but

09:04.170 --> 09:04.860
still private.

09:04.860 --> 09:09.240
In C plus plus we can use meta equals allow private access.

09:09.240 --> 09:15.540
This will allow us to make it a private variable in C plus plus but exposed in the blueprint.

09:15.810 --> 09:18.240
So now we have player name private.

09:18.240 --> 09:21.780
We just have to make sure we're not setting or getting it directly.

09:21.780 --> 09:28.950
And or a game mode base does do that and save slot data where it's setting the load screen, save game

09:28.950 --> 09:34.380
player name to the player name and the load slot we have to call get player name now.

09:34.380 --> 09:35.580
No big deal.

09:35.580 --> 09:37.950
All right, so back to our task though.

09:37.950 --> 09:42.630
We need a field notify for the map name so that we can bind that in the widget.

09:42.630 --> 09:46.470
So I'm just going to copy player name and paste a new one.

09:46.470 --> 09:48.540
And this one can be map name.

09:48.780 --> 09:52.200
And it's going to also have the same view property.

09:52.200 --> 09:54.150
It's going to be a field notify.

09:54.150 --> 10:00.450
And with getter and setter in the U property we have to add getters and setters here in C plus plus

10:00.450 --> 10:03.570
so we can make a setter void set map name.

10:03.900 --> 10:07.020
It can take an f string called in map name.

10:07.440 --> 10:13.410
And we'll generate a function definition for it because we're going to want to use the set property

10:13.410 --> 10:14.700
value macro.

10:14.700 --> 10:16.380
Let's just do that first thing.

10:16.380 --> 10:19.650
We're going to set that it's our map name.

10:20.130 --> 10:22.740
And we're setting it to in map name.

10:22.740 --> 10:27.960
And that's going to be broadcast to any widgets that bind to this field notify.

10:28.170 --> 10:30.540
And then we can create our getter.

10:30.540 --> 10:33.870
It can return an F string get map name.

10:33.870 --> 10:37.980
It'll be const and simply return map name.

10:39.420 --> 10:41.430
So now we have a field notify.

10:41.430 --> 10:47.160
All we need to do is actually set this map name and then bind to the field notify in our widget.

10:47.670 --> 10:49.410
So when do we set the map name.

10:49.410 --> 10:55.980
Well for starters I'd like to set it to the default map as soon as we've created our first slot.

10:55.980 --> 11:02.310
And we can go back to mVVM, load screen to new slot button pressed, where we're setting our player

11:02.310 --> 11:05.820
name to the entered name we're setting our slot status to taken.

11:05.820 --> 11:14.340
We can also set that map name as well, so we can take our load slots of slot here, and we can set

11:14.340 --> 11:17.940
its map name so we can call Set Map name.

11:17.940 --> 11:21.690
That way we'll be sure to broadcast the field notify.

11:21.690 --> 11:23.490
And what is the map name.

11:23.490 --> 11:25.800
Well we want to get that from our game mode.

11:25.800 --> 11:27.720
So we'll take our game mode.

11:27.720 --> 11:30.510
And we're going to get that default map name.

11:30.510 --> 11:31.770
And we'll set it to that.

11:31.770 --> 11:38.880
And as soon as our player ventures into a new map, well then we need to worry about saving that information

11:38.880 --> 11:40.530
to disk to our slot.

11:40.530 --> 11:40.980
Right.

11:40.980 --> 11:42.300
We'll get to that soon.

11:42.300 --> 11:48.360
But for now, we just need to make sure that at least our map name is correct when we first create a

11:48.360 --> 11:49.230
saved slot.

11:49.230 --> 11:52.860
So we'll do that when a new slot is created.

11:53.130 --> 12:01.470
So with this we just need to bind to our field, notify the map name in our mVVM load slot ViewModel.

12:01.470 --> 12:07.590
Let's go ahead and compile and launch and make sure that our map name is bound to that.

12:09.270 --> 12:09.750
All right.

12:09.750 --> 12:13.170
So back in the editor we're going to get everything back open.

12:13.200 --> 12:17.970
Now our load screen game mode definitely has that default map name.

12:18.030 --> 12:27.030
So what we can do is we can go back into blueprints UI load menu and make sure that our load slot taken,

12:27.030 --> 12:31.620
which is the one that has that map, has this property bound.

12:31.800 --> 12:37.500
So this one we have this text and it's called text underscore map value.

12:37.530 --> 12:39.930
We need to check is variable on that.

12:39.930 --> 12:42.930
And then we can bind this text.

12:43.230 --> 12:45.630
We'll do this just like we did the player name.

12:45.630 --> 12:49.140
We're going to show our view bindings down here.

12:49.350 --> 12:50.940
And we need to add one.

12:50.940 --> 12:52.770
We need to click add widget.

12:52.770 --> 12:56.100
And from the dropdown that says none we need to choose our widget.

12:56.100 --> 12:58.440
And it's called Text Map value.

12:58.440 --> 13:00.810
We're going to click on that and select it.

13:01.200 --> 13:05.250
And we need to choose what property on it that we want to bind.

13:05.250 --> 13:06.840
We want to bind its text.

13:07.320 --> 13:10.800
We'll select that we want this one way to the widget.

13:10.800 --> 13:14.580
And what we need to use is a conversion function.

13:14.580 --> 13:16.740
So we can click on conversion functions.

13:16.740 --> 13:18.960
We need two text from string.

13:18.960 --> 13:21.600
So two text parentheses string.

13:21.600 --> 13:28.830
And then the end string is going to be one of our field notifies the one on our load slot view model.

13:28.830 --> 13:30.600
And it's called map name.

13:30.600 --> 13:32.100
So we're going to select that.

13:32.100 --> 13:34.170
And now we have our binding.

13:34.320 --> 13:36.510
So we can test this.

13:36.510 --> 13:40.440
So we can go back to Maps Load menu.

13:41.240 --> 13:48.170
And playtest this, but we have to keep in mind that any slots that we already had saved, those we

13:48.170 --> 13:54.800
never actually set their field notifies in those mVVM load slot view models.

13:55.130 --> 13:56.960
It's only when we create a new game.

13:56.960 --> 13:58.490
So let's create a new one.

13:58.490 --> 14:01.700
I'll call this one Steven click new slot.

14:01.700 --> 14:09.020
And now we see First Dungeon, because it's only when we create that new slot, when we press our button,

14:09.020 --> 14:13.490
let's just remind ourselves here and load screen new slot button pressed.

14:13.490 --> 14:16.220
This is when we set that slots map name.

14:16.220 --> 14:19.550
That's when we broadcast that field notify.

14:19.550 --> 14:23.060
So it's only because we just created a new one.

14:23.060 --> 14:25.730
If we go ahead and take these slots and delete them.

14:27.530 --> 14:29.450
And we create new slots.

14:30.020 --> 14:32.270
Then they have first dungeon as well.

14:33.660 --> 14:37.080
Now, first dungeon is kind of big.

14:37.080 --> 14:41.430
We sort of need to lower our font size now, don't we?

14:41.460 --> 14:42.840
We can do that.

14:42.840 --> 14:47.310
Or if you like, the way it looks with the select slot button kind of lower.

14:47.310 --> 14:48.720
It's kind of cool.

14:49.770 --> 14:52.020
Let's see what happens when we delete it.

14:52.320 --> 14:53.580
Create a new one.

14:56.540 --> 15:02.480
It doesn't look too bad, but I think that these fonts could be a little bit smaller.

15:02.480 --> 15:09.020
So before we wrap up, I'm just going to take these and make them just a bit smaller, just a tad.

15:09.050 --> 15:11.060
Their size is 24.

15:11.830 --> 15:15.100
We can try 18 and see how that looks.

15:17.790 --> 15:21.090
So same for the map 18.

15:21.540 --> 15:24.120
Dungeon 18.

15:25.080 --> 15:26.460
We can see how that looks.

15:31.700 --> 15:34.490
And I'm going to go ahead and delete these two.

15:37.470 --> 15:38.940
Create new slots.

15:39.790 --> 15:41.620
And those look a little bit better.

15:43.700 --> 15:46.760
Of course, we might have text flow over, right?

15:47.300 --> 15:52.370
Now if I click close and start up again, well, we're not showing that map.

15:52.850 --> 15:57.620
We're not actually saving the map name and we're not updating the map.

15:57.620 --> 15:58.790
We're not loading it.

15:58.790 --> 16:01.640
And that's something that we could easily implement.

16:01.640 --> 16:03.020
We need to save it.

16:03.320 --> 16:12.380
So while we do have the ability to set the map name in our load slot view model and it updates in the

16:12.380 --> 16:15.440
field, notify we're not actually saving it to disk.

16:15.440 --> 16:19.550
And that's going to be our next step is saving the map name to disk.

16:19.550 --> 16:20.990
And we'll do that next.
