WEBVTT

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

00:08.040 --> 00:15.510
So our widget controller is broadcasting a delegate and we need to bind to that delegate in our widgets

00:15.510 --> 00:18.090
so that we can receive ability info.

00:18.360 --> 00:22.950
Our whole goal here is to show which abilities we have in our HUD.

00:22.980 --> 00:29.850
So I'm going to run in debug mode and we're going to bind to our ability info Delegate.

00:30.910 --> 00:32.310
So we're back in the editor.

00:32.320 --> 00:33.700
Here's our ability info.

00:33.730 --> 00:38.200
This is the stuff that we have exposed to the data asset itself.

00:38.230 --> 00:43.510
Now there's another field we don't see here, and that's the input tag, but that is blueprint read

00:43.510 --> 00:46.120
only so we can access that from within our widgets.

00:46.150 --> 00:47.180
Event Graphs.

00:47.200 --> 00:53.650
Now let's go into one of our widgets that we'd like to receive ability info in.

00:53.800 --> 01:00.440
We're going to go to Blueprints UI and what I'm interested in is in overlay sub widget.

01:00.460 --> 01:01.450
Actually, nope.

01:01.450 --> 01:05.710
It's in spell globes and it's called spell globe.

01:06.130 --> 01:10.030
Our spell globe is going to receive an ability info delegate.

01:10.360 --> 01:17.080
So I'm going to go to graph and as soon as our spell globe has had its widget controller set, we can

01:17.110 --> 01:20.260
bind to some delegates on that widget controller.

01:20.260 --> 01:27.910
So what I want to do is delete those nodes and right click and type event widget controller set.

01:28.120 --> 01:35.150
As soon as the widget controller has been set, then I know that I have a valid widget controller variable

01:35.150 --> 01:39.560
and then I can cast it to the overlay widget controller.

01:39.560 --> 01:45.110
So cast to and I'm going to cast to the blueprint version, BP overlay widget controller.

01:45.110 --> 01:52.220
And I can simply promote that to a variable and I'm going to call it BP overlay widget controller.

01:52.790 --> 01:59.090
Now that's the first thing I'm going to do in widget controller set, and that's not the only thing.

01:59.090 --> 02:03.680
So for that reason, I'm going to make a sequence node.

02:03.710 --> 02:09.890
So dragging off of this, I'm going to type sequence and that will be the first thing we do.

02:09.920 --> 02:17.200
The second thing we do will be to take that BP overlay widget controller and get that ability info delegate.

02:17.210 --> 02:20.000
So I'm going to assign ability info delegate.

02:20.030 --> 02:27.980
Now I have an event that will respond to it and that is going to receive a ability info struct.

02:27.980 --> 02:33.800
And if I drag off and I break the ability info struct I see the four fields, the ability tag, the

02:33.800 --> 02:36.470
input tag, the icon and the material.

02:36.470 --> 02:43.970
So now I can set my globe properties based on these, but I don't want to set it just for any ability

02:43.970 --> 02:44.600
info.

02:44.630 --> 02:46.490
I want to check the input tag.

02:46.490 --> 02:46.850
Why?

02:46.880 --> 02:54.280
Because our widget, if we press play, each one of these globes has its own input tag.

02:54.290 --> 03:02.030
The passive ability globes don't really have an input tag, but we can assign them input tags anyway

03:02.030 --> 03:03.560
to identify them.

03:03.560 --> 03:09.950
We can just call them passive one and two, but LNB, R and B and one through four have input tags,

03:09.980 --> 03:11.510
or at least they should.

03:11.540 --> 03:17.210
So for that reason, our spell globe should have a gameplay tag variable called input tag.

03:17.420 --> 03:18.950
So let's add that to it.

03:18.980 --> 03:25.850
We're going to add a variable called input tag and we're going to change this to a gameplay tag.

03:27.210 --> 03:34.830
And each of these spell globes needs to know what its input tag is and then it can check its input tag

03:34.830 --> 03:37.200
against the info it's receiving.

03:37.230 --> 03:39.960
So how is it going to know what its input tag is?

03:39.990 --> 03:49.520
Well, really the overlay is the only thing that knows that if we go into UI overlay and open up overlay,

03:49.530 --> 03:51.610
we know here what the input tag is.

03:51.630 --> 03:58.200
In fact, actually not even the overlay, but the health mana spells widget is what knows that.

03:58.200 --> 04:04.530
So we can go to sub widget and open health mana spells and the health man spells knows which one is

04:04.530 --> 04:04.920
which.

04:04.920 --> 04:05.610
Right.

04:05.640 --> 04:09.200
So we need to assign those input tags here.

04:09.210 --> 04:12.750
I need to take the first one and just to know which one is which.

04:12.750 --> 04:22.800
I'm going to rename this to spell globe underscore LMB and I'm going to take the next one and rename

04:22.800 --> 04:26.880
this one to spell Globe R&amp;B and take the next one.

04:26.880 --> 04:27.760
This is one.

04:27.760 --> 04:31.120
So I'm going to rename this to spell globe underscore one.

04:31.920 --> 04:33.900
And we'll do two through four.

04:46.200 --> 04:52.530
So there now they have names that we can easily identify them by, and I'm also going to name the passive

04:52.530 --> 04:53.600
ones as well.

04:53.610 --> 05:01.440
I'm going to call this one spell globe underscore passive, underscore one, and then the next one will

05:01.440 --> 05:03.690
be spell globe passive two.

05:05.310 --> 05:08.730
And we'll worry about creating gameplay tags for those later.

05:08.730 --> 05:13.320
But for now I'm going to select each of these and make them variables.

05:13.320 --> 05:16.040
I'm going to hold, shift and just click on each of them.

05:16.050 --> 05:22.020
Make sure it's only those spell globes selected check is variable and go back to the graph.

05:22.020 --> 05:25.550
And now I have variables for each of them.

05:25.560 --> 05:32.190
They're easily identifiable and I'm going to set their input tags so they know which ones they are.

05:32.220 --> 05:41.490
So I'm going to add a function to do that called set spell globe input tags, and I'm going to take

05:41.490 --> 05:47.730
each of them and set their input tags one through four and LMB and R&amp;B.

05:47.730 --> 05:52.800
I'm going to get LMB and R&amp;B first and then get one through.

05:53.330 --> 05:54.110
For.

05:57.950 --> 06:01.490
And I can simply set each of their tags.

06:01.670 --> 06:08.040
So if I drag off and type input tag, I can call set input tag.

06:08.060 --> 06:10.730
And I can use a sequence to set these.

06:12.910 --> 06:18.460
So first we'll get Spell Globe Lab and set its input tag to lab.

06:18.490 --> 06:23.680
So it's going to be input tag dot lab.

06:26.060 --> 06:27.590
Next is R&amp;B.

06:28.430 --> 06:33.560
And, you know, I'm just going to take this setter and duplicate it one, two, three, four, five

06:33.560 --> 06:34.670
more times.

06:37.490 --> 06:40.760
And for R&amp;B, I'm going to set it to R&amp;B.

06:42.170 --> 06:44.240
That'll be the next thing we do.

06:47.460 --> 06:53.370
And next we have spell globe one and that one gets the input tag one.

06:54.540 --> 06:55.680
We'll hook that up.

06:57.330 --> 07:03.660
Next we have spell globe two through four and I'm going to time lapse the rest of this.

07:08.830 --> 07:09.310
Okay.

07:09.310 --> 07:15.940
And just double checking the name of the spell globe with the name of the input tag.

07:19.370 --> 07:20.710
And they all match.

07:20.720 --> 07:23.800
So now we have this function for setting all the input tags.

07:23.810 --> 07:25.250
This can be set right away.

07:25.250 --> 07:28.070
In fact, it can be set before widget controller set.

07:28.100 --> 07:31.550
It can be set in event pre construct.

07:32.290 --> 07:37.270
So I'm going to set spell globe input tags as early as possible.

07:37.780 --> 07:42.910
And now those spell globes should all have their input tags set.

07:43.180 --> 07:45.050
So back to spell globe.

07:45.070 --> 07:53.350
Now that we know by the time this happens, the widget controller has been set, we can check the input

07:53.380 --> 07:57.280
tag against our spell globes input tag.

07:57.280 --> 08:07.680
We can say matches tag, we can do an exact match and check the input tag and we'll have a branch here.

08:07.690 --> 08:10.480
Now, what happens if we do get a match?

08:10.480 --> 08:12.490
Well, we have info.

08:12.520 --> 08:20.140
We have the icon in the background material that we can set here in our globe because we have the background

08:20.140 --> 08:21.640
and the spell icon.

08:21.640 --> 08:23.230
We want to set those.

08:23.230 --> 08:30.190
So we're going to call a function we specifically made for this set icon in background.

08:30.220 --> 08:37.060
These take brushes, so we have to make brushes based on the icon and the material.

08:38.760 --> 08:41.640
If we type make slate brush.

08:43.200 --> 08:46.330
Then we can make one from the image and drag it in.

08:46.350 --> 08:47.910
That's for the icon.

08:48.210 --> 08:53.430
And we can also get a background material and make slate brush.

08:55.630 --> 08:58.180
And use that as the image to.

08:58.830 --> 09:09.090
And so now we have a way to set the abilities, icon and background image based on the ability info

09:09.120 --> 09:10.190
that we receive.

09:10.200 --> 09:12.480
And this can all be collapsed to a function.

09:15.780 --> 09:21.360
And we can call it receive ability info.

09:23.270 --> 09:32.450
So now we have a nice struct that receives that info from our widget controller and we should now fingers

09:32.450 --> 09:34.820
crossed, see the ability.

09:35.670 --> 09:36.810
And we don't.

09:36.810 --> 09:38.520
And I think I know why.

09:38.550 --> 09:45.000
Because our firebolt ability doesn't have an ability tag.

09:45.770 --> 09:52.610
So in blueprints ability system or a abilities fire firebolt Firebolt.

09:53.090 --> 09:58.550
Our ability tags have nothing there because we never actually gave it the abilities.

09:58.550 --> 10:01.130
Fire firebolt ability.

10:01.160 --> 10:08.330
Now that that's set, now we know when we perform the lookup, we can identify it because we're looking

10:08.330 --> 10:11.570
for abilities that have that tag if we press play now.

10:12.740 --> 10:13.730
Still nothing.

10:13.730 --> 10:15.290
Let's go to ability info.

10:15.320 --> 10:18.170
We do have the abilities fire Firebolt.

10:18.440 --> 10:23.350
We don't know if our widget controller is being set for the spell globe.

10:23.360 --> 10:26.390
In fact I believe it is not.

10:26.390 --> 10:28.820
So that's something we have to do as well.

10:28.970 --> 10:35.860
Now that's something we have to do after the widget controller has been set here as our health mana

10:35.870 --> 10:42.470
spells is going to set the widget controller for its spell globes and those globes are going to share

10:42.470 --> 10:43.820
the same widget controller.

10:43.820 --> 10:51.290
So we actually need to create a function here and we're going to call this set globe widget controllers.

10:52.760 --> 10:57.830
And this has to actually call set widget controller on all of our Globes.

10:57.950 --> 11:04.010
So we're going to get that LMB first and call set widget controller.

11:06.450 --> 11:10.890
And hook this up and pass in widget controller.

11:11.870 --> 11:13.820
So we're going to set it to.

11:14.410 --> 11:16.450
This widgets widget controller.

11:16.750 --> 11:24.010
And the cool thing here is we can actually pass in all of our spell globes into this function call.

11:24.220 --> 11:30.640
So using that trick with one node, we can call it multiple times by passing in multiple targets.

11:30.640 --> 11:36.010
So we'll get the LMB, we'll get the R&amp;B, pass that in and one through four.

11:37.830 --> 11:39.900
And pass each of those in.

11:41.410 --> 11:44.410
So now they'll all have their widget controllers set.

11:44.440 --> 11:52.530
Now, it's very, very important that all of these have their input tags set before their widget controllers

11:52.540 --> 11:57.010
because in the spell globe, we're checking our own input tag.

11:57.010 --> 12:01.690
The input tag for the spell globe is checked, so that needs to be set first.

12:01.720 --> 12:04.980
Luckily, we're setting it really early on.

12:04.990 --> 12:08.560
We're setting it up here in event pre construct.

12:08.680 --> 12:19.240
So it might even be worth having a comment here that says input tags must be set before widget controllers

12:19.270 --> 12:28.810
are set on the spell globes and then widget controllers can be set set globe widget controllers, we

12:28.810 --> 12:30.160
can call that here.

12:30.160 --> 12:35.140
And then once that happens, the spell globes will have their widget controller set events.

12:35.410 --> 12:39.970
Then they can bind to the ability info delegate.

12:40.000 --> 12:49.400
So now we should be able to press play and sure enough, our left mouse button globe has our firebolt

12:49.400 --> 12:55.550
spell and none of the others do because they don't match any input tags that are broadcast.

12:56.240 --> 12:58.340
Okay, so that is great.

12:58.430 --> 13:02.490
But there's one last thing to take care of, and that's multiplayer.

13:02.510 --> 13:06.230
Let's go ahead and change the number of players to two and press play.

13:06.530 --> 13:15.020
And I'm going to take my client here and notice the client does not have that icon, so why not?

13:15.200 --> 13:18.860
Well, that all comes back to I'm going to close the editor.

13:18.890 --> 13:28.040
Our ability system component broadcasting that delegate when it gives abilities, it's broadcasting

13:28.040 --> 13:31.430
our abilities given delegate in add character abilities.

13:31.430 --> 13:33.590
But this is only done on the server.

13:33.680 --> 13:38.270
So we need a way to broadcast it on clients as well.

13:38.270 --> 13:40.790
And there's a nice, easy way to do that.

13:40.790 --> 13:48.980
You see, once our abilities have been given, then the ability system components, activatable abilities,

13:48.980 --> 13:50.870
container replicates.

13:50.870 --> 13:52.490
It's a replicated variable.

13:52.700 --> 13:56.700
In fact, if we search for Activatable all.

13:58.670 --> 13:59.600
Abilities.

13:59.690 --> 14:01.960
And here's what I find.

14:01.970 --> 14:07.760
Git activatable abilities if I go to its definition, here's.

14:07.790 --> 14:09.260
Activatable abilities.

14:09.260 --> 14:16.620
And if I go to its declaration or usages, we see here that it's replicated using en rep.

14:16.640 --> 14:20.810
Activatable abilities or en rep activate abilities.

14:20.900 --> 14:25.190
Now if we search for this, we see that it's a virtual rep notify.

14:25.220 --> 14:29.900
So this gets called in response to our activatable abilities replicating.

14:29.900 --> 14:34.280
So after we've called give abilities, this is going to replicate.

14:34.280 --> 14:41.300
And not only that, it's going to contain the ability specs of our newly given abilities so we can override

14:41.330 --> 14:45.440
en rep, activate abilities in our ability system component.

14:45.440 --> 14:48.230
And this is a protected function.

14:48.230 --> 14:56.720
So let's override it and are protected section in our ability system component virtual void en rep activate

14:56.720 --> 14:57.710
abilities.

14:57.740 --> 15:00.810
Let's go ahead and generate the definition.

15:00.810 --> 15:07.320
We'll let it call super and we'll also do what we want to make a broadcast.

15:07.350 --> 15:08.690
What do we want to broadcast?

15:08.700 --> 15:11.730
Well, that's going to be the abilities given delegate.

15:12.000 --> 15:16.560
We have to broadcast it and we have to pass in this.

15:17.460 --> 15:24.120
And not only are we going to do that, but we don't want to broadcast it every time this replicates.

15:24.150 --> 15:28.440
We want to do this only the first time we've given abilities.

15:28.440 --> 15:34.170
So what we'll do is check, if not be startup abilities given.

15:34.200 --> 15:37.290
Now we only set this on the server and it's not replicated.

15:37.290 --> 15:44.430
So down here on the client it will be false the first time and if it's false, we'll set it to true

15:44.460 --> 15:47.640
be startup abilities given equals true.

15:47.640 --> 15:53.850
And that way every time this activatable abilities replicates, we won't be broadcasting the delegate

15:53.850 --> 15:55.890
every time, just the first time.

15:55.890 --> 16:03.090
So now that we're broadcasting it on the client, we can actually test this in multiplayer and see if

16:03.090 --> 16:07.350
we can see that fireball icon on the client.

16:08.420 --> 16:09.140
Okay.

16:09.140 --> 16:11.150
So back in the editor.

16:11.420 --> 16:13.160
Moment of truth.

16:13.160 --> 16:14.930
I have two players.

16:14.930 --> 16:16.220
Let's press play.

16:16.220 --> 16:21.350
And on the client, sure enough, we see our ability icon.

16:22.150 --> 16:24.190
And it's assigned to our left mouse button.

16:24.190 --> 16:30.820
Now, the really magical thing about this, this is really cool because we have a dynamic system here

16:30.820 --> 16:34.330
that is extremely well coded.

16:34.360 --> 16:35.110
Why?

16:35.140 --> 16:41.350
Well, let's go to our GA firebolt and take a look at its input tag.

16:41.380 --> 16:42.910
Start up input tag.

16:42.910 --> 16:49.960
This is something we created and change it to right mouse button, R&amp;B and press play.

16:50.900 --> 16:51.950
Check it out.

16:52.220 --> 16:58.730
Our system is so robust, it already handles it and we can't fire our ability with the left mouse button

16:58.730 --> 16:59.180
anymore.

16:59.180 --> 17:01.350
We have to use the right mouse button.

17:01.370 --> 17:03.410
How cool is that?

17:03.740 --> 17:11.210
So when you code things well from the start, then expanding the system becomes relatively easy.

17:11.210 --> 17:17.600
As everything is in place, everything just works out of the box because you took the extra effort to

17:17.600 --> 17:18.710
code it well.

17:19.010 --> 17:20.810
I mean, this is so nice.

17:20.810 --> 17:29.060
We can go into our firebolt and change this to input tag dot one and if we press play, it's now in

17:29.060 --> 17:34.430
one and we have to press the one key in order to launch.

17:34.460 --> 17:37.850
The one key actually works to launch a firebolt.

17:37.850 --> 17:39.990
So pretty cool.

17:40.010 --> 17:42.410
I'm going to set it back to left mouse button.

17:42.410 --> 17:50.780
But the great thing about this is it's so robust that we can change a given abilities input tag at runtime

17:50.990 --> 17:58.580
as this variable is not what we would change, we would actually change its dynamic ability tags on

17:58.580 --> 18:01.580
the ability spec and our activatable abilities.

18:01.580 --> 18:09.500
And if we change that and removed the old input tag from it, then we could reassign abilities at runtime.

18:09.500 --> 18:11.360
That's exactly what we're going to do.

18:11.360 --> 18:17.210
But we need to make a HUD with buttons that can allow us to do that and all of that in time.

18:17.210 --> 18:18.230
We'll get to that.

18:18.230 --> 18:22.010
But for now, we have a great milestone under our belts.

18:22.040 --> 18:29.780
We now have the ability to show our start up abilities in our HUD, which is really nice.

18:29.780 --> 18:36.200
And when we start creating more abilities, we'll be able to see those here and we'll get to all that.

18:36.200 --> 18:40.100
But in the meantime we have this exp bar to take care of.

18:40.130 --> 18:47.150
So exp is one of the next things that we're going to implement so our character can start to level up.

18:47.300 --> 18:49.830
So really exciting stuff.

18:49.850 --> 18:50.540
Excellent.

18:50.540 --> 18:51.810
Excellent job.

18:51.810 --> 18:54.660
And I'll see you in the next video.
