WEBVTT

00:06.900 --> 00:07.980
Welcome back.

00:08.010 --> 00:12.990
Our widget controller is now capable of broadcasting initial values.

00:13.080 --> 00:20.100
We know that we can cast our attribute set to an aura, attribute set and access those attribute values

00:20.100 --> 00:22.080
with those attribute accessors.

00:22.080 --> 00:29.400
That's great, but we're going to want to be able to respond to when those attributes change and the

00:29.400 --> 00:34.230
ability system component has a function for doing just that.

00:34.290 --> 00:35.580
It looks like this.

00:35.730 --> 00:44.070
We take the ability system component pointer and we call get gameplay attribute value change delegate.

00:44.070 --> 00:48.660
This function needs to know what attribute we're talking about.

00:48.690 --> 00:52.230
Well, we could always get that from aura attribute set.

00:52.230 --> 00:58.770
If we're talking about the health attribute, we'd take aura, attribute set and call get health attribute

00:58.770 --> 01:01.740
that returns an if gameplay attribute.

01:01.740 --> 01:03.990
That's what this function requires.

01:03.990 --> 01:09.760
So this returns the delegate and if we want we can bind to that delegate.

01:09.760 --> 01:18.910
It returns an on gameplay attribute value change delegate and to bind to it we use the dot operator

01:18.910 --> 01:22.960
and we use the function add you object.

01:22.990 --> 01:30.640
Now, if this were a dynamic multicast delegate, we could use add dynamic, but gameplay attribute

01:30.640 --> 01:39.040
value change if we right click and go to declaration or usages and then right click on this gameplay

01:39.040 --> 01:44.380
attribute value change and go to its declaration or usages.

01:44.380 --> 01:50.140
We see that it's a multicast delegate, it's not a dynamic multicast, so we can't use Add dynamic.

01:50.140 --> 01:57.460
We have to use Add you object and to bind a callback to it, we pass in this followed by the callback

01:57.460 --> 02:05.620
function and the callback function has to have a specific signature to be able to be bound to this delegate.

02:05.620 --> 02:09.220
So we really need to create a function to bind to it.

02:09.220 --> 02:12.970
And so that's one of the next things that we need to do.

02:13.150 --> 02:21.520
But really before we do that, binding callbacks to the dependencies of this widget controller is something

02:21.520 --> 02:23.770
that all widget controllers need to do.

02:23.980 --> 02:29.560
So we're going to make a function that we can use to bind our callbacks to all those dependencies.

02:29.740 --> 02:33.370
Let's add that to our Aura widget controller.

02:33.400 --> 02:38.950
That's the parent class, and that way all widget controllers can implement that function.

02:38.950 --> 02:45.580
So I'm going to make it a virtual void function and I'm going to call it bind callbacks to dependencies.

02:47.500 --> 02:51.670
So this will be a very important step that our widget controllers have to go through.

02:51.850 --> 02:57.190
I'm going to generate the definition, but leave it blank because I want my overlay widget controller

02:57.190 --> 02:58.750
to override it.

02:58.780 --> 03:03.340
So here an overlay widget controller just under broadcast initial values.

03:03.340 --> 03:11.140
I'm going to override virtualvoid, bind callbacks to dependencies and go ahead and generate the definition

03:11.140 --> 03:11.830
here.

03:11.830 --> 03:15.790
And I don't care about calling super in this case.

03:15.790 --> 03:22.660
I'm just going to bind callbacks here and we need a callback that we can bind to that delegate that's

03:22.660 --> 03:27.640
broadcast whenever our attributes change, such as health and max health.

03:27.640 --> 03:31.630
So I'd like a callback function for each of these.

03:31.630 --> 03:36.820
So let's go to our H file and I'm going to make these protected.

03:37.660 --> 03:39.820
They're going to be void functions.

03:39.820 --> 03:42.850
And for health, I'm just going to call it health changed.

03:43.390 --> 03:49.760
Now here's the signature that it has to have to bind to those delegates on the ability system component.

03:49.790 --> 03:56.870
It has to be a const reference to F on attribute change data.

03:56.990 --> 03:59.900
So we have a const reference, we're going to call it data.

03:59.990 --> 04:04.070
So I'll have one for health changed and I'll have one for max health change.

04:04.070 --> 04:11.420
So I'll go ahead copy and paste that and change it to max health changed and we can create definitions

04:11.420 --> 04:12.800
for these.

04:16.560 --> 04:25.320
Now these functions have a signature that qualifies them to bind to the delegate that is broadcast when

04:25.320 --> 04:26.790
an attribute changes.

04:26.820 --> 04:29.960
And so we'll do that here in bind callbacks to dependencies.

04:29.970 --> 04:36.540
So I'm going to take my line here where we're getting our attribute set and casting to our attribute

04:36.540 --> 04:38.280
set as I need that.

04:38.280 --> 04:45.960
And after that I'm going to take the ability system component and call get gameplay attribute value

04:45.960 --> 04:51.330
change delegate passing in the attribute that I want to bind a callback for.

04:51.360 --> 04:53.190
So first I'll do it for health.

04:53.190 --> 04:58.290
So I'll get aura attribute set and call get health attribute.

04:58.590 --> 05:02.130
So this whole expression here returns that delegate.

05:02.130 --> 05:10.080
So I'm going to use the dot operator here and call add you object passing in this for the user object

05:10.080 --> 05:18.550
and the address of my health changed function callback fully qualified with the class name here like

05:18.550 --> 05:19.270
so.

05:19.270 --> 05:24.900
And now whenever the health changes, this function callback will be called.

05:24.910 --> 05:25.900
Now that's a lot.

05:25.930 --> 05:27.250
All on one line.

05:27.250 --> 05:29.050
If you want, you can break it up.

05:29.080 --> 05:33.850
You can say put an enter there and there.

05:33.850 --> 05:35.830
If you want to do that, you can put it.

05:35.830 --> 05:37.690
Enter there and there.

05:37.690 --> 05:38.650
Put a new line.

05:38.650 --> 05:39.790
It's up to you.

05:39.790 --> 05:45.790
I'm going to go ahead and organize it like this on two lines.

05:45.790 --> 05:48.050
I think that's enough for me.

05:48.070 --> 05:50.320
And there we have it.

05:50.320 --> 05:56.680
So I've bound health changed to this delegate for when our health attribute changes.

05:56.680 --> 06:04.420
So really it's this part here the input for get gameplay attribute value change delegate.

06:04.450 --> 06:11.890
This is the attribute we specify and then this is the callback that we specify specifically.

06:11.890 --> 06:17.560
So if I want to do this for max health change, I can copy these lines, paste them here and instead

06:17.560 --> 06:24.460
of get health attribute, I can call get max health attribute and instead of health change I can use

06:24.460 --> 06:27.160
my callback that I called max health changed.

06:27.940 --> 06:31.920
So now these functions will be called when the attributes change.

06:31.930 --> 06:34.690
So what do we want to do when the health changes?

06:34.720 --> 06:40.930
Well, I just want to broadcast my on health change delegate so my widgets can respond to it.

06:40.930 --> 06:43.000
So I'm going to broadcast it there.

06:43.030 --> 06:47.590
Now, I don't need to access it from aura attribute set.

06:47.620 --> 06:50.700
I actually have that information here in data.

06:50.710 --> 06:59.980
So in order to get the new value from data, I can take this broadcast call and pass in data dot new

06:59.980 --> 07:00.700
value.

07:01.000 --> 07:05.740
And that's how we get that new value that has just changed for the attribute.

07:05.770 --> 07:08.530
Now writer says this can be made const.

07:08.530 --> 07:11.980
So let's listen to writer and why not?

07:12.010 --> 07:13.960
We'll make these functions const.

07:15.630 --> 07:19.170
That means we need to put const here on the definitions as well.

07:20.820 --> 07:23.220
Now for Maxhealth change, we'll do the same thing.

07:23.220 --> 07:24.390
We'll take this line.

07:25.040 --> 07:28.280
Paste it here, except instead of on health changed.

07:28.310 --> 07:34.280
We're going to broadcast the on max health changed broadcasting data new value.

07:34.310 --> 07:40.760
So now whenever health and max health attributes change, these delegates will be broadcast and our

07:40.760 --> 07:45.770
widgets are already bound to on health changed and on max health changed.

07:45.920 --> 07:51.290
At least our health globe widget is bound to these so we can test this out.

07:51.320 --> 07:57.380
We know that our health potion adds to our health and if we go to our attributes set and instead of

07:57.420 --> 08:03.860
emitting our health to 100, we can emit our health to 50, for example, and leave our max health at

08:03.860 --> 08:04.490
100.

08:04.520 --> 08:09.890
That way our health globe will start off half empty or half full, depending on whether you're an optimist

08:09.890 --> 08:10.910
or a pessimist.

08:10.910 --> 08:18.140
And then once we pick up the health potion, we should see that health globe go up to 75% because our

08:18.140 --> 08:21.170
health potion adds 25 to our health.

08:21.820 --> 08:25.780
So tying this all together is going to be your quest.

08:25.810 --> 08:32.950
We never actually called bind callbacks to dependencies, so you're going to need to call that function.

08:32.950 --> 08:36.190
So you need to think about where this should be called.

08:36.220 --> 08:38.980
When is it appropriate to call this function?

08:38.980 --> 08:44.860
Once you've called it, you can play test, go pick up a health potion and see if that health globe

08:44.860 --> 08:48.520
changes in response to the attribute change.

08:48.520 --> 08:52.120
So pause the video and conquer this quest now.

08:55.480 --> 09:01.600
Okay, so the question arises, where do we call bind callbacks to dependencies?

09:01.810 --> 09:07.120
Well, let's take a look at where we're calling broadcast initial values.

09:07.210 --> 09:10.000
That would be over here in the HUD.

09:10.030 --> 09:17.350
When we call init overlay, right, we're broadcasting initial values there, so you might have thought

09:17.350 --> 09:19.030
maybe I can call it there.

09:19.060 --> 09:25.480
Well, we also have get overlay widget controller, which is where that widget controller is constructed

09:25.480 --> 09:27.280
for the very first time.

09:27.310 --> 09:32.260
Now this will be called when we call get overlay widget controller.

09:32.260 --> 09:37.840
So if we place it in that function, those callbacks will be bound to the dependencies there.

09:38.140 --> 09:43.900
So I think that's a great place to put it and that's where I'm going to put that function call.

09:43.900 --> 09:51.280
So as soon as we set the widget controller params, we know that those key variables are set.

09:51.490 --> 09:54.820
As soon as those are set, I'm going to bind callbacks.

09:54.820 --> 10:03.590
So I'm going to take overlay widget controller and call bind callbacks to dependencies right here.

10:04.190 --> 10:06.980
Just before we return the widget controller.

10:07.310 --> 10:13.580
And then we know that the widget controller is callbacks will be bound so that when those attributes

10:13.580 --> 10:21.320
change or whatever other dependencies we bind callbacks to change, we'll get the change broadcast.

10:21.500 --> 10:23.810
So I'm going to run in debug mode.

10:24.590 --> 10:32.660
Let writer compile and we should see a half full health globe since we're now initializing health to

10:32.660 --> 10:35.300
50 and max health to 100.

10:35.330 --> 10:39.150
So I'm hoping to see a half full health globe here.

10:39.170 --> 10:40.160
I'm going to press play.

10:40.190 --> 10:40.810
There it is.

10:40.820 --> 10:42.400
It looks about half full.

10:42.410 --> 10:46.310
And if I pick up this health potion, it goes up.

10:46.310 --> 10:47.450
Look at that.

10:47.690 --> 10:48.770
Excellent.

10:48.770 --> 10:51.150
So that is looking great.

10:51.170 --> 10:56.330
We now have our health globe reacting to changes in our ability system.

10:56.330 --> 11:04.670
We can even double check by entering the console command show debug ability system and we can see that

11:04.670 --> 11:06.280
our health is now 75.

11:06.290 --> 11:15.190
It started at 50, but we picked up a health potion and now we have 75% as shown on the health globe.

11:15.200 --> 11:16.880
So this is looking great.

11:17.150 --> 11:26.220
Now, it seemed like a lot of work to set all this up, but now we have a class designed to handle controlling

11:26.220 --> 11:29.370
the widget data and retrieving it from the system.

11:29.550 --> 11:33.720
And the way we have it set up, our dependencies are all one way.

11:33.750 --> 11:39.840
Our ability system component knows nothing about the overlay widget controller.

11:40.020 --> 11:41.940
It's completely independent of it.

11:41.940 --> 11:47.160
An overlay widget controller knows nothing of the widgets that are bound to its delegates.

11:47.160 --> 11:49.170
They're completely independent of it.

11:49.290 --> 11:54.540
This is going to be a very powerful system as we'll see throughout this course.

11:54.540 --> 11:58.110
So excellent job and I'll see you in the next video.
