WEBVTT

00:06.950 --> 00:08.030
Welcome back.

00:08.030 --> 00:15.680
Now our load menu map has a load screen game mode which has its own load screen HUD.

00:15.710 --> 00:18.920
Now we're going to want to do some stuff in that HUD.

00:18.920 --> 00:22.010
We want to create a new widget.

00:22.010 --> 00:26.120
And I'd like that widget to be one of our C plus plus classes.

00:26.120 --> 00:34.070
We just created our load screen widget, which by the way we can make sure that our load screen widget

00:34.070 --> 00:35.810
blueprints are based on it.

00:35.810 --> 00:39.500
So let's go into blueprints UI load menu.

00:39.500 --> 00:44.540
And we're going to make these load screen widgets based on our C plus plus class.

00:44.540 --> 00:50.900
But even more than that, I'd like to make a blueprint based class based on load screen widget that

00:50.900 --> 00:56.780
all of these can inherit from, and that way they can inherit anything we add in blueprint as well.

00:56.780 --> 01:02.090
So I'm going to right click and make a new user interface widget blueprint.

01:02.090 --> 01:06.560
And this is going to be based on our load screen widget.

01:06.560 --> 01:14.810
So I'm going to select that I'm going to call this Wbhp load screen widget underscore base.

01:15.650 --> 01:19.970
So we have a base class, and these other widgets can be based on it.

01:19.970 --> 01:23.840
And they'll inherit anything that we put in that C plus plus class.

01:23.840 --> 01:29.690
And in our new load screen widget base, if we decide to put things here and we will.

01:29.690 --> 01:37.040
So I'm going to close that and make sure that these widgets all inherit from load screen widget base.

01:37.040 --> 01:39.980
So we'll start with our load menu.

01:40.490 --> 01:50.150
We'll go to the graph, go to Class Settings and set our base class to Wbbp load screen widget base.

01:50.860 --> 01:55.390
We'll go ahead and save that, and we can do the same thing for these other widgets.

01:55.390 --> 01:58.090
We have the enter name widget.

01:58.090 --> 02:02.770
This can be now Reparented to load screen widget base.

02:08.990 --> 02:19.520
We can also go to the take in widget Reparent this to load screen widget base and the load slot vacant.

02:20.060 --> 02:26.360
We can reparent this to load screen, widget base and finally load slot widget switcher.

02:26.360 --> 02:29.630
This one too can be a load screen widget base.

02:29.630 --> 02:34.310
They're all based on the same blueprint now, which is a load screen widget.

02:34.310 --> 02:40.430
And just like all of our other widgets are based on or a user widget, these are all based on load screen

02:40.430 --> 02:41.090
widget.

02:41.330 --> 02:47.060
So with that, I'm going to go ahead and close down all these as we don't need them anymore.

02:48.480 --> 02:54.720
And now that we have a load screen widget class, I'd like to construct one of these.

02:54.720 --> 02:58.950
I'd like to add it to the viewport, and I'm going to do that in my load screen HUD.

02:58.950 --> 03:05.880
So I'm going to go ahead and close down the editor and go to my load screen HUD dot h file.

03:05.880 --> 03:12.570
And I'd like to first of all have a public and a protected section.

03:12.570 --> 03:14.640
The protected is for begin play.

03:15.060 --> 03:19.290
We're going to overwrite that Virtualvoid begin play override.

03:19.800 --> 03:22.050
We'll go ahead and get that constructed.

03:22.560 --> 03:26.940
Now, in addition to that, I'm going to want to spawn some things.

03:26.940 --> 03:34.860
I want to spawn a user widget, and I'd like that user widget to be my load screen menu.

03:35.310 --> 03:39.030
So I'm going to make a subclass of for the class for it.

03:39.030 --> 03:40.950
It's going to be a user widget.

03:44.250 --> 03:51.570
We'll call this load Screen widget class, and we'll set this in our HUD blueprint.

03:51.570 --> 03:54.900
We'll give it a U property edit defaults only.

03:55.320 --> 03:59.760
And that is going to be the class that we want to create.

04:00.300 --> 04:07.110
And in addition to that, we'll have a pointer for the user widget itself once we create it so we can

04:07.110 --> 04:13.140
hold on to it, we're going to have a t object pointer of type user widget as well.

04:13.140 --> 04:14.970
And this will be the load screen.

04:14.970 --> 04:19.320
Widget one is the class, the other is the widget.

04:19.320 --> 04:23.310
And the widget itself is going to be blueprint read only.

04:30.230 --> 04:36.290
And with that, we can construct a new load screen widget and add it to the viewport so we can go into

04:36.290 --> 04:37.310
Begin Play.

04:37.310 --> 04:40.100
And we can take our load screen widget.

04:40.880 --> 04:47.000
And we can initialize it by using Create Widget and create widgets is a template.

04:47.000 --> 04:50.810
It's going to need that user widget class to spawn.

04:51.110 --> 04:54.560
Now writers telling me to include user widget.

04:54.560 --> 04:58.280
Now that I have I can spawn with create widget.

04:58.280 --> 05:00.110
The type of widget I want to create.

05:00.110 --> 05:10.790
I can create a u load screen widget if I like, and for the owning object, I'm just going to have the

05:10.790 --> 05:12.020
world own it.

05:12.020 --> 05:17.600
And for the class to spawn it's going to be load screen widget class.

05:18.830 --> 05:28.070
Now we can add this to the viewport add to viewport, and then we can do anything we want on the Load

05:28.070 --> 05:29.120
screen widget.

05:29.120 --> 05:31.640
Tell it to do things whatever we want.

05:31.640 --> 05:34.700
And in fact load screen widget doesn't have to be just a user widget.

05:34.700 --> 05:42.110
It could be a u load screen widget, and then we wouldn't even have to cast it as create widget is going

05:42.110 --> 05:43.550
to return that type.

05:44.450 --> 05:48.350
So this can be a you load screen widget.

05:48.350 --> 05:50.450
We can add a forward declaration for that.

05:50.450 --> 05:53.690
And now we have this in the form of a load screen widget.

05:53.720 --> 05:55.220
Now this is great.

05:55.220 --> 05:56.960
We can go ahead and compile.

05:56.960 --> 05:59.150
We can launch make sure that it works.

05:59.890 --> 06:00.940
We'll do that real quick.

06:03.120 --> 06:06.240
And we can go right into our HUD.

06:06.240 --> 06:12.990
So I can go to my HUD folder to load screen HUD and set that class load screen widget class.

06:14.670 --> 06:17.790
And it's actually called Wbhp load menu.

06:18.640 --> 06:20.200
That's our load screen widget.

06:20.200 --> 06:22.150
So we're going to go ahead and set that.

06:22.730 --> 06:26.930
And we can go over to our load menu map.

06:26.930 --> 06:29.270
Let's go to maps Load menu.

06:29.300 --> 06:35.540
We can press play and we're spawning our load screen widget our load menu okay.

06:35.540 --> 06:36.980
So nothing new right.

06:36.980 --> 06:38.780
We've already done that before.

06:38.780 --> 06:40.760
Now we're just doing it in C plus plus.

06:40.760 --> 06:45.380
But the difference here is now I want to create a view model.

06:45.650 --> 06:47.870
So how can we create a view model.

06:47.870 --> 06:49.340
Well we can do it in C plus.

06:49.340 --> 06:55.130
Plus we can add a class to spawn just like we did our load screen widget class.

06:55.130 --> 06:58.040
We can have a view model class.

06:58.040 --> 07:00.110
So I'm going to have a subclass of.

07:02.990 --> 07:07.520
And this will be of our load screen view model type.

07:07.520 --> 07:10.100
And that starts with a U and its mVVM.

07:10.100 --> 07:12.800
So you mVVM load screen.

07:12.800 --> 07:14.480
We'll add a forward declaration.

07:14.480 --> 07:19.730
And this is going to be the load screen view model class.

07:20.450 --> 07:24.560
And just like our load screen widget class it's going to be edit defaults only.

07:26.490 --> 07:32.940
And we'll also have a t object pointer of this type so that we can store it once we've created it.

07:32.940 --> 07:38.730
So we'll have a t object pointer using our load screen ViewModel type.

07:38.730 --> 07:41.580
And this will be load screen ViewModel.

07:42.060 --> 07:45.030
And this will be blueprint read only as well.

07:46.380 --> 07:50.130
So let's go back to begin play and let's create one of these.

07:50.130 --> 07:52.710
Now this is a new object.

07:52.710 --> 07:54.360
We can create it with new object.

07:54.360 --> 07:57.120
We'll do it before creating the load screen widget.

07:57.120 --> 08:04.140
So we'll say load screen ViewModel and we'll use new object.

08:04.170 --> 08:05.640
Now this is a template.

08:05.640 --> 08:09.720
We specify you mVVM load screen.

08:10.390 --> 08:12.340
That type will be included.

08:12.340 --> 08:19.720
We got the header include there and new object needs an outer will just use this this particular HUD

08:19.720 --> 08:22.810
and the class load screen view model class.

08:22.810 --> 08:23.890
Now we have it.

08:24.580 --> 08:30.130
So now that we're creating this load screen view model and we're doing it before creating the load screen

08:30.130 --> 08:34.540
widget, how do we set our load screen widgets view model.

08:35.020 --> 08:36.400
That's the question.

08:36.400 --> 08:40.960
And there are a few options when it comes to setting the view model.

08:40.960 --> 08:42.250
Let's explore some of these.

08:42.250 --> 08:45.640
Let's go ahead and compile and launch okay.

08:45.640 --> 08:51.340
So I'm going to go ahead and get my load screen HUD back because we have a load screen view model class

08:51.340 --> 08:51.850
to set.

08:51.850 --> 08:53.770
Now we only have the C plus plus class.

08:53.770 --> 08:56.920
But we can make a blueprint based on view models too.

08:57.220 --> 08:58.420
And I'd like to do that.

08:58.420 --> 09:05.170
I'd like to go into blueprints UI and have just like we have Widget controller, we can have a view

09:05.170 --> 09:05.980
model class.

09:05.980 --> 09:12.880
So everything you're seeing here is going to be very similar to the way we've done things already with

09:12.880 --> 09:16.450
widget controllers, but we'll start to see some differences pretty soon.

09:16.930 --> 09:24.370
Here in the view model folder, we're going to create a new class based on our mVVM Load screen class.

09:25.450 --> 09:28.600
And this is going to be called our load screen view model.

09:28.600 --> 09:33.370
We can call this BP Load Screen View model.

09:34.780 --> 09:41.650
That way it's nice and different from our C plus plus version of the class and load screen view model

09:41.650 --> 09:42.700
is a blueprint.

09:42.700 --> 09:47.020
Much like other blueprints, it has its own event graph.

09:47.020 --> 09:52.150
We can add functions, we can add variables to it, and we're going to go back to Load screen HUD and

09:52.150 --> 09:57.670
set our load screen view model class to our new load screen model blueprint.

09:58.390 --> 10:01.330
So now we should be constructing one of those.

10:01.330 --> 10:09.280
If we go back to our maps and load menu map and we save all, we can press play.

10:09.280 --> 10:15.670
And not only are we constructing our new load screen widget, we're constructing that view model too.

10:16.240 --> 10:18.340
We just can't see anything as a result of it.

10:18.340 --> 10:19.270
It's invisible.

10:19.270 --> 10:19.720
Now.

10:19.720 --> 10:24.730
Just because we're constructing one in the HUD doesn't mean that it's associated with our load screen

10:24.730 --> 10:25.300
widget.

10:25.300 --> 10:26.260
It's not.

10:26.260 --> 10:34.660
We have to make sure that that happens by going into our load screen widget in blueprints UI load menu,

10:35.110 --> 10:36.400
and we have it here.

10:36.400 --> 10:37.630
It's called Load menu.

10:37.630 --> 10:42.790
Now I keep calling everything load screen except for this one widget here.

10:42.790 --> 10:46.540
So it seems kind of like it should be called load screen shouldn't it?

10:46.540 --> 10:51.520
Let's go ahead and just rename it to Load screen Wbhp load screen.

10:51.520 --> 10:53.920
And now we won't be so confused.

10:54.370 --> 10:56.080
Let's open load screen.

10:56.500 --> 10:59.080
And the question is how do we set its view model.

10:59.750 --> 11:05.390
Now, we've seen in our system, we created with our widget controllers that we could do this in a number

11:05.390 --> 11:13.820
of ways if we wanted to do it using our ability system library, like get some kind of widget controller.

11:14.890 --> 11:21.370
Attribute menu, overlay spell menu, and provided that those widget controllers have already been constructed

11:21.370 --> 11:24.520
by the time we call this, we'll have a valid one.

11:24.820 --> 11:29.500
The question is, is there a way to do that with Viewmodels?

11:29.530 --> 11:31.090
Well, kinda.

11:31.330 --> 11:32.560
It's a little different.

11:32.560 --> 11:39.370
What we have to do is go up to the window tab and in window in the designer we have to be in designer,

11:39.370 --> 11:40.990
we can't be in the graph tab.

11:40.990 --> 11:44.350
In the designer tab we can click on View Models.

11:44.350 --> 11:47.620
Notice we have this view models option.

11:47.620 --> 11:53.530
But if we go back to graph where we're in the event graph and we go to window there is no view model.

11:53.530 --> 11:55.630
So you might be confused.

11:55.630 --> 11:56.980
If you can't find it.

11:56.980 --> 11:59.950
Just remember you have to go back to designer.

11:59.950 --> 12:05.110
If you're in the designer tab then you can click window and open View models.

12:05.620 --> 12:09.310
Now here's where we can add a view model to this particular widget.

12:09.310 --> 12:13.420
If we click plus then we can select the view model class.

12:13.420 --> 12:16.810
And we have the C plus plus class as an option.

12:16.810 --> 12:21.400
But there's a dropdown where we can select the blueprint version as well.

12:21.580 --> 12:29.740
So if we select that and click select we now have Load Screen View model under the View Models window.

12:29.770 --> 12:35.650
Now you could dock this if you wanted to dock it right here under details for example right there.

12:35.650 --> 12:38.860
You could do that now under view model.

12:38.860 --> 12:43.870
If we select BP load screen view model we have a little menu that pops up.

12:44.440 --> 12:50.710
And here is where we select one of the options for creating the view model.

12:50.710 --> 12:53.470
For this widget there's a creation type.

12:53.890 --> 12:58.210
Now we can hover over them to see what the different creation types do.

12:58.210 --> 13:03.970
Creation type create instance says a new instance of the view model will be created when the widget

13:03.970 --> 13:04.810
is created.

13:04.810 --> 13:06.490
So that's one option.

13:06.670 --> 13:11.830
Now if you want to have tighter control you can select a different one.

13:11.830 --> 13:13.990
You can choose manual and a manual.

13:13.990 --> 13:16.810
One says the view model will be assigned later.

13:16.810 --> 13:21.490
So you have to assign that view model manually to this widget.

13:21.490 --> 13:22.660
That's another way.

13:22.690 --> 13:25.450
There's also global view model collection.

13:25.450 --> 13:30.220
So we could create a global view model and add it to a global view model collection.

13:30.220 --> 13:32.620
And then it will be retrieved that way.

13:32.770 --> 13:39.820
And then another way, which is actually a kind of cool way to do it is by selecting property path.

13:40.360 --> 13:48.220
Property path allows us to create some kind of function on our widget that will find the property.

13:48.220 --> 13:50.890
It will find our view model.

13:50.890 --> 13:58.690
And if we set this to property path and choose that function name, if we expand advanced we have view

13:58.690 --> 13:59.740
model property path.

13:59.740 --> 14:06.190
Here we can enter a function name here and that function will be called to find the view model.

14:06.190 --> 14:12.040
Let's see how this method works because it's perhaps the most confusing sounding, but it's actually

14:12.040 --> 14:12.940
quite simple.

14:12.940 --> 14:17.950
Let's create a function that can find our view model, but I'm not going to put it on load screen.

14:17.950 --> 14:19.960
I'm going to put it on the base class.

14:20.470 --> 14:25.480
Let's go into WP load screen widget base.

14:26.540 --> 14:31.550
Here, we're going to have a function that we can use to find the view model.

14:31.970 --> 14:33.980
I'm going to create this function here.

14:33.980 --> 14:36.080
It's going to be a new function.

14:36.080 --> 14:41.420
And I'm going to call this find load screen view model.

14:42.620 --> 14:45.170
And it's going to return a view model.

14:45.170 --> 14:48.890
Let's add an output to it and select the type for the output.

14:48.890 --> 14:55.790
I'm going to search for BP load screen view model.

14:57.580 --> 15:00.040
And it's going to return an object reference of that.

15:01.690 --> 15:05.530
And then we can determine here how to find that view model.

15:05.530 --> 15:09.670
And we could do it quite simply, we can get the player controller.

15:10.780 --> 15:11.290
Why?

15:11.290 --> 15:14.140
Because the player controller can get the HUD.

15:16.150 --> 15:17.470
Why do we want the HUD?

15:17.470 --> 15:19.060
Because we want to cast it.

15:19.990 --> 15:21.760
To BP.

15:21.790 --> 15:23.410
Load screen HUD.

15:23.740 --> 15:25.510
Why do we want to cast it to BP?

15:25.510 --> 15:26.470
Load screen HUD.

15:26.500 --> 15:31.990
Because we made a blueprint read only property called ViewModel.

15:31.990 --> 15:34.180
It's called load screen ViewModel.

15:34.180 --> 15:35.500
We want to get that.

15:35.680 --> 15:36.730
Why do we want to get that?

15:36.730 --> 15:38.410
Because that's what we want to return.

15:38.950 --> 15:40.960
Now this returns a BP, right?

15:40.960 --> 15:42.520
We can't just hook that in.

15:42.520 --> 15:45.460
We have to cast again to BP.

15:46.570 --> 15:47.410
Load screen.

15:47.410 --> 15:48.460
View model.

15:49.030 --> 15:50.560
And then return that.

15:55.650 --> 15:59.250
So provided that these casts don't fail.

16:00.990 --> 16:04.410
And they shouldn't because we've set these classes.

16:05.150 --> 16:11.030
Then this function gets the player controller, gets the HUD from it from the HUD cast to load screen

16:11.030 --> 16:16.700
HUD from load screen HUD gets the load screen view model from the load screen view model casts to the

16:16.700 --> 16:19.040
blueprint version and returns it.

16:19.700 --> 16:23.090
Now this we just put on load screen widget base.

16:23.090 --> 16:29.150
So all of our load screen widgets inherit this including load screen and load screen.

16:29.150 --> 16:32.000
Because it's creation type is property path.

16:32.000 --> 16:36.800
We have this view model property path we can set to find.

16:36.800 --> 16:38.000
Oh I forget what it's called.

16:38.000 --> 16:40.850
It's called find load screen view model.

16:41.090 --> 16:47.060
So we can use that as the property path find load screen view model.

16:48.550 --> 16:54.220
And with that, as soon as our widget is constructed, it's going to call that function to find and

16:54.220 --> 16:57.130
set its own load screen view model.

16:57.520 --> 17:05.020
We can click on compile and we get compiler errors because there's a very specific requirement for these

17:05.020 --> 17:07.030
property path functions.

17:07.030 --> 17:12.520
And that specific requirement is that it has to be a const function.

17:12.910 --> 17:21.940
So if we go back to load screen widget base and get this new function, if we make this a const function

17:22.270 --> 17:29.140
by going to advanced and checking the checkbox for const, then going back to load screen Wbhp load

17:29.140 --> 17:29.440
screen.

17:29.440 --> 17:31.810
That is, we no longer have compiler errors.

17:31.810 --> 17:35.350
So that is one important detail that you can't forget.

17:35.350 --> 17:38.110
These property path functions have to be const.

17:38.640 --> 17:44.760
But now I'm going to show you something kind of cool back in our Wbhp load screen, because we now have

17:44.760 --> 17:46.680
this load screen view model.

17:46.680 --> 17:53.550
If we go to our graph and we right click and type load screen view model.

17:55.110 --> 17:55.530
Look at this.

17:55.530 --> 18:00.930
We have get BP load screen view model like it's a member variable.

18:01.380 --> 18:02.010
It's not.

18:02.040 --> 18:08.280
We don't see it here but we can access it anyway because we've added this view model.

18:08.520 --> 18:13.770
And what I'd like to do is just see at some point and in event tick.

18:13.770 --> 18:17.610
Because right now I don't have any other place to check.

18:17.760 --> 18:18.810
I'm going to check.

18:18.810 --> 18:25.410
I'm going to use a validated get and in tick I'm going to get that load screen view model, get object

18:25.410 --> 18:28.620
name on it and call print string.

18:31.530 --> 18:37.500
And as soon as it becomes valid, we should start seeing its name, just spamming the screen.

18:37.500 --> 18:42.360
So I'm going to go ahead and save all press play and there's my load screen view model.

18:42.360 --> 18:45.810
So it is being set in our load screen.

18:45.810 --> 18:47.190
So it does have a view model.

18:47.190 --> 18:51.870
That's one of the cooler ways to set that load screen view model.

18:51.870 --> 18:53.910
And we'll get some experience with the others.

18:53.910 --> 18:57.120
But the property path it's a little bit more confusing.

18:57.120 --> 18:58.440
So we'll start with that one.

18:58.440 --> 19:02.790
Now that we see that it's not actually confusing, we've got it under our belt.

19:02.790 --> 19:07.710
We now know that our load screen has its own load screen widget set.

19:08.580 --> 19:10.860
Now this is where the magic can really happen.

19:10.860 --> 19:12.930
This is where we can tie things together.

19:12.930 --> 19:20.340
We now have a ViewModel for our widget, and we can start doing some really exciting things, such as

19:20.340 --> 19:26.310
binding some of our widget variables to our ViewModel variables so that they're closely connected and

19:26.310 --> 19:27.690
can update each other.

19:27.960 --> 19:29.670
So we'll start doing that next.

19:29.700 --> 19:30.780
Excellent job.

19:30.810 --> 19:31.890
I'll see you soon.
