WEBVTT

00:07.590 --> 00:08.580
Welcome.

00:09.210 --> 00:16.140
So our game project involves attributes such as health, and in nearly all game projects, health and

00:16.140 --> 00:20.370
other important attributes are displayed to the player on the screen.

00:21.010 --> 00:25.210
We refer to objects displayed on the screen as widgets.

00:25.390 --> 00:31.450
And in Unreal we create widget blueprints to provide visual representations of game data.

00:33.050 --> 00:40.130
Widget blueprints are derived from the base C plus plus class you user widget widget blueprints need

00:40.130 --> 00:41.540
to receive data.

00:41.960 --> 00:44.930
A health bar needs to know how much health to display.

00:44.930 --> 00:50.090
An icon for a given ability needs to show the correct icon for that ability.

00:50.090 --> 00:57.170
The point is that widget objects must receive data so they know the correct values to depict and the

00:57.170 --> 00:59.480
game is rife with this data.

00:59.630 --> 01:06.200
The attribute set contains numerical data for all of the attributes belonging to a given character.

01:06.380 --> 01:12.500
The player state might contain a number of variables that need to be shown to the player on the screen

01:12.500 --> 01:13.990
for any number of reasons.

01:14.000 --> 01:20.030
There are numerous classes in the game, each containing data that may or may not need to be known by

01:20.030 --> 01:26.690
the widget objects in order to show the player what's happening behind the scenes of the game mathematically.

01:26.690 --> 01:31.160
So the question arises how should the widget object get that data?

01:31.190 --> 01:37.470
There are a number of ways the widget object could manage to dig its hands deep into the game code,

01:37.470 --> 01:43.740
retrieving pointers and references to the characters controllers player states, ability system components,

01:43.770 --> 01:48.510
attribute sets and access all that data it needs directly.

01:48.750 --> 01:50.760
But is this the best way?

01:50.940 --> 01:56.880
As you're making your game project, the question should arise in your mind How should this type of

01:56.880 --> 02:01.410
system be designed as the game grows in size and complexity?

02:01.410 --> 02:03.780
How should this type of data be handled?

02:03.780 --> 02:07.800
How would, say an experienced developer do it?

02:07.830 --> 02:10.200
How do triple-A games do it?

02:10.560 --> 02:13.230
That's what we're concerned with in this course.

02:13.230 --> 02:17.400
How to do this in a scalable and maintainable manner.

02:17.940 --> 02:23.100
Now, in a well structured program, we should have a separation of concerns.

02:23.430 --> 02:24.480
With UI.

02:24.510 --> 02:26.630
We have three different domains.

02:26.640 --> 02:33.720
The first domain is the display of visual effects of the data, such as health bars and ability icons.

02:33.720 --> 02:40.530
Basically all your widgets, we'll call this domain the view as it contains all the things the player

02:40.530 --> 02:42.480
views while playing the game.

02:42.600 --> 02:45.300
Now we also have the data itself.

02:45.330 --> 02:51.690
These are the numerical values, the player's health, the player's level, mana experience, which

02:51.720 --> 02:57.480
abilities have been unlocked, what their levels are and what buttons those abilities are assigned to.

02:57.720 --> 03:04.020
All this data exists within the code base of the game project itself, and we'll call this data the

03:04.020 --> 03:08.400
model as it models the underlying rules and results of the game.

03:08.400 --> 03:14.580
This is the data that will ultimately drive the widgets that we will see in the view domain.

03:14.730 --> 03:20.250
Now, getting data from the model to the view is a task we need to think about.

03:20.370 --> 03:27.360
This can be done in a number of ways, but a good way to organize this is to have some sort of class

03:27.360 --> 03:33.270
that can handle retrieving the data from the model and broadcasting it to the view.

03:33.660 --> 03:40.410
This class can be responsible not only for the retrieval of the data, but any calculations or algorithmic

03:40.410 --> 03:43.980
functionality involved in processing that data.

03:44.040 --> 03:51.090
This class exists in a domain that we'll call the controller in this system, and the controller will

03:51.090 --> 03:58.500
be responsible for retrieving data from the model and passing it to the view so it can depict data visually.

03:58.560 --> 04:03.780
Now we're not talking about the a controller or a player controller classes in the engine.

04:03.810 --> 04:07.500
Those are designed to possess and control pawns.

04:07.500 --> 04:12.930
What we're talking about is a controller class used to drive data to the View.

04:12.930 --> 04:17.400
So for that reason we'll refer to this as a widget controller.

04:17.520 --> 04:24.420
This means the view can simply focus on how the data should look receiving the data from any broadcasts

04:24.420 --> 04:25.890
made from the controller.

04:25.890 --> 04:30.630
But the view may contain widgets that the player can interact with, such as buttons.

04:30.630 --> 04:37.050
When the player clicks a button, that action may result in some change in the model, such as increasing

04:37.050 --> 04:40.350
attributes or granting new abilities to the player.

04:40.350 --> 04:46.710
So the controller's job is also to facilitate the actions resulting from the widget interaction by the

04:46.710 --> 04:49.200
player causing changes in the model.

04:49.230 --> 04:54.240
In other words, the controller is a middleman between the view and the model.

04:54.240 --> 05:00.270
Now some implementations of this software architecture pattern are different than others.

05:00.270 --> 05:07.710
Sometimes the widget controller is only responsible for retrieving data from the model and presenting

05:07.710 --> 05:08.790
it to The View.

05:08.790 --> 05:15.690
But for our project, the widget controller is going to have a little bit more responsibility in that

05:15.690 --> 05:21.960
it'll handle button presses and information that the player will provide and actually send signals out

05:21.960 --> 05:22.680
to the model.

05:22.680 --> 05:29.580
So the model can make changes with the model view controller architecture, we have three separate concerns

05:29.580 --> 05:32.550
and each domain is isolated from the others with.

05:32.550 --> 05:34.890
Which makes the system highly modular.

05:35.130 --> 05:39.750
It prevents us from hard coding dependencies that would render the system rigid.

05:40.230 --> 05:46.260
Our model shouldn't ever need to care about which controllers or widgets are being used to represent

05:46.260 --> 05:47.140
their data.

05:47.160 --> 05:51.480
It's the controller itself that depends on the classes in the model.

05:51.630 --> 05:56.820
The controllers should never need to know which widgets are receiving data broadcast to them.

05:56.820 --> 05:59.820
It's the widgets that depend on the controller.

05:59.820 --> 06:06.180
And if we maintain these one way dependencies, then the model can have its widget controller changed

06:06.180 --> 06:12.330
out for other widget controllers without needing to change any code in the classes in the model.

06:12.630 --> 06:18.510
Likewise, the controller shouldn't need to know what types of widgets the system has as it's the widgets

06:18.510 --> 06:20.190
that depend on the controller.

06:20.220 --> 06:26.100
This way the controllers can have their widgets switched out as well without changing any code in the

06:26.100 --> 06:26.990
controller.

06:27.000 --> 06:30.930
And now we have a code base that's flexible and well coded.

06:31.320 --> 06:37.560
This is the type of system we'll design for this game project and we'll see the benefits of such a system

06:37.560 --> 06:40.080
as our project grows in complexity.

06:40.110 --> 06:46.320
Our controller can be a simple object and we'll give it the ability to harvest data from the system

06:46.320 --> 06:48.420
and broadcast it to the widget.

06:48.420 --> 06:54.360
And we'll create a subclass of the user widget that will be compatible with our widget controller class.

06:54.850 --> 06:59.950
So our next steps are to create this architecture for the UI in our game.

06:59.980 --> 07:05.920
We'll want our own custom base widget class, which we'll call you, or a user widget.

07:06.130 --> 07:12.460
We'll make the widget controller class you or a widget controller, and we'll want to subclass the HUD

07:12.460 --> 07:18.340
as well so we can have a location where these classes can be constructed and initialized.

07:18.860 --> 07:24.530
Once we have the system in place, we can go about harvesting and broadcasting data in the widget controller,

07:24.530 --> 07:30.470
receiving it in the widgets we create that can display visuals in the view and we'll be able to see

07:30.470 --> 07:33.350
the health and mana attributes in our game.

07:33.560 --> 07:35.690
So we'll do these things next.
