Welcome back.
Now we're adding to some values and we have placeholder functions for others.
We actually are adding to the player level.
We're just not adding to attribute points and spell points.
We can see that in our character where we implemented these interface functions.
Add to player level actually calls, add to level on the player state attribute points and spell points
have to do's.
Now in the player state, since we have this level variable and it's replicated with a rep notify.
We know that when we set this on the server it will be replicated and if we take a look at the CPP file,
when we add to the level we're broadcasting a delegate, we're broadcasting the level with on level
change delegate and in the rep notify we're broadcasting it there as well.
And this delegate is designed for our widget controller to respond to it.
So if we go to UI, widget controller and overlay widget controller, I'm going to go in the private
folder.
Actually we can see where we're binding to our delegates and so far we're only binding to on exp change.
We're not binding to on level changed yet.
So that's something that we'll have to take care of.
Now what do we want to do when our level changes?
Well, I'd simply like to pass that on up to a widget.
Now, we haven't created that widget yet, but we'd like to pass that on up by broadcasting a value.
Now, overlay Widget controller has a number of delegates for broadcasting things.
One is for when an attribute changes.
We're reusing that for our exp bar we have on exp percent change delegate.
Now I'd like a delegate to broadcast when our level changes as well.
In fact, we'd like a delegate to broadcast when any integer value changes.
That's our level, our attribute points, our spell points and so on.
Now we could just keep reusing on attribute change signature, but really these are not attributes.
Even our exp percent is not an attribute.
Now I'm okay with just reusing this delegate for on exp percent change because the percent for the exp
is a float.
It's a ratio, but for attribute points, spell points and level.
I'd like to broadcast an integer and I'd like a delegate designed to broadcast that.
So I'm going to declare a dynamic multicast delegate one param, but this one is going to be for player
stats rather than attributes.
So I'm going to call this F on player stat changed signature and this is going to use an int 32 instead
of a float and we'll make an on player stat changed delegate.
So we'll use on player stat change signature and this one will be for player level so we'll say on player
level changed delegate.
We can give it blueprint assignable category gas and instead of XP, we'll say level and we'll broadcast
this in response to the player level changing.
So in bind callbacks to dependencies, we can bind and really I can just create a lambda for this so
I can take my aura player state access on level change delegate and call add lambda.
So for add lambda, I'm going to give myself some room here and as I always do when I make a lambda,
I make the square brackets, the parentheses and the function body and then give the function body its
own room.
And all I want to do is broadcast my new on player level changed delegate.
So I'm going to broadcast that here.
Now we need to broadcast a value right and on level change, delegate on the player state.
If we look at that, it's an on player state changed and if we look at that delegate it broadcasts it
in 32.
So to bind to this we need a callback that takes an int 32.
So our lambda should take an int 32 called new level.
And of course we're using on player level change delegate, which means we must capture this and we're
going to broadcast new level.
And now we can receive that in any of our widgets.
So the last step is to create a widget that can receive this delegate broadcast.
And we're going to do that now.
I'm going to go ahead and run in debug mode.
So we need a widget to show our level.
Now if we go into blueprints ui spell globes.
The spell globe would be kind of nice.
It'd be great if we had something like this that just shows our player level.
But the spell globe is kind of specific to spells.
It receives ability info with this delegate, so it kind of has all this other stuff that we don't need.
It waits for cooldown, changes.
It's kind of overkill.
But other than that, it's almost exactly what we want.
So I'm going to go ahead and copy this now.
I could go and make a parent widget blueprint that contains, say, the ring and the glass and then
repair and spell globe.
I'm not going to bother with any of that.
This is just going to be a separate blueprint.
So I'm going to duplicate it and call this one WB underscore value globe because I'd like this to just
have a value.
So I'm going to close spell globe and open value globe and this is going to be the same only it's going
to have a lot less stuff in it.
It's going to use the overlay widget controller.
Yes.
So we do want that part.
But instead of binding to the ability info delegate, we're not going to do that at all.
So I'm going to remove that whole part there.
Instead, we're going to bind to a different delegate.
We're going to bind to on player level change delegate, and we'll do that soon.
But first, let's clean up this widget and take everything out that we don't need.
Now, for one, we don't need a spell icon, so I'm going to delete that.
I do want the glass.
I do want the ring and I do want the text for the cooldown.
In fact, I want my text to have its render opacity set to one so I can see it.
So I'm going to set that to one and I'm going to go into the graph and make sure we're not hiding that
cooldown text.
I'm going to delete the call to that.
We're also calling Clear Globe, which is setting the image spell icon a variable that no longer exists
and setting the image background to the transparent brush.
We don't even need to call Clear Globe, do we?
We also don't need to update the spell icon brush because we don't have a spell icon anymore, so I'm
going to delete that.
In fact, I'll delete that whole function.
Update spell icon brush.
We can keep update globe padding, although I should check to make sure we're not using something that
doesn't exist anymore.
That's that spell icon.
We can remove that, but we're setting the glass and the image background padding so we can keep that.
We're updating the ring brush.
That looks good and we're updating the box size.
We want to keep that as well.
So we're keeping everything else.
Now over here in our functions.
Let's see if there's anything we don't need.
We do need update box size ring brush glow padding set background tint could be useful as we may choose
to give this a background and set it to a dark tint.
Clear Globe is just setting the background to a clear, transparent brush.
I don't really see a need to delete that.
We have set icon in background which sets the brush for the icon.
We really don't care about that and we can set the image background if we want to.
So I'm going to remove these for the image spell icon.
And we'll just call set brush here.
We don't need icon brush.
No worries.
We won't use that.
We don't need receive ability info.
That's a function that we're not going to use.
And it also uses an input tag and a cooldown tag.
Things we don't need.
So I'm going to delete input tag.
Yes, I know it's in use.
I do really want to delete it.
I'm going to check.
Don't show this again and click.
Yes, I'm going to delete cooldown, tag time remaining cooldown int timer frequency cooldown, timer
handle wait cooldown change and I can delete receive ability info.
We can just delete that whole function and I'm going to go back and rename the text from text cooldown
to text value.
All right.
So we're gutting out this whole thing almost and we can set the default value for this text to one and
see what it looks like with that value.
And in fact, I'm going to make its size bigger.
We'll try 36.
We'll see a two digit value in here, too, and make sure that's not too big.
That looks good.
And I'd like my background to have an image and we're updating our background.
We're actually not anymore, but we have a function called set icon and background.
I'm actually going to change this to simply.
Update background.
And remove the icon brush as an input.
And now we just have something that sets the background brush, and we'll call that an event construct
as well.
So we'll have update background here.
And this actually should just use a variable in our globe properties for the background.
We don't need spell icon brush anymore, but we can rename this spell icon brush variable to background
brush.
And we can use that.
But no need for this to actually be an input parameter.
We can just use background brush directly in this.
And remove that input parameter as well.
Okay.
And now we're updating the background.
So if we change the background brush, then we should see it in our designer tab.
Now if I type globe.
And I select em Flowing globe, for example.
We'll see that here.
But I'd rather use something a little bit less colorful, like, am I locked?
BG I'm going to set that.
So for background brush, I'm going to select it and set it to my locked BG.
And now we see what it looks like.
But I'd also like this to be a little bit darker, too.
So I'm going to set the tent and that's why I kept that function set background tint.
I'm going to set that here in event pre construct and just set it to 0.1 and see what that looks like
compiling.
That looks pretty cool.
Alternatively, I may want it a little bit darker.
0.01.
Let's see what that looks like.
Almost black.
So we can play with the tent here, but alternatively, we can also change this.
Am I locked BG now?
Am I locked?
BG.
Is made for a specific purpose.
It's going to be used for locked spells in our spell menu once we create that.
So I can just duplicate this.
And call this one my level.
BG And we'll use this one instead if we want to change it.
So changing this to my level.
BG Now I can change level.
BG without changing the other one locked.
BG So I'm not going to set the background tint.
Instead, I'm going to play around with the material instance.
And I need to make sure my background brush is set to the correct one.
Not in my locked BG, but am I level BG?
So compiling, making sure the image background has my level bg.
Now I can mess with my level.
BG.
Now we have a cloud darkness.
We can adjust that.
If we make it lower, then the clouds get brighter.
If we make it higher, then we get sort of a little bit more washed out.
We also have a negative color that we can darken a bit.
And of course our color is white, but we can make the color itself darker so we can play with these
parameters a bit until we have something that's looking a little bit darker.
We also have a perimeter shadow.
We can make that darker as well.
And then our speed, the speed at which these noise textures are panning, we can lower that to make
it look a little bit less turbulent.
And when we play with the darkness and make it contrasted more, sometimes it looks better with a lower
speed.
So negative color is pretty dark.
Color itself is going to be pretty dark and my perimeter shadow is pretty high.
So I'm going to save that and see what it looks like here.
And I think that's looking pretty good.
So tweak that to your heart's content.
I might actually raise the color and up that perimeter shadow even more.
I think I like how this looks.
And you don't have to make that color completely desaturated either.
You know, it could be red, although red kind of looks like our health globe.
It could be purple.
It could be a color that you haven't used.
Green kind of looks good.
Maybe we'll experiment as we go, but now we have something that can represent our level.
I'm going to make this a darker green, actually.
But anyways, enough tweaking.
For now.
We have something that can represent our level.
It looks cool.
We need it to respond to the delegate we created and our broadcasting.
It's called on player level change Delegate.
We're going to subscribe to that Delegate So let's get our BP overlay widget controller.
Type in on player level changed delegate.
Hook that up to our sequence and take our new value and we're going to set our text value here.
So taking text value calling.
Set text.
That function.
And for our level, we can take new value, plug it in.
We're converting from text to integer.
Compile that and save.
And we have a widget.
Now we just need to add this to our overlay so we can go to content blueprints, UI overlay, WP overlay,
and we can drag one of these in somewhere.
So I'm going to search for WP Value Globe.
We'll drag one in.
We're going to rename this to Value Globe Underscore level.
And we'll just have it up here for now.
And we need to set its widget controller, so we'll do that right after setting our other widget controllers
here.
So let's get our value globe.
I did not check his variable.
So now after doing that, we can bring it in.
We can call set widget controller.
And we can pass in our widget controller.
So that it's widget controller will be set.
And compiling and saving will save all.
Press play.
And we see our level there.
Now we need to test out when our level changes, of course, because right now we're just seeing its
default value and we could easily make ourselves level up quite quickly by changing the amount of experience
that one of our level one warriors gives us.
So we can go into ability system data and go to Exp, reward Warrior and choose level one that key and
change this to a higher value like 150.
Now we only have to kill two of these things to level up.
So let's see what happens if we do.
Pressing play will kill one of them.
And we have half of our XP bar filled up.
Let's kill one more.
And look at that.
Our level went up to two.
Now that's the only thing that happened.
Usually a lot more dramatic effects happen and we'll make all those happen.
But at least we know that our level is updating in the HUD and that looks great.
Now, usually we see a little something more than just a value like a number there.
There's usually something else in the overlay, like the picture, like a portrait of our character,
something like that.
So before wrapping up the video, I'd like to create another widget.
Not functional.
Doesn't listen for any broadcasts, just something that's a nice framed picture of aura like a screenshot.
Now if we click on all and filter by texture, we'll see.
Right up here at the top we have Aura render.
I can double click on it and here we have a nice portrait of aura.
I'd like to use this and perhaps even frame it.
Maybe even get a globe with a ring and a glass with her picture behind it.
I think that would look really nice.
So I'm going to go ahead and create another widget using Aura Render so I can remove that texture filter
and go to Blueprints UI.
And I'm just going to go into progress bar and get my Globe progress bar and steal that.
I'm going to duplicate it and call this one BP picture frame.
That's all it's going to be is a picture frame.
It's actually not going to be a progress bar.
So I can drag it out of the progress bar and I'll just put it straight into overlay the overlay folder
move here and here in overlay, I'll just drag it into sub widget and move their.
So we can start gutting out what we don't need here.
I'm going to go into the graph and first of all, we don't need globe percent set.
I'm going to delete that.
We don't need event tech.
We don't need to interpolate anything.
We don't need to update the ghost globe brush.
We'll keep the glass padding.
We'll keep the glass brush.
We don't need to update the globe padding or the globe brush.
We'll keep the background brush and the box size.
Everything else is unnecessary.
So over here in the functions, we'll see what we'll keep.
Update Box size.
Now, background brush.
That's something we're using, right?
That's our image background.
So we'll keep that.
We don't need update, glow brush or glow padding.
We'll keep glass, brush and glass padding.
We don't need to set progress bar percent.
We don't need to update the ghost glow brush or set the Ghost Progress bar.
Percent Now we see that it's in use.
Let's see where it is in use.
If we hit compile, we can click on this link.
Here we see that it's in Interp Ghost Globe.
We can just remove that function too.
And now we've gutted out everything we don't need.
We can come back to the designer and I typically save all before deleting these.
Sometimes they can cause a crash, but I'm going to delete those progress bars.
And we have this now we want a picture, so I'm going to drag in an image.
Right here and it can go beneath the glass.
And this image I'm going to call image underscore picture.
I'm going to set it to fill and I'm going to browse to Ora Render.
And set that for the picture.
And that looks pretty nice.
It's too bad the background on this picture isn't transparent because then we could use a flowing material
for that too, and that would look kind of cool.
But we have this nice picture.
Now we can use this in our overlay.
I'd like to just save this and go into our WP overlay and find our picture.
WPP.
Picture frame.
Now, I'd like to align both of these, so I'm going to select this one.
It's anchored to the top left, and so is this.
So I'm going to take this one and take its position X, copy it, take my picture, paste its position
X in.
And unfortunately, that means that their left sides are aligned, of course.
So what I'm actually going to do is set my picture frame almost all the way to the left will make it
ten, and my size X is to 50.
Half of that is 125.
Add ten to that, we have 135.
That's where I want this one to be, minus half of its size.
So if I take position X and put it to 135 and then take its size x, which is 100 and subtract 50 from
that one, 35 -50, that's 85.
So if I put in 85 now I know they're aligned.
Now I can take this one my picture frame and bring it up to the corner and take my value globe and bring
it down.
And actually, I'm going to put the picture frame behind it so that I can take my value globe and put
it in front like this.
That might look pretty nice.
Let's see how it looks in the viewport.
Yeah, I like that.
I think that looks nice.
We could put it up more and to the right a little bit, but we can move them together now.
So selecting them both, I can just click and drag.
And that looks pretty good.
I'm going to save all.
Yeah, that looks great.
Actually, I'm very happy with that.
We may have it brought in a little, but let's see how it looks.
Full screen.
F11 will full screen it actually like that.
I think it looks great.
We can open the menu.
The menu covers it almost completely.
I think it looks great.
And if we level up, we can see it go up to two.
Let's kill a couple of these things before I die.
There and it goes up to level two and it looks great.
I like it.
I like it a lot.
So I'm going to go ahead and wrap it up here.
We may just tweak one last little thing.
My value globe can have probably a bigger text size.
I might go up to 40, perhaps even oh, maybe 46.
And we can even have.
More of a yellowish color.
But this is all just tweaking at this point.
I think things are looking quite nice.
I'm very happy with that.
I might change the outline size to two.
All right.
Excellent job.
And with that, we'll wrap this up and I'll see you in the next video.