WEBVTT

00:06.840 --> 00:08.020
Welcome back.

00:08.040 --> 00:14.490
So now that we have our ability info data asset, we need to figure out how to get information to the

00:14.490 --> 00:21.870
widgets about which abilities we have equipped or given to our ability system component.

00:21.870 --> 00:26.760
So this is going to involve linking our ability system component with our widgets.

00:26.760 --> 00:30.230
And the middleman for that is our widget controller.

00:30.240 --> 00:32.280
So we're going to open our widget controller.

00:32.280 --> 00:38.430
And the widget controller for this overlay is our overlay widget controller.

00:38.430 --> 00:40.230
So let's go into that class.

00:40.410 --> 00:47.700
I'm going to go ahead and close all tabs for now and open up our public folder and we're going to go

00:47.700 --> 00:51.870
into UI widget controller overlay, widget controller.

00:51.870 --> 00:53.160
Let's get that open.

00:53.250 --> 01:00.780
In addition to this, I'm going to open up my ability system folder and go to aura ability system component

01:01.470 --> 01:02.340
as well.

01:02.370 --> 01:06.790
So these have to communicate somehow with each other.

01:06.790 --> 01:13.690
So how are we going to communicate which abilities we have, or at least when it's appropriate to get

01:13.690 --> 01:17.830
those abilities and look up their data from our data asset?

01:17.860 --> 01:23.770
Well, one way is to create a delegate we can broadcast from our ability system component.

01:24.040 --> 01:29.080
I'd like to broadcast a delegate for when our abilities have been given.

01:29.080 --> 01:37.780
Now this can be a regular, plain old delegate, but in case I want to bind to it from multiple different

01:37.780 --> 01:39.850
classes, it's going to be multicast.

01:39.850 --> 01:42.520
But I don't plan on exposing this to blueprint.

01:42.550 --> 01:46.420
We're just going to broadcast this so our widget controller can pick it up.

01:46.420 --> 01:55.030
So I'm going to declare a multicast delegate and I'm going to call this F abilities given.

01:55.420 --> 02:00.730
So F abilities given can be broadcast whenever we give our abilities.

02:00.730 --> 02:02.110
Let's create this.

02:02.110 --> 02:04.000
It's got to be a public variable.

02:04.000 --> 02:09.760
And I'm going to stick this right here under our other delegate f effect asset tags, and I'm going

02:09.760 --> 02:12.190
to call this abilities given.

02:13.460 --> 02:17.750
And to make it clearer, we could call this abilities given delegate.

02:18.290 --> 02:23.150
And I'm not going to bother renaming our asset tags in this way.

02:23.240 --> 02:28.110
I'd like to stay with the task at hand so we have an ability as given delegate.

02:28.130 --> 02:32.560
I'd like to broadcast this delegate when our abilities have been given.

02:32.570 --> 02:33.680
When is that?

02:33.680 --> 02:37.370
Well, let's go into our CPP file and find out.

02:37.400 --> 02:40.370
Right here we have Add character abilities.

02:40.370 --> 02:42.320
This is when we call give ability.

02:42.320 --> 02:48.440
So after we loop over all the start up abilities that have been passed in here, we know that our abilities

02:48.440 --> 02:53.180
have been given and we can broadcast that delegate abilities given delegate.

02:53.180 --> 02:55.700
So let's go ahead and broadcast that here.

02:55.700 --> 03:02.840
At this point, we know that our abilities have been given, and if we respond to this in our widget

03:02.840 --> 03:08.680
controller, we know that we can access those abilities on the ask ability system component.

03:08.690 --> 03:16.830
So what we'll do is go into our overlay widget controller and what function in this class do we need

03:16.830 --> 03:20.580
to use to bind to our new delegate?

03:20.580 --> 03:26.280
Well, bind callbacks to dependencies is the function where we're doing those things.

03:26.280 --> 03:32.760
So here in bind callbacks to dependencies, we have our ability system component, we can access it

03:32.760 --> 03:34.440
and bind to delegates.

03:34.440 --> 03:39.240
So what do we want to bind to on abilities given?

03:39.240 --> 03:45.180
Well, I'd like a function to bind to it and then we can bind it right here after we've bound to our

03:45.180 --> 03:48.090
other ability system component delegates.

03:48.090 --> 03:51.930
So I'm going to make a new function on my widget controller.

03:51.930 --> 03:58.110
It can be in the protected section and it'll be a void function that takes zero arguments.

03:58.110 --> 04:05.010
And I'm going to call this function on initialize startup abilities.

04:05.280 --> 04:12.000
So we'll call this as soon as we know that the ability system has given all of its startup abilities.

04:12.000 --> 04:19.470
So I'm going to generate a definition for this and bind this callback to our new delegate on the ability

04:19.470 --> 04:20.460
system component.

04:20.460 --> 04:24.750
So we're going to say ability system component.

04:25.980 --> 04:32.580
We're going to get that abilities given delegate or what was it called?

04:33.420 --> 04:35.970
Yes, it's called abilities given delegate.

04:35.970 --> 04:37.440
It's in the public section.

04:37.440 --> 04:42.840
And of course, we can't get this unless we cast to aura ability, system component.

04:42.870 --> 04:44.190
Now we're doing it here.

04:44.190 --> 04:47.790
So what this means is it's now time to have a local variable, right?

04:47.790 --> 04:57.090
So I'm going to make a you or a ability system component called aura ask and set it equal to the result

04:57.090 --> 04:58.350
of this cast here.

04:58.770 --> 05:06.480
And we can actually wrap this in an if so, we're going to say if here and inside the if we're going

05:06.480 --> 05:07.920
to use aura ask.

05:08.490 --> 05:14.370
So instead of casting and calling the function from that cast directly, I'm going to change this to

05:14.370 --> 05:15.390
aura ask.

05:15.720 --> 05:23.970
And then this goes all into our if statement right here like so and let's see if I can hit tab there.

05:23.970 --> 05:24.630
There we go.

05:24.630 --> 05:28.260
Now it's nice and indented and our ability is given.

05:28.260 --> 05:32.760
Delegate has to be accessed from the aura ability system component.

05:32.760 --> 05:41.710
So once we access that here, now we can bind and we're going to use Add you object as this is binding

05:41.710 --> 05:50.500
just to multicast delegate and we can bind using this followed by the address of our new callback,

05:50.620 --> 05:53.920
which is going to be this function here.

05:54.880 --> 05:58.630
So the fully qualified on initialized start up abilities.

05:59.560 --> 06:00.040
Okay.

06:00.040 --> 06:04.540
So as soon as the abilities have been given, we're calling this function, right?

06:04.540 --> 06:11.020
And then we could go in and find all abilities on the ability system component.

06:11.050 --> 06:12.610
But here's the thing.

06:12.610 --> 06:16.720
We can't be absolutely sure of the timing of things here.

06:16.840 --> 06:20.620
For example, let's say that things go as we expect.

06:20.650 --> 06:24.520
Our widget controller reaches this line in the code.

06:24.550 --> 06:30.340
It uses add object and binds its callback here to abilities given delegate.

06:30.340 --> 06:36.550
And let's just assume that our ability system component has not given its abilities yet.

06:36.580 --> 06:39.620
Well, in that case, things are going to work out just fine.

06:39.640 --> 06:47.440
We'll bind to our callback and then our ability system some time later will give the abilities and broadcast

06:47.440 --> 06:52.930
the delegate, at which point our callback will be called and we can access those abilities, look up

06:52.930 --> 06:55.360
their tags in the data asset and all that.

06:55.630 --> 07:02.360
Now consider for a moment what would happen if the ability system component gave its abilities first

07:02.360 --> 07:07.280
and broadcast that delegate before we even got to this line here?

07:07.550 --> 07:09.260
Which one happens first?

07:09.260 --> 07:13.300
Well, we can't be sure because it could change.

07:13.310 --> 07:19.370
It could be different depending on what's happening on the server versus the client and so on.

07:19.370 --> 07:23.900
So we have to take care of both situations.

07:23.930 --> 07:29.750
We have to take care of the situation where the abilities are given first and the broadcast is made,

07:29.750 --> 07:34.100
in which case we'll be binding to that broadcast too late.

07:34.100 --> 07:39.380
And we also have to take into account the situation where the opposite happens.

07:39.380 --> 07:43.840
We bind first and then the AC broadcasts.

07:43.850 --> 07:51.170
So to take care of both, what we can do is have a boolean on the ability system component for when

07:51.170 --> 07:52.960
the abilities have been given.

07:52.970 --> 07:55.520
So I'll put that right under Add character abilities.

07:55.520 --> 08:03.350
It's going to be a bool called be abilities, or rather we should call this startup abilities given.

08:03.590 --> 08:09.020
It'll be false by default, but as soon as we've given abilities we'll set it to true.

08:09.290 --> 08:17.240
So back in our ability system component just before making the broadcast, we're going to set be startup

08:17.240 --> 08:19.670
abilities given equal to true.

08:19.760 --> 08:25.340
That way we can always check that and we can know if those abilities have been given or not.

08:25.730 --> 08:27.860
Now in the widget controller we can check.

08:27.860 --> 08:33.860
So here in bind callbacks to dependencies, we can take that risk.

08:34.640 --> 08:45.200
So if our AC startup ability is given and if this is true, we know that our abilities have been given,

08:45.200 --> 08:52.190
in which case on initialized startup abilities, which is going to go and get that ability information

08:52.190 --> 08:54.770
from the AC, it can safely do that.

08:54.770 --> 09:00.560
So we really don't even care about binding to that delegate.

09:00.560 --> 09:03.620
We're just going to call the callback ourselves directly.

09:03.650 --> 09:10.430
Now there's an else case, however, and the else case means that startup ability is given is not true.

09:10.430 --> 09:15.680
In other words, the ability system component has not given the abilities yet.

09:15.680 --> 09:17.660
It has not made the broadcast yet.

09:17.660 --> 09:22.940
So in that case, we do want to bind our callback to abilities given delegate.

09:22.940 --> 09:25.640
So we'll have an if else here now.

09:25.640 --> 09:29.060
So this way we're taking care of both situations.

09:29.640 --> 09:35.970
Now on initialized startup abilities is going to need that ability system component and rather than

09:35.970 --> 09:42.930
getting our ability system component variable and casting again, we could just pass in the pointer

09:42.930 --> 09:49.200
of a U or a ability system component straight into on initialized startup abilities.

09:49.320 --> 09:52.850
I'd rather do that than do a second redundant cast.

09:52.860 --> 09:57.090
So we're going to pass in a pointer to this type.

09:57.120 --> 10:01.080
We're going to call this aura ability system component.

10:01.290 --> 10:06.030
I'm going to check up at the top to see if it's been forward declared or included.

10:06.830 --> 10:07.850
It has not.

10:07.850 --> 10:13.400
So I'm going to forward declare class you or ability system component.

10:13.880 --> 10:17.450
Now this function requires a pointer to this.

10:17.450 --> 10:21.980
So we'll go back to the CPP file and take this function.

10:22.740 --> 10:27.190
And pass it in now because it requires this pointer.

10:27.210 --> 10:34.410
We can't bind it to abilities given delegate anymore unless abilities given delegate is designed to

10:34.410 --> 10:38.310
broadcast a parameter that can be passed into the callback.

10:38.430 --> 10:45.390
So for that reason, we'll go to our ability system component and change this from declare multicast

10:45.390 --> 10:51.480
delegate to multicast delegate one param and then we can pass that pointer.

10:51.480 --> 10:57.360
It's going to be a you or a ability system component and that's a pointer.

10:57.540 --> 11:04.350
So now that this delegate is a different type, it can now have functions bound to it that require this

11:04.350 --> 11:05.190
pointer.

11:05.280 --> 11:10.200
And with that we can come back and see that our error is gone.

11:10.470 --> 11:15.330
But now this function requires an aura ability, system component.

11:15.330 --> 11:20.340
So when we call it here, we can call it passing in or ASC.

11:20.520 --> 11:23.170
And now the function will receive that.

11:23.170 --> 11:29.410
And in addition we have to go back to aura ability system component CP where we're making the broadcast

11:29.410 --> 11:34.840
because this broadcast now needs a pointer to the aura ability system component.

11:34.870 --> 11:37.540
We can simply pass this straight in.

11:37.840 --> 11:46.150
And now our widget controller has our callback on initialized startup ability is called and this function

11:46.150 --> 11:53.830
is now going to be able to get information about all of the abilities in the ability system component.

11:53.860 --> 12:03.280
So I'm going to just make a to do comment here that says get information about all given abilities,

12:03.550 --> 12:09.040
look up their ability info and broadcast it.

12:10.720 --> 12:12.190
Two widgets.

12:13.290 --> 12:16.260
So we have a few things we need to do here, right?

12:18.290 --> 12:22.870
Now, the first thing I'm going to do is just make a sanity check.

12:22.880 --> 12:29.150
I'm going to make an if check taking aura ability system component and check to see if it's startup

12:29.150 --> 12:30.920
abilities has been given.

12:30.920 --> 12:32.810
And I'm going to return early.

12:32.810 --> 12:34.030
If it has not.

12:34.040 --> 12:43.820
So I'll return with a not here if be startup ability is given is not true and then we'll know past that

12:43.820 --> 12:47.000
point that those abilities have been given.

12:47.030 --> 12:53.870
Now I'd like an easy way to do something for all of my activatable abilities, and I don't really want

12:53.870 --> 12:59.510
to have to loop through all of those abilities from within my widget controller.

12:59.510 --> 13:04.970
I don't want to loop through Activatable abilities outside of the ability system component class.

13:04.970 --> 13:13.280
So in the next video we're going to work on a way to easily do something for all of our abilities in

13:13.280 --> 13:19.800
our ability system component and that thing we want to do here is what we have our to do for.

13:19.800 --> 13:22.590
We want to get information and broadcast it to widgets.

13:22.590 --> 13:26.100
So we'll take care of that in the next video.
