Welcome back.
So now that we have an aura widget controller, an aura user widget, we can now make some widgets based
on this or a user widget class.
So the first thing we're going to want is some kind of way to show our health.
That's what I'd like to start with.
So I'd like to make a widget designed to handle that.
Now for this project, I like health and Mana to be represented as globes.
If we go into assets and we check out the UI folder and go to Globes, we have a number of materials.
Notice that that's what these are our materials and we have an m flowing globe and an m I health globe.
Let's double click my health globe.
We'll see that its parent material is M flowing globe and this is a nice health globe that has clouds
swirling.
It kind of looks like red liquid and you'll see that we have a number of parameters as it's a material
instance with some parameters in it, and we're going to want to use this material.
I would like to use this as a health globe material, so I'd like to make a widget that can use this
in a sort of progress bar.
So what I'm going to do is I'm going to go into the content blueprints folder, right click and make
a new folder for the UI.
I'm going to call this UI, and here in UI, I'm going to make another folder.
And for this folder I'm going to place all my progress bars, including the globes that we use as progress
bars.
So in progress bar, I'll just call it Progress Bar without an S, I'm going to make a widget blueprint,
so I'm going to right click and go to user interface and choose widget Blueprint, but I'm going to
choose Ora user widget.
That way I'll make a widget blueprint that inherits from Ora user widget and has a widget controller
pointer.
So I'm going to select that and I'm going to call this BP underscore Globe Progress Bar.
So what I'd like to do is make use of inheritance.
Since I want both a health and a man, a progress bar in the form of a globe.
I'm just going to have a BP globe progress bar that these can both inherit from, and that way we can
have some features inherited and we can set other features manually.
So how are we going to use inheritance with widgets?
Well, what we can do is first we can determine what the size should be for this.
But I'd like the size to be something we can override in child classes just in case we need to do something
that's a sort of smaller progress globe.
So I'm going to make a size box.
So dragging a size box in.
We now have this box that right now fills the entire screen.
But if I change this from fill screen here at the top right to desired, I now have the ability to override
the size over here under the details panel under child layout.
We have width override and height override.
I can override this.
So for example, I can check these check boxes and set these two values that I want, such as, say,
250 pixels each for width and height, just as an example.
But if we want to be able to override this in child classes, well, how exactly can we do that?
Well, what we could do is we could create variables for the width and the height, and then we can
set those over in the graph territory.
So the size box I'm going to rename this to actually size box underscore root so we can treat this as
a sort of root widget here in Globe Progress Bar.
And if we go over to the graph, then we have these events here.
And the one I'm interested in here is an event pre construct.
Now this is similar to the construction script in regular actor blueprints in that if we change any
properties here on this blueprint, this widget blueprint, then this will be fired off.
Now I'm noticing I named this BP.
This should actually be BP.
I just like to have W for widget blueprint.
So I'm just going to really quickly rename this to BP.
So in this widget blueprint, this will fire off when we change something such as a variable.
Now what we can do is we can make variables for the width and height for that size box, that root.
So if I click plus under variables and create a new variable called box width and change this to a float
and then make another variable called box height and let that be a float.
Then we now have these variables that we can use to set the width and height of that size box.
So for example, if I compile this, I can set box width, I can give it a default value of 250 and
I can set box height.
I can give that a default of 250.
And then here in event pre construct, I can take that size box, that size box root that we have here
and I can set properties on it.
Now I need to come up here in the details panel and check is variable and compile so that back in the
graph I can see the size box root and drag it out and get it.
And what we can do is take size box root and we can call set width override.
And we can pass in our box width so we can get that pass it in and hook that up to event pre construct.
And we can also set the height as well.
So I'm going to copy size box root with control D and drag off of it and call the function set height
override.
If I call that, I can hook that up and I can drag out our box height and hook that in.
And now if we change these values, as soon as we change them, we should see that size change here
in the designer tab.
For example, if I go to box width and change this from 250 down to say 80 and go back to designer and
hit compile, now we see that it's skinnier, it has a width of 80.
So this is a nice way for us to just have variables that we can set and we can set these on child widget
blueprints that are based off of this widget blueprint.
And now we'd like to keep these nice and organized.
So I'm going to highlight these nodes and right click and collapse to a function.
That way we can update our box size all in a single function.
I'm going to call this function update box size.
And now our event graph is nice and organized, So this is sort of the pattern we're going to take to
inherit child widget blueprints from our base widget blueprint.
And this is how it's done in Fortnite.
As you can see, some GDC talks where they talk about how they do this in Fortnite and this is how they
do it.
Now we have a size box that determines the size for our widget and anything that's underneath it in
the hierarchy.
I'd like to stack things on top of each other, and to do that we need an overlay.
So I'm going to get an overlay and bring that up onto my size box root and I'm going to call this overlay
underscore root.
That way we know that this is sort of the root overlay and we can place things on top of it.
Now, I'd like several things.
I'd like a background image, something that can sort of be a ring or a frame for our health globe.
We know that this is going to be the progress bar.
Is this health globe, right?
So we're also going to want a sort of ring or a background.
Now we have plenty of ring assets.
If we go to assets and go to UI, we can go to rings and we have globe ring, globe ring.
There's two styles to choose from here.
Here's the globe ring texture.
And then we have a globe ring two, which is a little bit more pale.
So notice one has more saturation in the color, the other is a bit paler.
I'm going to just use the regular globe ring here, so I'd like to add an image here into our Globe
Progress bar, and I'm going to set it to that globe ring.
But this is also something I'd like to be able to override in child classes.
So what I'm going to do is first drag in the image.
I'm going to get an image and drag it on to the overlay route.
And this image is going to be our background image.
I'm going to call this image underscore background.
So our image background here is something I'd like to be able to set with a variable as well.
So what I can do is I can take this image background, I can go to horizontal and vertical alignment
and choose fill for both.
And I can also come into the graph tab and I can make a variable for the brush.
That's what we use for images in widgets is a structure known as the brush.
So I can make a variable here, I can click plus I can call this background brush and I can change its
type.
I can search for brush, and the type that I want is slate brush.
So I have a slate brush variable and I can use that to set the brush for the background here, which
means our background needs to be a variable.
So we're going to check that in the details panel, compile that and come back to the graph so we can
see that we have our image background.
Now already I'm starting to see that these are getting a little bit mixed up.
We have our variables and then we have our widgets that are exposed as variables from our hierarchy
here.
So I'd like to put these sort of in their own categories.
I'd like to have at least one category for the overridable variables.
So for the Glow progress bar, I'm going to select box width and come down here to the properties and
find category and change this from default.
I would like this to be in its own category.
I'm going to call this Globe Properties.
So now we have this globe properties and I can put box height and globe properties as well and I can
put background brush and globe properties as well.
So now we have the Globe properties and they're different from our widget variables that we have here.
Now I'd like to take my background brush and drag it out and select get and I'd also like to get my
image background, that widget that we exposed as a variable from over here in the designer tab.
This image background.
I'm going to take that image background and I'm going to call set brush.
Now calling set brush requires a slight brush structure for that.
I'm going to use background brush.
I'm going to drag that in and hook it up and select my background brush and scroll down to the background
brush default value.
And I can set this.
I'm going to choose that globe ring.
I'm going to search for globe ring and choose globe ring and compile.
And if I go back to the designer tab now I see the globe ring set.
So we're giving this base widget blueprint a default value for that globe ring here.
Okay.
And now that this is driven by a variable, if we inherit from this in a child blueprint class, we
can set that background brush and change that background if we like.
Now I'd also like to refactor this into its own function.
So I'm going to highlight these nodes right click and collapse to function.
And this can be called update background brush, and we have that encapsulated into its own function.
Now, in addition to a background, we want the progress bar itself.
So for the progress bar, I'm going to want well, a progress bar.
So up here in common here's progress bar.
If I drag that out, I can put it onto the overlay.
That's what overlays are good for is stacking things on top of each other and the progress bar itself
that can be set to fill horizontally and vertically.
And this progress bar is going to want a style.
Now, I want the style here to have a fill image.
If I expand fill image, here it is and I can set this to a default value.
Now I want to use my my underscore health globe.
That'll just be the default value here.
So my health globe will set that for the fill image.
And if I take my percent and drag it all the way up, I can see what it looks like when it's all the
way full.
Now, that doesn't look right, does it?
It looks completely black.
So we need to find out why.
Well, if we scroll down here in the details panel for one, here's a fill color and opacity.
I'm going to want that set to completely white.
So I'm going to open the color picker and bring the saturation all the way down and click okay, so
that's better.
But it doesn't look like a globe, does it?
So we're going to scroll all the way back up to fill image, and here's what we want to do.
If we want to show this as it looks here in our health globe, what we have to do is right here under
draw.
As we have to change this from box to image, if we change that to draw as image, well, now this is
what it looks like.
It looks like it does in our material instance, and that's what we want to use now for the background
image.
I don't want that gray there.
So what I'm going to do is expand background image and under tint I'll actually open that color picker
and drag the alpha down to zero and click okay.
So now we have really nothing for the background, which is what I want as I already have a background
image.
I don't really want a background for the progress bar itself, and if I drag the percent down, there's
nothing there.
That's what I want.
Now.
Later we'll have a second progress bar that will trail behind this one as it's changing, but we'll
get to that later.
For now, we're concerned with setting up the progress bar itself.
Now notice when I drag the percent down, we're going from left to right.
I'd like this health globe to fill from top to bottom.
So here, under progress, I'm going to change bar fill type from instead of left to right.
I want to fill bottom to top.
So as we start running out of health, it goes down like that.
And as we go up, then we go up to the top.
Okay.
Looking good.
Now we have a couple of issues, right?
For one, we need some padding.
We want that health globe to be a little bit padded so it's not covering the ring.
But also I'd like to be able to set this progress bar image, that material instance in child classes
so that way we can change what it looks like and maybe we can make a child that takes a blue health
globe material and we can use it for mana.
So I'm going to take the progress bar and check is variable.
Go ahead and compile and come back into the graph.
And I see that it's called Progress Bar for 16.
So actually I'm going to rename that to Progress bar underscore Globe.
I think that's a better name for it.
And in the graph we'll drag out Progress Bar Globe And what do we want to set?
We want to set our fill image.
We're going to drag off and we're going to type, style and choose set style.
Now, why did we choose style?
Well, all of this stuff under style has to do with what it looks like.
We have the background image, we have the fill image.
We're interested in having a empty background image, and our fill image is going to have a brush that
we'd like to set.
So what we can do here is we can drag off of the input for the set style and we can say make progress
bar style, and we'll make a structure that will satisfy this set node.
And then we can set these various properties such as the background image.
Now for the background image, we want an empty sort of zero alpha transparent image.
So I'm going to drag off of background image and choose make slate brush and we'll make a slate brush
structure here and expand it.
And that way we can choose these properties.
Now I'm going to get these two nodes out of my way.
I'm going to delete them.
And what I'm concerned with for background image here is setting my tint to a tint that has zero Alpha.
That's all we did here in the designer under style.
If we look at background image, we took our tint and we set its alpha to zero.
So I'm going to take the tint which is a slate color structure, drag off and choose make slate color.
And here I can choose a specific color.
I can open the color picker and drag the alpha down to zero, click okay.
And now I have a slate brush whose slate color has zero alpha.
That's the background image for the progress bar style.
So that takes care of the background.
But for the fill image, this I would like to have a variable that I can change, so I'm going to make
a fill image slate brush structure.
So I'm going to go to variable Click plus and this will be progress.
Bar fill image.
And I'm going to drag that in and set that for the fill image, and I'm going to compile and come down
here to progress bar fill image and set this image to my underscore health globe.
Now whenever we call set, I can compile and see, well, it's set to this red my health globe.
But if I come back in here and change progress bar fill image to maybe a different color.
If I search for perhaps my manage globe and compile and come back to the designer, I see that it's
now blue.
So changing this value for the variable is what's going to change what our health globe material looks
like.
Now I'm going to take that progress bar, fill image and set its category to globe properties.
So it's in here with our other variables.
And I'm also going to, of course, collapse it into its own function here.
So I'm going to highlight all of this right click Collapse two function and this one will be set globe
image.
And now we have that function.
And if we change our globe image, that's going to change it here for our widget.
Now we do want some padding, don't we?
So if I take my progress bar globe, get that?
How are we going to set the padding?
If we search for padding, we see set border padding.
But if we look in the designer, we see this padding here is under slot overlay slot.
So if I drag off and type in slot and we get slot as overlay slot, now we have the overlay slot object
reference.
And if we drag off of that and type padding, now we see that we can set the padding directly here and
this is a margin structure.
If we drag off and choose make margin, we'll make one of these structures and we have left, right,
top and bottom, and we can set the padding here.
So what I'd like to do is make these variables that we can set and then in child classes, we can override
them if we want.
Now what values do we want the defaults to be?
Well, we can just set padding here to say five.
Nope, that's not enough.
We can set it to eight.
Almost good enough.
Let's do nine.
Maybe set it to ten and I think ten is looking pretty decent.
So ten is a good default value.
So it's up to us if we want individual left, right, top and bottom, or if we just want one value
to set them all to the same one really doesn't matter.
For now, I'm going to use a single value.
If in the future we decide we need these all for separate variables, we can do that.
But for now I'm going to drag off of one of them left.
I'm going to promote a variable and simply call this globe padding.
It's the padding for our globe.
I'm going to set its category down here to Globe Properties and I'm going to use globe padding for all
four of our parameters for make margin.
And that's going to be the margin that we use to set our padding.
Now, hooking this up and compiling, we see, well, it looks like we have zero padding, right?
That's because globe padding has a value of zero.
But if we set it up to ten and compile and look, there we go.
We have a padding of ten.
So now we have a parameter to set our padding.
So let's go ahead and collapse this to a function and call this update globe padding.
And since all of these are called update except for set globe image, I'm going to change this to actually
update globe image.
So we're consistent and we have our update functions being called here.
Now, these are for before the game starts, right?
So this is just all for configuring how this is supposed to look as we're building our widgets, right?
It's not really for changing at runtime or anything like that.
Okay.
So that's almost everything.
There's one last thing I'd like to do, and that is that when our globe is getting low, when our percentage
is dropping for our progress bar, I'd like there to be a sort of glare, a bit of a glass reflection.
So it looks like we have an actual glass globe here.
So that's essentially going to be an empty globe material.
For that, I'm going to drag in another image onto my overlay route.
I'm going to rename this to Image Underscore glass.
We'll just call it glass for lack of a better name.
And I'm going to set horizontal and vertical alignment to fill and we're going to set that image.
So let's go back into our event graph.
We actually need to check is variable, right?
And come back in here and compile.
And then we have our image glass.
Let's drag that out.
And just like we did with our update globe image, right?
Remember, we had to have a slate structure.
We're going to want a slate variable to update our image glass and we're going to call set brush.
So calling, set brush and we'll make a variable for that brush for the glass.
So I'm going to click plus call this glass brush without typos.
I'm going to remove that typo and it's a slate brush.
I'm going to hit compile so I can give it a default value.
We'll get an error because I don't have anything plugged in there.
We'll fix that shortly.
But for Glass Brush, there exists a material instance in this project called My Empty Globe.
I'm going to choose that and I'm going to drag in glass brush, get it and set our brush.
And I'm also going to set this glass brush category to globe properties.
So it's in there with my variables.
I'm going to compile, go back to designer and there's the glass brush and I can really see it if I
select my progress bar and drag that progress percent down, you'll see that there's the glass brush
and we kind of want that to have some padding as well, don't we?
So let's take that image glass and experiment with padding values.
I'm going to hit a five.
Seems a little low.
Let's try.
Eight is a little too high.
Six looks pretty good.
Maybe five is actually pretty good as well.
If I drag that percent up, I want these to overlay with each other.
I don't want to see a sort of trail or ghost image, so I'm going to actually try a value of four,
six, seven, eight.
I think eight looks good, maybe even nine.
Maybe it is ten, maybe ten.
Yeah, ten is going to be it.
So ten is going to work.
So image, glass padding, ten we're going to create a variable for that.
So we're going to take our image glass and we're going to do what we did for the padding.
Update globe padding here.
We're going to get the slot as overlay slot and call set padding.
So take image glass, drag off slot as overlay slot.
And we're going to call set padding.
We're going to take in padding, drag off, make margin, and we're going to make a new variable for
our padding.
And it looks like actually we're using ten for both of these.
For now, I'm just going to use the same globe padding.
And later, if we make a child that uses a different material and for some reason we need a different
globe padding for the glass, we can change it then.
But for now it looks like we can use the same one.
So that's going to look good.
We can compile and look.
It's looking good.
And as we drag that percent down for the globe.
Then we still have.
That sort of glass look and it's a little heavy, which means I might want it to have a bit less of
an alpha.
I might want the alpha to be turned down a little, which means I can take my fill color and opacity
and bring it down a bit.
Actually, not this one.
This is the progress bar I want to get.
Image, glass.
And for this image I want to take color and opacity and bring that opacity down to about 0.5.
Now, if I want in the future, this could be a overrideable parameter.
For now, I'm just going to set it to 0.5 like this and just experiment with our percent bar and see
that that looks pretty good.
Okay.
So last things last.
We're going to take our set brush and collapse this into a function and call this update glass brush
and we're going to collapse this one into a function.
And call this update glass padding.
And now all of our functions are nice and tidy for our globe Progress bar.
And this is great because now we can make child blueprints based on this and all we have to do if we
want to change its size or its images, its progress, bars, the materials, all that good stuff.
Those are parameters that we can change.
So in the next video, we'll go ahead and make our actual health and mana progress bars based on this
parent class and we'll see how easy it is to inherit those.
So great job and I'll see you soon.