WEBVTT

00:07.140 --> 00:07.650
Okay.

00:07.650 --> 00:08.520
Welcome back.

00:08.520 --> 00:17.490
Now we have three callback functions, and for all of our input actions that exist in our data asset,

00:17.490 --> 00:23.310
our input config, we're going to bind all three of these to those input actions.

00:23.310 --> 00:26.970
We have callbacks for pressed, released and held.

00:27.000 --> 00:33.720
Now we'd like to be able to activate abilities and we'd like to use the input tag to identify those

00:33.720 --> 00:34.620
abilities.

00:35.070 --> 00:40.230
Now abilities can be associated with gameplay tags in any number of ways.

00:40.230 --> 00:45.990
We know that our ability system component will grant us our startup abilities, and if we start the

00:45.990 --> 00:52.470
game with abilities, those abilities should be associated with some kind of input tag by default so

00:52.470 --> 00:57.180
that we know if we press that particular input, we can activate that ability.

00:57.780 --> 01:05.850
So for this reason I'd like to add a gameplay tag variable to our aura gameplay ability here in our

01:05.850 --> 01:11.710
ability system folder under abilities, there's our aura gameplay ability.

01:11.710 --> 01:19.450
I'm going to open the header file and I'd like this class to have a member variable for its startup

01:19.450 --> 01:20.620
input tag.

01:20.830 --> 01:29.260
Now a gameplay ability might have its input tag changed at runtime, so this variable is really only

01:29.260 --> 01:31.810
for the startup input tag.

01:31.900 --> 01:37.600
So it only applies if this is one of our startup abilities given at the beginning of the game.

01:37.780 --> 01:42.790
So we'll make a public section and this input tag will be right here.

01:42.790 --> 01:49.450
We're going to call this F gameplay tag startup input tag.

01:50.550 --> 01:57.000
So this is the input tag that we'll use if this ability is a startup ability.

01:57.210 --> 02:02.730
So I'll make this a new property and I'd like to be able to set this on the gameplay ability.

02:02.910 --> 02:09.330
So I'll make it edit defaults only and I'll stick it in a category of input.

02:10.190 --> 02:12.800
So we have this start up input tag.

02:13.100 --> 02:23.330
Now the thing is that this will be set for our class default object for any given ability, but that's

02:23.330 --> 02:25.890
not something that we should change at runtime.

02:25.910 --> 02:32.570
Our abilities have different instancing policies and really it's the gameplay ability spec that we'll

02:32.570 --> 02:34.310
be using throughout the game.

02:34.310 --> 02:41.690
So start up input tag is really only good to check at the very beginning when giving abilities to the

02:41.690 --> 02:42.560
character.

02:42.680 --> 02:50.300
So if we go into our ability system component class and we can actually go into the CPP file where we're

02:50.300 --> 02:58.010
adding character abilities, right here is where we can check if the ability has a valid startup input

02:58.040 --> 02:58.730
tag.

02:58.880 --> 03:04.820
Now we want our gameplay abilities to have the concept of an input tag, but we'd like to be able to

03:04.820 --> 03:06.520
change this at runtime.

03:06.530 --> 03:12.390
For example, we might have an ability mapped to the left mouse button and we may want to reassign it

03:12.390 --> 03:13.800
to the right mouse button.

03:13.980 --> 03:23.280
So having a variable on the gameplay ability class is great for something like the startup input tag,

03:23.400 --> 03:29.910
but if we want to be able to change it, we can't really use variables on the gameplay ability class.

03:30.120 --> 03:37.110
Well, the gameplay ability spec has a gameplay tag container specifically for tags that can be added

03:37.110 --> 03:39.960
or removed dynamically throughout the game.

03:39.960 --> 03:43.050
So that's perfect for our input tag.

03:43.050 --> 03:49.440
And as our ability system component adds the abilities for the first time at the beginning of the game.

03:49.440 --> 03:55.710
Since these are startup abilities, we can check that startup input tag and we can add those to our

03:55.710 --> 03:58.290
ability spec for that given ability.

03:58.290 --> 04:04.620
So right after we've created our ability spec, what we can do is we can take this ability spec and

04:04.620 --> 04:07.830
we can get those dynamic tags and add to them.

04:07.830 --> 04:11.670
So that tag container is called dynamic ability tags.

04:11.670 --> 04:19.200
And if we add a tag with the add tag function, we can simply get the ability and get its startup ability

04:19.200 --> 04:20.250
input tag.

04:20.340 --> 04:22.400
So how do we get the ability?

04:22.410 --> 04:24.390
Well, we take the ability spec.

04:25.410 --> 04:34.860
And we use the dot operator to get ability and ability is the actual ability that the ability spec is

04:34.860 --> 04:36.660
a representation of.

04:36.690 --> 04:42.500
And if that ability is not a null pointer, then we can get variables on it.

04:42.510 --> 04:51.540
Now ability is a simple you gameplay ability, so we'll have to cast it in order to get that member

04:51.540 --> 04:53.970
variable called start up input tag.

04:54.060 --> 04:56.850
So we'll go ahead and cast right here in the for loop.

04:56.850 --> 04:57.750
Let's do it.

04:58.020 --> 05:07.140
We're going to say if and we'll make a const you ora gameplay ability that will be a pointer and notice

05:07.140 --> 05:09.120
writer included the header for me.

05:09.150 --> 05:18.840
We'll call this ora ability and we'll use a cast to you or a gameplay ability and we're going to cast

05:18.840 --> 05:23.100
our ability spec, which means we need the ability spec first, don't we?

05:23.100 --> 05:25.210
So I'm going to move this line here.

05:25.210 --> 05:28.650
I'm going to control X, control V to paste it there.

05:28.860 --> 05:33.510
And what we're going to cast is ability, spec, dot, ability.

05:35.360 --> 05:43.430
So if our ability spec ability can cast to an aura ability, we now are able to get that aura ability

05:43.430 --> 05:46.300
and access startup input tag from it.

05:46.310 --> 05:52.850
So I'm going to take this line where we're trying to add a tag to dynamic ability tags, control X and

05:52.850 --> 05:59.060
control V right here and what we're going to add to it now, instead of using our ability spec, we're

05:59.060 --> 06:04.010
going to use aura ability and get that startup input tag.

06:04.010 --> 06:12.230
So now if we're looping through our abilities and if any of those are derived from aura gameplay ability,

06:12.260 --> 06:19.100
then we get that startup input tag and we add it right here to dynamic ability tags.

06:19.100 --> 06:22.420
And as soon as we've done that, we can then give the ability.

06:22.430 --> 06:27.980
Now we've seen that we can give the ability and activate it immediately with give ability and activate

06:28.010 --> 06:33.470
once that was just so we could prove to ourselves that the ability could be activated.

06:33.470 --> 06:35.700
So we're not going to use that anymore.

06:35.700 --> 06:38.040
We're just going to use give ability.

06:38.190 --> 06:46.290
So as soon as we've added that startup input tag to the ability specs, dynamic ability tags, we're

06:46.290 --> 06:48.330
then going to give that ability.

06:49.110 --> 06:54.990
So now our startup abilities as we give them to the character are going to have their startup input

06:55.020 --> 06:57.900
tag added to their dynamic ability tags.

06:57.930 --> 07:04.950
Now this is great because dynamic ability tags are designed to be added and removed at runtime so we

07:04.950 --> 07:07.050
can change this later if we want to.

07:07.610 --> 07:11.680
And Ryder's going to tell me that ability class can be made const.

07:11.690 --> 07:16.820
So to satisfy that little suggestion, I'm going to make that const.

07:16.850 --> 07:17.660
Why not?

07:17.750 --> 07:25.400
Okay, so now our start up abilities have in their dynamic ability tags, an input tag and all of our

07:25.400 --> 07:33.200
input tags start with input tag dot something so they're really easy to identify as input tags if their

07:33.200 --> 07:36.550
parent tag on the hierarchy has input tag.

07:36.560 --> 07:37.790
So that's great.

07:37.790 --> 07:43.970
That allows us to identify abilities and that's going to be crucial when we want to activate them.

07:43.970 --> 07:46.640
Now to activate them, what are we going to do?

07:46.640 --> 07:51.710
Well, here in our player controller, all we're doing so far is adding debug messages.

07:51.710 --> 07:58.970
But what we can do instead is to call some function on the ability system component passing in the input

07:59.000 --> 08:01.010
tag, telling the ability system component.

08:01.040 --> 08:07.860
Hey, we're pressing this input, so if you have any abilities with this input tag assigned, go ahead

08:07.860 --> 08:15.180
and activate them And the ability system component is going to see if we pass an input tag over that

08:15.180 --> 08:17.970
corresponds to one of its activatable abilities.

08:17.970 --> 08:21.450
Well, the ability system component can activate that ability.

08:21.450 --> 08:24.030
So I'm going to make a couple of functions.

08:24.030 --> 08:31.020
I'm going to make a function for when an input is pressed or held and a function for when an input is

08:31.020 --> 08:34.140
released for activating abilities.

08:34.140 --> 08:41.010
I'm really only concerned with when an input is held and released because if an input is pressed for

08:41.010 --> 08:47.760
the first time, well, that's kind of something we can know if we're holding an input based on whether

08:47.760 --> 08:50.280
or not an ability is activated.

08:50.280 --> 08:52.170
So I'm going to have two functions.

08:52.170 --> 08:58.080
We'll go back into our ability system component and these are going to be public and they'll be for

08:58.080 --> 08:59.460
activating abilities.

08:59.460 --> 09:08.720
So first we'll make a void function called ability input tag held and it's going to take a const gameplay

09:08.720 --> 09:09.410
tag.

09:11.160 --> 09:14.580
By reference, and this will be the input tag.

09:15.490 --> 09:21.160
And I'll have another function called ability input tag released.

09:22.060 --> 09:27.260
And it's also going to take a const reference to an input tag.

09:27.290 --> 09:30.400
Looks like I accidentally moved my semicolon there.

09:30.910 --> 09:36.070
Let's get it back to where it belongs so we can generate the definitions for these.

09:38.380 --> 09:46.490
And what we can do is call these functions from our player controller for ability input tag held.

09:46.510 --> 09:53.400
I'd like to access our ability system component and call its ability input tag pressed.

09:53.410 --> 10:01.630
So back in my aura player controller class, when our ability input tag held is called, I'd like to

10:01.630 --> 10:05.410
call ability input tag held on the ability system component.

10:05.560 --> 10:12.940
Now I don't want to have to cast every single time as ability input tag held may be called every frame

10:12.940 --> 10:14.550
and that can be expensive.

10:14.560 --> 10:22.090
So I'm going to go into aura player controllers and I'm going to rearrange my tabs up here just a little

10:22.090 --> 10:22.870
bit.

10:26.600 --> 10:27.500
There we go.

10:27.500 --> 10:29.580
And an aura player controller.

10:29.600 --> 10:35.870
I'm going to scroll down and I see that I don't have any variables to store my ability system component

10:35.870 --> 10:39.680
and I'd like one so I don't have to cast more than a single time.

10:39.680 --> 10:44.090
So I'm going to forward declare the aura ability system component.

10:44.090 --> 10:46.640
So you or a ability.

10:47.790 --> 10:53.400
System component will forward declare that and we'll make a pointer of this type.

10:53.400 --> 10:57.870
So down here under input config, we're going to say T object pointer.

10:59.880 --> 11:06.690
You are a ability system component and we'll call this aura ability system component and we'll give

11:06.690 --> 11:08.070
it a new property.

11:08.460 --> 11:10.770
And where are we going to set it?

11:10.800 --> 11:16.740
Well, I'd like to set it the first time we access it, so I'm going to make a function that returns

11:16.860 --> 11:18.450
a pointer to this.

11:18.450 --> 11:24.090
So you aura ability system component pointer, we're going to call this get ASC.

11:24.840 --> 11:28.080
We're going to generate a definition for it.

11:31.940 --> 11:39.590
And what we'll do is say if aura ability system component is a null pointer, which it will be the first

11:39.590 --> 11:48.830
time, then we're going to set our ability system component equal to the result of a cast to oral ability

11:48.830 --> 11:49.580
system component.

11:49.580 --> 11:51.740
So we'll only cast the first time.

11:51.740 --> 11:52.430
Right?

11:52.460 --> 11:55.720
So how are we going to get the ability system component?

11:55.730 --> 11:59.600
Well, we know several easy ways to do it right.

11:59.630 --> 12:06.080
One of the most convenient is to use the you ability system blueprint library.

12:07.140 --> 12:13.890
Function called get ability system component, which requires an actor and we can simply pass in our

12:13.890 --> 12:16.380
pawn controlled by this controller.

12:16.950 --> 12:18.690
We can use get pawn.

12:18.720 --> 12:22.140
Now, get pawn requires a template parameter type.

12:22.140 --> 12:23.850
We can use a pawn.

12:24.360 --> 12:26.190
So calling get pawn.

12:26.220 --> 12:32.430
Passing that into get ability system component gets us the ability system component and that can be

12:32.430 --> 12:36.090
simply cast to the aura ability system component.

12:36.120 --> 12:38.430
Now if we want one big line, we can do that here.

12:38.430 --> 12:43.740
We can simply cast to you aura, ability, system component.

12:43.770 --> 12:51.920
The result of this function and we can set aura ability system component equal to that.

12:51.930 --> 12:55.950
If you don't want such a long line, you can break it up into multiple lines.

12:55.950 --> 12:57.650
That would be fine as well.

12:57.660 --> 13:03.090
So either way, if the variable is null will attempt to get it.

13:03.120 --> 13:04.850
Now this cast could fail.

13:04.860 --> 13:06.760
This could be called too early.

13:06.760 --> 13:10.480
Perhaps the ability system component is not set yet.

13:10.480 --> 13:11.770
That's totally fine.

13:11.770 --> 13:17.620
That means this will return a null pointer because we're going to return aura ability system component.

13:17.620 --> 13:24.430
But as soon as this function is called for the first time that the ability system component on our pawn

13:24.430 --> 13:30.820
is valid, then we will get a valid ability system component and it won't be null from that point on.

13:30.820 --> 13:37.390
So get ask is a nice utility function we'll use here in the player controller and it will ensure that

13:37.390 --> 13:38.860
we only cast once.

13:38.860 --> 13:45.940
So when we get the ability system component from here in ability input tag held, then we won't be casting

13:45.940 --> 13:46.780
every frame.

13:46.900 --> 13:52.750
So what we're going to do is we're going to get ASC here and we know that this is an aura ability system

13:52.750 --> 13:53.260
component.

13:53.260 --> 14:00.250
So we can call ability input tag held, which requires the gameplay tag for our input.

14:00.280 --> 14:04.750
We're going to pass an input tag and for released we'll do the same thing.

14:04.750 --> 14:15.030
We'll say get ASC ability input tag released, passing in input tag now because get ASC could return

14:15.030 --> 14:21.990
a null pointer if we call it just too early in the game, we're going to say if get ASC.

14:23.990 --> 14:27.200
And we'll just check if it's a null pointer and return early.

14:28.960 --> 14:34.420
So we'll say if get ASC is null return and we'll do that in both of these.

14:34.570 --> 14:40.900
We don't want to do a check because it's possible we call this too soon, at which point we want to

14:40.900 --> 14:42.670
return and do nothing.

14:43.180 --> 14:43.840
Okay.

14:43.840 --> 14:46.750
And for now, ability input tag pressed.

14:46.750 --> 14:47.950
I'd like to do nothing.

14:47.950 --> 14:53.050
I'm just going to comment out the on screen debug message there.

14:53.140 --> 15:00.580
And now it's up to the ability system component itself to handle what happens when we press these inputs.

15:00.790 --> 15:03.910
So what is the ability system component going to do?

15:04.000 --> 15:11.220
Well, we know we're giving it at least one startup ability and we can set its startup input tag.

15:11.230 --> 15:17.980
So we want the ability system component to check to see if we have any activatable abilities associated

15:17.980 --> 15:19.400
with this input tag.

15:19.420 --> 15:23.390
And I'd like to activate them if they're not already active.

15:23.410 --> 15:28.930
So if they're already active, I don't want to activate them every single frame while we're holding

15:29.030 --> 15:29.780
input.

15:29.780 --> 15:31.990
So we're going to check to see if they're active.

15:32.000 --> 15:34.400
So we have a few things to do here.

15:34.670 --> 15:41.080
First, I'm going to check to make sure the input tag is valid, so I'm going to say if input tag dot

15:41.120 --> 15:46.920
is valid, we can do that with gameplay tags and if they're not valid, we can return and do nothing.

15:46.940 --> 15:53.480
After that I want to check to see if this ability system component has any activatable abilities with

15:53.480 --> 15:54.710
this input tag.

15:54.740 --> 15:55.880
So how do we do that?

15:55.880 --> 16:01.470
Well, we have a function that contains all of our activatable abilities.

16:01.490 --> 16:05.220
It's called get Activatable abilities.

16:05.240 --> 16:11.180
Now this returns a array of gameplay ability specs.

16:11.540 --> 16:17.060
Now Activatable abilities means abilities that we have that can be activated.

16:17.060 --> 16:22.760
And remember, we've seen lots of different gameplay tags that can block abilities and so on.

16:22.760 --> 16:26.780
So this is the way to get all abilities that we can activate.

16:26.810 --> 16:34.070
Now we can loop through these, so we're going to say for and first I'm going to say auto ref and say

16:34.070 --> 16:40.550
ability spec because these are ability specs I'm going to say for auto ability spec and get activatable

16:40.550 --> 16:41.540
abilities.

16:41.540 --> 16:42.740
And what is auto?

16:42.740 --> 16:45.440
Well it's an for gameplay ability spec.

16:45.470 --> 16:52.370
This is just kind of a lazy habit I have so I don't have to think about or type the data type for certain

16:52.370 --> 16:53.000
things.

16:53.000 --> 16:58.070
So we're looping through all the gameplay ability specs in activatable abilities.

16:58.070 --> 17:00.620
So we don't want to just activate them all.

17:00.620 --> 17:04.250
We want to activate any abilities that have the input tag.

17:04.250 --> 17:06.890
So we're going to check the input tags.

17:06.890 --> 17:09.920
We're going to say if ability spec.

17:11.190 --> 17:19.110
And we're going to get those dynamic ability tags and dynamic ability Tags is an gameplay tag container

17:19.110 --> 17:25.890
and therefore it has functions like has tag and has tag exact.

17:25.920 --> 17:30.390
We want to check for an exact match to see if it has the input tag.

17:31.210 --> 17:38.350
Now, in this case, we now have an ability in our activatable abilities that has the tag that our player

17:38.350 --> 17:39.700
controller passed over.

17:39.730 --> 17:42.560
That means we pressed that input, right?

17:42.580 --> 17:46.870
So now we want to activate it if it's not already active.

17:46.900 --> 17:48.070
So how do we check that?

17:48.070 --> 17:55.690
We can say if and we can get our abilities back and call is active, but we want to activate it if it's

17:55.690 --> 17:56.400
not active.

17:56.410 --> 18:02.250
So we're going to place the negation operator here and we're going to activate it only if it's not active.

18:02.260 --> 18:03.740
So how do we activate it?

18:03.760 --> 18:11.860
Well, the ability system can do that with tri activate ability and it requires a spec handle so we

18:11.860 --> 18:19.330
can take our ability spec and from that we can get the handle and that's how we can activate abilities.

18:19.330 --> 18:24.970
We have to call tri activate ability because there may be things that prevent the ability from being

18:25.000 --> 18:25.870
activated.

18:25.870 --> 18:29.380
So we have to try to activate it.

18:29.680 --> 18:37.640
Now abilities themselves have the concept of input being pressed or not pressed for those abilities

18:37.640 --> 18:44.300
and you can check at any time if an abilities input is being pressed or released and decide yourself

18:44.300 --> 18:45.680
what that means for you.

18:45.710 --> 18:53.000
An ability can be in the input pressed state or input not pressed state, and you can provide your own

18:53.000 --> 18:58.070
custom functionality or meaning for when its input is pressed and released.

18:58.530 --> 19:01.890
To tell an ability that its input is being pressed.

19:01.920 --> 19:05.280
We call the function and we'll put it right here.

19:05.910 --> 19:10.650
Ability spec input pressed and we have pressed and released.

19:10.680 --> 19:14.400
Now this requires the ability spec, so we're going to pass that in.

19:14.940 --> 19:16.680
And what does this do exactly?

19:16.680 --> 19:23.190
Well, it just basically sets a boolean on the ability spec that is keeping track of whether or not

19:23.190 --> 19:25.260
its particular input is pressed.

19:25.260 --> 19:28.780
And we can always go to the declaration or usages.

19:28.800 --> 19:30.690
Here's the implementation of it.

19:30.720 --> 19:34.530
We see that the ability spec itself has an input pressed.

19:34.560 --> 19:38.310
It's a uint8, so it's just a flag we can set it to.

19:38.310 --> 19:39.030
True.

19:39.030 --> 19:45.120
And then it checks itself to see if it's active and if it's a non instance ability.

19:45.120 --> 19:50.940
Well it just says for the spec get that ability and call input pressed on it.

19:51.090 --> 19:57.720
Otherwise if it's not a non instanced ability then this function gets all instances of the ability as

19:57.720 --> 20:01.720
there can be multiple and for each instance it's calling input pressed.

20:01.720 --> 20:05.380
So the ability itself has an input pressed function.

20:05.380 --> 20:11.890
We can go to that function if we want to see and we see that it's a virtual function that's not implemented.

20:11.890 --> 20:17.770
So you can implement something on your gameplay ability by overriding input pressed and input released

20:17.800 --> 20:22.680
if you want something to happen as a result of input being pressed and released.

20:22.690 --> 20:25.270
So there's a lot of customizability here.

20:25.300 --> 20:32.080
The takeaway here is that nothing is really happening other than we're just telling the ability, Hey,

20:32.080 --> 20:37.450
your input is being pressed right now and we're going to do that whether it's active or not.

20:37.450 --> 20:44.320
As long as we're holding the input down, we want the ability to know that its input is pressed and

20:44.320 --> 20:49.090
if the input is released, we want it to know, Hey, your input is released.

20:49.750 --> 20:54.520
So ability input tag released is going to be somewhat similar.

20:54.520 --> 21:00.250
I don't want to just end an ability if its input is released.

21:00.250 --> 21:06.130
I want the ability to determine that because not all abilities need to be canceled or ended when their

21:06.130 --> 21:08.670
ability is no longer pressed.

21:08.680 --> 21:12.430
Some abilities will just press the button and release it right away.

21:12.430 --> 21:17.590
And we don't want to necessarily end that ability as soon as it's released.

21:17.590 --> 21:23.440
All I really want to do here in this function is tell the ability itself, Hey, your input is not being

21:23.440 --> 21:30.610
pressed anymore, so we'll do something similar to what we did in input tag held is we'll copy these.

21:32.280 --> 21:33.600
We'll paste those lines.

21:33.600 --> 21:34.740
And what are we doing?

21:34.740 --> 21:37.380
Well, we're checking if the input tag is valid.

21:37.410 --> 21:46.470
We're looping through our activatable abilities and if the ability matches exactly with the input tag,

21:46.470 --> 21:47.310
what are we doing?

21:47.310 --> 21:52.770
Well, we don't want to activate the ability, so I'm going to remove this if statement and we don't

21:52.770 --> 21:58.350
want to call ability spec input pressed, we want to call ability spec input.

21:59.200 --> 22:03.370
Released and we pass in the ability spec.

22:03.700 --> 22:05.530
So that's all we want to do.

22:05.560 --> 22:09.670
Now our ability will know that its input is released.

22:09.910 --> 22:16.120
Okay, so really all we're doing is if we're pressing any of our inputs, if we have an activatable

22:16.120 --> 22:22.940
ability that's been granted with this input tag, it's going to be activated.

22:22.960 --> 22:26.740
So what we can do is we can test this out with our test ability.

22:26.770 --> 22:33.400
We can set that test abilities, start up input tag to one of our inputs and try to activate it.

22:33.400 --> 22:36.070
So let's hit debug and test this out.

22:37.410 --> 22:40.680
So what we can do is we can go into our ability.

22:40.680 --> 22:44.010
So that's going to be in blueprints, ability system.

22:44.040 --> 22:45.330
Gameplay abilities.

22:45.330 --> 22:51.840
And here's our test gameplay ability blueprint, which we are giving to our character at the beginning

22:51.840 --> 22:52.560
of the game.

22:52.560 --> 22:55.860
Now under input we have start up input tag.

22:55.860 --> 23:00.540
Now replicate input directly was an inherited variable.

23:00.540 --> 23:05.430
We already decided we're not going to use that, but it also happens to be in the category input.

23:05.460 --> 23:07.050
Now our start up input tag.

23:07.050 --> 23:14.760
We can choose an input tag and I'm going to choose the lab input tag and we know that that is associated

23:14.760 --> 23:18.810
with our left mouse button thanks to our input mapping context.

23:18.990 --> 23:24.690
So as soon as I press my left mouse button, I'm going to activate this ability because it will not

23:24.690 --> 23:31.380
be active yet and then it will be active and then after five seconds it will end itself.

23:31.380 --> 23:35.580
So I should only be able to activate it if it's not already active.

23:35.610 --> 23:37.770
Let's test that out.

23:37.770 --> 23:40.350
I'm going to save all and press play.

23:41.210 --> 23:43.040
And press the left mouse button.

23:44.320 --> 23:45.460
And nothing happened.

23:45.460 --> 23:47.020
So I'm going to debug this.

23:47.020 --> 23:54.070
I'm going to place a breakpoint here in ability input tag held just right there to see if we even have

23:54.070 --> 23:58.990
this function called I'm going to press play and left click and we're getting this far.

23:58.990 --> 23:59.980
That's great.

24:00.340 --> 24:04.570
Now this right here is our ability system component.

24:04.570 --> 24:10.330
And if we expand these dropdowns, we can see what our activatable abilities contains.

24:10.330 --> 24:13.480
We should have an activatable ability in there.

24:13.810 --> 24:18.940
Here's activatable abilities opening that we have under items.

24:18.940 --> 24:19.930
We have one.

24:19.930 --> 24:26.170
And if we expand further, we see we have the test gameplay ability.

24:26.410 --> 24:32.530
So we know we have an ability, which means we should make it into this for loop.

24:32.530 --> 24:38.590
So if we go ahead and continue, it looks like we did not make it that far.

24:38.590 --> 24:40.390
In fact, we didn't make it past the return.

24:40.390 --> 24:40.630
Why?

24:40.660 --> 24:44.180
Because look at that input tag is valid.

24:44.180 --> 24:47.090
That's something I do from time to time.

24:47.090 --> 24:49.640
If the input tag is valid, we're returning.

24:49.670 --> 24:53.240
We actually only want to return if the input tag is not valid.

24:53.240 --> 24:53.630
Right?

24:53.630 --> 24:57.440
So I'm going to go ahead and stop and fix this bug.

24:57.440 --> 24:59.600
It actually should be not is valid.

24:59.600 --> 25:02.240
Same thing for the released version.

25:02.240 --> 25:04.190
We're going to say not is valid.

25:04.190 --> 25:05.360
Then we return.

25:05.360 --> 25:06.800
Let's try this again.

25:07.740 --> 25:13.500
That's just one of those little things that you probably noticed right away and put the negation operator

25:13.500 --> 25:13.950
there.

25:14.980 --> 25:18.400
Okay, I'm going to go ahead and open up my test gameplay ability.

25:18.400 --> 25:24.130
I still have my left mouse button tag and if I press play and click, I get my message.

25:24.130 --> 25:27.730
Five seconds later, I should get my test ability ended.

25:27.730 --> 25:28.720
There it is.

25:28.870 --> 25:35.680
And I should only be able to activate this if it's not already active, so I can't spam it and that's

25:35.680 --> 25:36.370
great.

25:36.550 --> 25:41.590
And if I didn't have the delay, I should be able to spam it because it will end itself instantly.

25:41.590 --> 25:43.240
So let's try spamming it.

25:43.920 --> 25:44.610
There we go.

25:44.610 --> 25:51.090
In fact, we're spamming it even if I hold that button down because we're activating on ability input

25:51.120 --> 25:52.230
tag held.

25:52.260 --> 25:54.570
So that's something to be aware of.

25:54.600 --> 26:00.390
We could be activating an ability every single frame if we're ending it instantly, right?

26:00.390 --> 26:06.480
So something to be aware of, but our abilities are going to choose when they should end themselves.

26:06.480 --> 26:07.980
So that shouldn't be a problem.

26:07.980 --> 26:08.910
Okay, great.

26:08.910 --> 26:16.110
So we now have the ability, for lack of a better word, to activate abilities using input, and we're

26:16.110 --> 26:20.100
identifying those abilities based on their input tag.

26:20.100 --> 26:26.280
So there are a few moving parts to this, but it's actually really versatile and really well put together

26:26.280 --> 26:34.440
because we can associate abilities with their input tag and all we need to do is set the input tag for

26:34.440 --> 26:38.250
a given ability to assign it to that specific input.

26:38.250 --> 26:43.960
And we do that by having that input tag in the ability specs, dynamic ability tags.

26:43.960 --> 26:49.930
So if we were to remove the input tag from an ability specs dynamic ability tags, we'd no longer be

26:49.960 --> 26:52.990
able to activate it or deactivate it.

26:52.990 --> 27:00.130
And if we remove the input tag from dynamic ability tags and then add another input tag to its dynamic

27:00.130 --> 27:06.520
ability tags, then we can activate it using that other input associated with that other input tag.

27:06.640 --> 27:07.570
Excellent.

27:07.690 --> 27:14.200
So now that we can activate abilities and we know how to end them, we're all set up and ready to start

27:14.200 --> 27:17.530
really architecting some interesting abilities.

27:17.530 --> 27:19.660
So we'll do that in the videos to come.

27:19.660 --> 27:22.000
So great job and I'll see you soon.
