WEBVTT

00:06.870 --> 00:07.920
Welcome back.

00:08.460 --> 00:12.960
Now we're updating our ability statuses in the ability system component.

00:12.960 --> 00:18.090
Actually, we're not doing that, but we have a function that can we're not calling it yet, but once

00:18.090 --> 00:22.860
we do call it, then we'll be updating our ability statuses.

00:22.860 --> 00:28.620
Specifically, what that means is we'll be looping through ability info and checking to see if any of

00:28.620 --> 00:35.160
those gameplay abilities that have not been granted yet have a level requirement that we now meet.

00:35.160 --> 00:39.810
But we need to call this function and pass in the current level as soon as we level up.

00:39.810 --> 00:46.470
And we can easily do that because our Aura character has an interface function implementation.

00:46.470 --> 00:52.110
If we go to Aura character, let's go to the CPP file and character or a character.

00:52.110 --> 00:53.550
We have a couple of options.

00:53.550 --> 00:59.820
We have add to player level that gets called and on the server from the attribute set and we also have

00:59.820 --> 01:00.570
level up.

01:00.600 --> 01:08.100
Now I'd like level up to just be concerned with, you know, cosmetics and things that happen as a result

01:08.200 --> 01:13.450
of gaining a level and then add to player level, which calls add to level on the player state.

01:13.480 --> 01:20.710
This is where I'd like to get the ability system component and call that function update ability statuses.

01:20.770 --> 01:23.080
Now we need the ability system component.

01:23.080 --> 01:31.720
So we're going to say you aura ability system component or ASC we'll cast to you or ability system component

01:32.950 --> 01:36.070
didn't mean to include that library.

01:36.810 --> 01:40.380
So I'm going to undo that.

01:40.560 --> 01:48.060
It's going to be your ability system component and we're casting and we'll just call it get ability

01:48.060 --> 01:49.260
system component.

01:49.590 --> 01:52.680
Now I'm just going to wrap this in an if statement.

01:54.060 --> 02:02.100
And here in the if statement, we'll take our ask and we can call update ability statuses passing in

02:02.100 --> 02:04.560
the new level in player level.

02:06.690 --> 02:09.900
And now the ability system component will respond.

02:10.640 --> 02:16.280
And it's going to give any abilities that exist in the ability info that we meet the level requirements

02:16.280 --> 02:17.150
for now.

02:17.240 --> 02:20.490
But now we need to tell our widget controllers about this.

02:20.510 --> 02:23.570
They need to know so they can update their widgets.

02:23.810 --> 02:28.820
So our ability system component could use a new delegate.

02:30.040 --> 02:36.430
I'd like to broadcast a couple of gameplay tags through a delegate, the ability tag and the new status.

02:36.430 --> 02:39.100
So I'm going to declare a new delegate.

02:39.340 --> 02:52.570
I'm going to say declare multicast delegate and it'll have two params I'm going to call it F ability

02:52.570 --> 02:58.540
status changed and it's going to broadcast two gameplay tags.

02:59.050 --> 03:01.510
I'll broadcast them by const reference.

03:01.510 --> 03:10.060
So const f gameplay tag and we don't need to say their names, but I'm going to in a comment this will

03:10.060 --> 03:15.730
say ability tag and this should be a const ability tag reference.

03:17.510 --> 03:20.480
And I'm going to have a second gameplay tag.

03:21.390 --> 03:24.480
Only this one will be the status tag.

03:25.280 --> 03:32.810
And I can add an ability status changed delegate right here in the public section called ability status

03:32.810 --> 03:36.500
changed and we'll be broadcasting this.

03:36.680 --> 03:43.100
We could come in here to update ability statuses and broadcast it here, but this is only on the server,

03:43.100 --> 03:50.660
so I want to handle broadcasting this on server and client in the case where the human controlling the

03:50.660 --> 03:54.050
character can receive the broadcast on their machine.

03:54.050 --> 04:02.150
For that reason I'm going to make a special client RPC just for this that will broadcast the ability

04:02.150 --> 04:03.980
tag and the new status.

04:03.980 --> 04:10.310
So here in aura ability system component, we'll go all the way down to the protected section and make

04:10.310 --> 04:11.750
a new client RPC.

04:12.950 --> 04:17.390
It's going to be called client update ability status.

04:17.600 --> 04:22.370
So its inputs will be const gameplay tag reference.

04:22.400 --> 04:35.120
Ability tag and const gameplay tag reference status tag and client update ability status will be a new

04:35.120 --> 04:40.400
function with client and reliable, so we'll go ahead and generate the definition.

04:40.400 --> 04:49.430
It has to have implementation in its name and this client RPC is just going to broadcast the delegate

04:49.460 --> 04:52.280
ability status changed.

04:52.610 --> 04:55.880
So we'll take ability status changed will broadcast.

04:55.910 --> 05:00.710
We're going to broadcast ability tag and we're going to broadcast status tag.

05:03.800 --> 05:10.550
And now all we need to do is call client update ability status in update ability statuses here.

05:11.230 --> 05:17.380
So we'll do it as soon as we've given the ability because we know this ability has just had its status

05:17.380 --> 05:18.210
changed.

05:18.220 --> 05:24.190
So we're going to call client update ability status passing in the ability tag.

05:24.190 --> 05:26.980
That's info dot ability tag.

05:26.980 --> 05:30.190
And we're going to pass in that status.

05:30.220 --> 05:35.170
We know the status is going to be eligible, so we can just pass that straight through.

05:36.170 --> 05:37.130
Right there.

05:37.830 --> 05:45.190
And with that, we now should have a delegate broadcast for when an ability status changes.

05:45.210 --> 05:52.020
And now our widget controller can subscribe to that delegate and broadcast a delegate of its own up

05:52.020 --> 05:54.780
to our widgets, which can update themselves.

05:55.530 --> 05:59.940
Now that can actually be quite an easy thing for us to do.

05:59.940 --> 06:02.970
All we have to do is use our ability info delegate.

06:03.090 --> 06:10.890
So if we just really quickly go over to our private folder into UI, into widget controller and open

06:10.890 --> 06:18.450
spell menu, widget controller and bind callbacks to dependencies, we can simply bind something to

06:18.480 --> 06:20.580
ability status changed.

06:21.220 --> 06:23.800
So we can call Git or ask.

06:24.850 --> 06:27.820
We can get ability status changed.

06:30.240 --> 06:32.130
And we can bind to it.

06:32.160 --> 06:33.990
We can use add lambda.

06:34.080 --> 06:36.690
We could just bind a lambda real quick.

06:36.960 --> 06:41.280
So let's do our square parentheses and curly braces.

06:41.460 --> 06:44.790
And I'm just going to put these braces on their own line.

06:45.000 --> 06:53.520
And the function has to be able to take in a const f gameplay tag called ability tag and a const F gameplay

06:53.520 --> 06:54.270
tag.

06:55.890 --> 06:57.660
Calls status tag.

06:59.570 --> 07:03.260
And all it has to do is get its ability info.

07:03.260 --> 07:08.780
So if ability info remember our widget controllers have ability info as well.

07:08.810 --> 07:10.100
Pretty convenient.

07:10.130 --> 07:16.460
Now if we're going to get ability info, we have to capture this right there in the square brackets

07:16.460 --> 07:21.460
and if ability info is valid we can get the ability info for the ability tag.

07:21.470 --> 07:31.190
We can say for ability info, call it info equals ability info and we can call find ability info for

07:31.190 --> 07:31.580
tag.

07:31.580 --> 07:35.940
All of these helper functions are really really useful aren't they?

07:35.960 --> 07:40.250
We can pass in ability tag and we now have the ability info.

07:40.250 --> 07:43.850
And the thing is we've set the ability tag.

07:43.850 --> 07:46.580
We just need to set the ability status.

07:47.360 --> 07:50.480
So info dot and we have the status tag.

07:50.480 --> 07:52.310
We can set it to status tag.

07:55.360 --> 07:59.050
And then we can broadcast ability info delegate.

08:00.780 --> 08:04.020
So we'll broadcast our info.

08:06.070 --> 08:07.720
So that was pretty easy.

08:07.750 --> 08:13.000
Now, whenever the ability status has changed on the ask, it's going to broadcast it.

08:13.000 --> 08:18.850
Our spell menu is going to receive that info and receive its status tag.

08:18.850 --> 08:20.380
That has just changed.

08:20.410 --> 08:22.720
We know that's the up to date tag.

08:22.720 --> 08:29.170
We'll get the ability info from the data asset and then we'll set the status tag and broadcast up to

08:29.170 --> 08:32.050
our widgets, which should update themselves.

08:32.380 --> 08:40.510
So the last thing to do is just see if we can change that second ability, the one with a level requirement

08:40.540 --> 08:45.520
of two to update in the spell menu as soon as we level up to level two.

08:47.260 --> 08:47.800
All right.

08:47.800 --> 08:49.240
We're back in the editor.

08:50.390 --> 08:54.830
Just double checking the ability tag is abilities lightning.

08:54.830 --> 09:00.050
We still have lightning in our ability info data asset.

09:00.050 --> 09:02.180
It's level requirement is two.

09:02.210 --> 09:09.680
We can grant that ability as soon as we level up to level two and we should see the lightning bolt in

09:09.680 --> 09:10.970
our spell menu.

09:11.970 --> 09:13.960
So let's just see if it works.

09:13.980 --> 09:20.940
We see the locked icon, and as soon as I level up, I expect to see it change and it does not.

09:20.940 --> 09:25.360
So we need to figure out where we're not succeeding.

09:25.380 --> 09:31.860
Now, the first thing I'm going to do is place a breakpoint in update ability statuses just to see what

09:31.860 --> 09:33.810
that level value is.

09:33.960 --> 09:37.950
That should give me some info, so I'm going to go ahead and level up.

09:39.580 --> 09:42.100
And it looks like level is one.

09:42.250 --> 09:46.270
Now, if I just leveled up, I expect it to be two, right?

09:46.300 --> 09:50.350
But this could mean that I've made some kind of logic error.

09:50.350 --> 09:59.320
So let's go back and if I click on gameplay effect execute, I see that I'm calling add to player level.

09:59.320 --> 10:05.380
And you know what the num level ups is one, we only leveled up once, so we're actually passing in

10:05.380 --> 10:12.370
that number of times we've leveled up over to the ability system component, not the total level we

10:12.370 --> 10:14.560
need to pass the total level over.

10:14.560 --> 10:22.480
So instead of passing in player level, we actually need to pass the total player level, which we can

10:22.480 --> 10:24.190
get from Player State.

10:24.220 --> 10:29.230
We can call Aura Player State get player level.

10:29.230 --> 10:32.230
That is the level that we need to pass in.

10:32.230 --> 10:35.440
So once again, fixing that logic error.

10:35.470 --> 10:37.540
Let's see if all this works.

10:38.600 --> 10:39.020
Okay.

10:39.020 --> 10:39.950
Pressing play.

10:39.950 --> 10:43.690
Looking at my spell menu all looks as expected.

10:43.700 --> 10:45.050
Leveling up.

10:46.860 --> 10:50.280
And I still have my break points, so I'm going to remove it and resume.

10:51.830 --> 10:56.790
I have leveled up, I can open my menu and sure enough, I see the lightning bolt.

10:56.790 --> 11:02.490
It's in the eligible state and that means things are working.

11:02.490 --> 11:05.190
Now, we can't just go in there and.

11:05.920 --> 11:07.420
Spend a spell point on it yet.

11:07.450 --> 11:14.260
We haven't implemented that yet, but we do have our icon updating to the eligible state, which is

11:14.260 --> 11:16.420
exactly what I wanted to see.

11:16.480 --> 11:19.390
So this is looking really nice.

11:19.960 --> 11:22.630
Now let's test the client.

11:22.660 --> 11:25.360
We're going to go ahead and increase the number of players to two.

11:25.360 --> 11:27.330
I'm going to full screen my client.

11:27.340 --> 11:28.480
I'm going to look at it.

11:28.480 --> 11:29.790
Looks like it's locked.

11:29.800 --> 11:31.750
I'm going to level up once.

11:33.990 --> 11:36.000
And it works on the client as well.

11:36.000 --> 11:38.640
So that is looking beautiful.

11:38.880 --> 11:42.210
Now I'm going to test one particular scenario, though.

11:42.240 --> 11:47.880
I'm going to press play and I'm going to level up before I even open my spell menu for the first time

11:47.880 --> 11:49.560
and then I'm going to open it up.

11:49.560 --> 11:56.640
I wanted to do that because I wanted to make sure that it gets the current information accurately,

11:56.640 --> 11:59.040
and I'm going to do that on the client as well.

11:59.040 --> 12:06.480
I'm going to level up before the first time I open my spell menu and then open it up after leveling

12:06.480 --> 12:10.890
up just to make sure I see what I expect and I do.

12:10.890 --> 12:13.200
So things are looking really nice.

12:13.200 --> 12:18.570
It's really exciting to be able to see your progress in a visible way.

12:18.570 --> 12:27.150
And before we wrap up, I would like to see if our spell menu updates while it's open, because that's

12:27.150 --> 12:32.760
an important thing too, except I can't move around while it's open, so I temporarily need to disable

12:32.760 --> 12:33.970
that feature.

12:33.970 --> 12:44.230
I need to go into UI overlay WB overlay and I have to go into attribute menu button clicked, which

12:44.230 --> 12:50.680
is an event and in fact I have abstracted it away into input mode UI only.

12:50.680 --> 12:57.580
So that's actually really convenient because all I have to do is disconnect this here and then I should

12:57.580 --> 13:00.550
be able to run around even with my menu open.

13:00.550 --> 13:03.730
So abstracting things into functions is handy.

13:04.330 --> 13:05.770
All right, let's level up.

13:06.210 --> 13:08.640
And there it updated looked good.

13:08.640 --> 13:13.690
And for giggles, let's just test on the client as well.

13:13.710 --> 13:15.720
I'm going to open my menu.

13:15.720 --> 13:16.740
Level up.

13:17.800 --> 13:18.790
And it updates.

13:18.790 --> 13:21.430
So everything works as expected.

13:21.760 --> 13:23.140
Excellent.

13:23.140 --> 13:25.540
I'm going to go ahead and hook that back up.

13:25.540 --> 13:27.740
Everything's looking good so far.

13:27.760 --> 13:30.370
We still have some things to do, though, right?

13:30.370 --> 13:37.030
If I now have an eligible spell, I want to be able to spend points on that spell.

13:37.030 --> 13:40.930
So now we need to start implementing the spell points.

13:40.960 --> 13:43.990
We have to be able to gain spell points.

13:43.990 --> 13:50.320
We have to be able to spend spell points and we have to be able to select globes in our tree so that

13:50.320 --> 13:53.860
we can then click spell point and spend a spell point on it.

13:53.860 --> 14:01.720
So quite a few things to implement in our spell menu, but we're coming right along and things are really

14:01.720 --> 14:04.420
starting to come together, which is really exciting.

14:04.660 --> 14:07.390
Excellent job and I'll see you in the next video.
