Welcome.
So our game project involves attributes such as health, and in nearly all game projects, health and
other important attributes are displayed to the player on the screen.
We refer to objects displayed on the screen as widgets.
And in Unreal we create widget blueprints to provide visual representations of game data.
Widget blueprints are derived from the base C plus plus class you user widget widget blueprints need
to receive data.
A health bar needs to know how much health to display.
An icon for a given ability needs to show the correct icon for that ability.
The point is that widget objects must receive data so they know the correct values to depict and the
game is rife with this data.
The attribute set contains numerical data for all of the attributes belonging to a given character.
The player state might contain a number of variables that need to be shown to the player on the screen
for any number of reasons.
There are numerous classes in the game, each containing data that may or may not need to be known by
the widget objects in order to show the player what's happening behind the scenes of the game mathematically.
So the question arises how should the widget object get that data?
There are a number of ways the widget object could manage to dig its hands deep into the game code,
retrieving pointers and references to the characters controllers player states, ability system components,
attribute sets and access all that data it needs directly.
But is this the best way?
As you're making your game project, the question should arise in your mind How should this type of
system be designed as the game grows in size and complexity?
How should this type of data be handled?
How would, say an experienced developer do it?
How do triple-A games do it?
That's what we're concerned with in this course.
How to do this in a scalable and maintainable manner.
Now, in a well structured program, we should have a separation of concerns.
With UI.
We have three different domains.
The first domain is the display of visual effects of the data, such as health bars and ability icons.
Basically all your widgets, we'll call this domain the view as it contains all the things the player
views while playing the game.
Now we also have the data itself.
These are the numerical values, the player's health, the player's level, mana experience, which
abilities have been unlocked, what their levels are and what buttons those abilities are assigned to.
All this data exists within the code base of the game project itself, and we'll call this data the
model as it models the underlying rules and results of the game.
This is the data that will ultimately drive the widgets that we will see in the view domain.
Now, getting data from the model to the view is a task we need to think about.
This can be done in a number of ways, but a good way to organize this is to have some sort of class
that can handle retrieving the data from the model and broadcasting it to the view.
This class can be responsible not only for the retrieval of the data, but any calculations or algorithmic
functionality involved in processing that data.
This class exists in a domain that we'll call the controller in this system, and the controller will
be responsible for retrieving data from the model and passing it to the view so it can depict data visually.
Now we're not talking about the a controller or a player controller classes in the engine.
Those are designed to possess and control pawns.
What we're talking about is a controller class used to drive data to the View.
So for that reason we'll refer to this as a widget controller.
This means the view can simply focus on how the data should look receiving the data from any broadcasts
made from the controller.
But the view may contain widgets that the player can interact with, such as buttons.
When the player clicks a button, that action may result in some change in the model, such as increasing
attributes or granting new abilities to the player.
So the controller's job is also to facilitate the actions resulting from the widget interaction by the
player causing changes in the model.
In other words, the controller is a middleman between the view and the model.
Now some implementations of this software architecture pattern are different than others.
Sometimes the widget controller is only responsible for retrieving data from the model and presenting
it to The View.
But for our project, the widget controller is going to have a little bit more responsibility in that
it'll handle button presses and information that the player will provide and actually send signals out
to the model.
So the model can make changes with the model view controller architecture, we have three separate concerns
and each domain is isolated from the others with.
Which makes the system highly modular.
It prevents us from hard coding dependencies that would render the system rigid.
Our model shouldn't ever need to care about which controllers or widgets are being used to represent
their data.
It's the controller itself that depends on the classes in the model.
The controllers should never need to know which widgets are receiving data broadcast to them.
It's the widgets that depend on the controller.
And if we maintain these one way dependencies, then the model can have its widget controller changed
out for other widget controllers without needing to change any code in the classes in the model.
Likewise, the controller shouldn't need to know what types of widgets the system has as it's the widgets
that depend on the controller.
This way the controllers can have their widgets switched out as well without changing any code in the
controller.
And now we have a code base that's flexible and well coded.
This is the type of system we'll design for this game project and we'll see the benefits of such a system
as our project grows in complexity.
Our controller can be a simple object and we'll give it the ability to harvest data from the system
and broadcast it to the widget.
And we'll create a subclass of the user widget that will be compatible with our widget controller class.
So our next steps are to create this architecture for the UI in our game.
We'll want our own custom base widget class, which we'll call you, or a user widget.
We'll make the widget controller class you or a widget controller, and we'll want to subclass the HUD
as well so we can have a location where these classes can be constructed and initialized.
Once we have the system in place, we can go about harvesting and broadcasting data in the widget controller,
receiving it in the widgets we create that can display visuals in the view and we'll be able to see
the health and mana attributes in our game.
So we'll do these things next.