Welcome to your next quest.
In this quest, I'd like you to replace the callbacks in our overlay widget controller with Lambdas.
So we have some callbacks for when our attributes change and we're binding those to delegates on the
ability system component.
But I'd like you to actually get rid of those callbacks and instead use lambdas inside of which you're
going to make those delegate broadcasts to the widgets.
So pause the video and conquer this challenge now.
Okay.
So for this quest, we're going to replace some callbacks in the overlay widget controller.
I don't really need gameplay tag container, so I'm going to close those files.
And here we have our callbacks health change, Max, health changed and so on.
And all these functions are doing is broadcasting some values with our delegates.
And by the way, I'm noticing something right here my on max health changed is an on health change signature,
not an on max health change signature.
Something from copy pasting, I think so I'm going to take my on max health change signature and just
replace that there.
Now the reason it still worked is because this is a separate variable than this and they're both just
delegates that can broadcast a float.
So really there's no reason that we can't use the same delegate for all of our attributes and just create
a new variable of that same type for each one.
So maybe we'll refactor that here as well.
But for the task at hand, we need to get rid of these delegates and replace them with lambdas.
Now, the most important thing here is that our lambda has the correct signature.
Otherwise it can't bind to a delegate that requires this signature.
And that's a function signature with an input parameter of const reference to on attribute change data.
So I'm just going to copy that input parameter and I'm going to come back up to where we are binding
callbacks to these delegates.
And I'm going to start with the health.
And all we need to do here is instead of calling Add new object, we're going to call add lambda instead.
And the lambda goes right here inside of the parentheses.
So I'm going to put those each on new lines so we can put the lambda right here in between.
Now it's going to have square brackets, it's going to have parentheses and it's going to have a body.
And in the parentheses that's where we put what I copied, the const reference called data.
And I'm going to put the body on a new line so we can see the scope of this lambdas body quite easily.
And down here to health change.
All I want to do is broadcast my on health changed delegate.
So I'm going to paste that in.
Now of course I get the red squiggles because it says this is not captured.
Remember, the capture goes into the square brackets and we can capture this and that's going to take
care of it.
Now the cool thing is, while, yes, I put these all on a bunch of different lines, this is all very
compact.
We could put this all on a single line and keep this really nice and neat if we want.
Here's what it looks like if you do that.
We'll just go ahead and delete the empty space.
Like so.
And one more thing that closing parentheses there.
So here's what it looks like on a single line.
Now, as you can see, we have quite a few tokens just bunched up.
So I prefer not to do that.
But if you wanted to, you could.
So I'm going to hit Control Z a few times until it gets back to how it was.
And I think that's it.
So we're good.
And now our callback health changed is obsolete.
We don't need it.
I'm going to remove it.
And I'll remove it from here as well.
So this is a nice way to clean up our widget controller.
Right.
So we can do the same thing for our maxhealth.
So I can copy this being extremely careful because copy and paste can be dangerous.
So we're going to go through the entire line.
We see that we're getting the health attribute.
We want to get max health attribute and we're adding a lambda.
And what we want to broadcast is on max health changed like so.
So we're done with this one and we're done with Max health changed.
We don't need that and we don't need the declaration as well.
We'll delete that.
Okay, so two more we want manage changed and Max manage changed.
So I'm going to copy this and we have to change the getter for the attribute we want get mana attribute
and we want to change the delegate.
We want on mana changed.
And then last one.
It's going to be get max mana attribute and on max Mana changed and we can get rid of these lines where
we're binding callbacks instead we're now binding lambdas and we can get rid of these callback functions
altogether so we'll get rid of them.
Okay, so we've just reduced the amount of code quite a bit.
And again, we could make this four lines of code right here if we wanted to.
It doesn't have to take up this much space, but I prefer to be able to kind of see what's going on.
So I'm going to leave it like that.
And now we see that thanks to Lambdas, we don't need callbacks.
We can just make an anonymous function that broadcasts a delegate for us.
This is kind of nice.
It's a little bit cleaner and I prefer this way for a lot of things.
And that concludes the challenge.
Now, before we wrap up, though, I'm going to go back to this issue where we have four delegates that
are essentially identical.
The only thing that's different is their names.
And down here, we're creating one of each kind to broadcast an attribute value.
And really, because these are all functionally identical, we don't really need a delegate for each
attribute.
In fact, this project is going to have more attributes.
They're going to grow in number.
So really, we don't need to declare a new delegate each time.
We can just use a single delegate.
In fact, I'm going to declare one here.
It's going to be called F on attribute changed signature.
And we'll call this float new value and then we can just have one of these for each of these instead
of each of them being a different type.
Each of these can all be the on attribute changed signature.
We can change them all to this and we can come back here and delete these four declarations.
And now we just have a single delegate capable of broadcasting a float.
That's all we care about our delegate being able to do.
And for some reason I think I've deleted a semicolon down here.
So I'm going to fix that.
And with that, I should make sure this all compiles because we've made quite a few changes here.
So compiling and the build succeeds because all of these broadcasts just take floats and they work.
But we're going to want to play test because when you make this many changes, you should really test
out your work.
But before we do take a look, our widget controller looks a lot better.
It's a lot cleaner.
We have less delegate declarations and we have less functions.
In fact, we have no callbacks at all.
We just bind lambdas.
So that's cool.
Let's hit the debug button and test it out.
All right.
So I'm going to press play, and pressing play is a good way to find out if we have some errors in the
blueprints.
I'm going to open all errored blueprints and my message log gives me links to where those errors are.
I'm going to click on the one for Health Globe.
And really, it's just because our delegate has changed.
All I need to do is right click and refresh nodes and make sure that those connections aren't broken.
And I have another one down here on Maxhealth changed.
We can refresh the nodes here.
And hook that up.
Compile again, and we're good.
Now that's the health globe.
Let's go to the Mana Globe and compile here.
Actually, I see the two errors, refresh nodes here and hook up.
Refresh nodes here.
And hook up.
Compile and we're good and we just need to play test.
I'm going to save all and then test and pick up mana.
We're getting Mana looks good.
Let's pick up health.
We're getting health.
Looks great.
And everything works.
Excellent.
So awesome job.
I'm proud of you for tackling the challenge.
It was a pretty good one and I'll see you in the next video.