WEBVTT

00:01.330 --> 00:06.640
Okay, so you're sitting at your desk and the project manager for your video game walks up and says,

00:06.640 --> 00:10.390
hey, lovely developer, I need knockback.

00:10.480 --> 00:15.190
And you look at your project manager and say, uh, what's knockback?

00:15.280 --> 00:17.050
And the PM says knockback.

00:17.080 --> 00:22.230
You know, when an enemy gets hit, it flies in the air, kind of like the death impulse.

00:22.240 --> 00:24.820
And you say, oh, knockback.

00:24.820 --> 00:25.620
Right.

00:25.630 --> 00:28.410
And your PM says, that's right, knockback.

00:28.420 --> 00:33.700
I need knockback and I know that you are capable of implementing that.

00:33.760 --> 00:39.970
The project manager then proceeds to tell you more details that you don't really know, such as well,

00:39.970 --> 00:47.140
damage abilities should have a knockback magnitude and when taking damage if it's not fatal knockback.

00:47.140 --> 00:53.800
And just so we have knockback well defined, it's when you launch the character into the air when they

00:53.800 --> 00:54.610
get hit.

00:54.610 --> 00:59.590
So for when an enemy takes fatal damage we have the death impulse, right?

00:59.590 --> 01:04.270
But when damage is not fatal, we are going to have a knockback.

01:04.270 --> 01:12.280
Now there should be a knockback chance that could be a parameter, and we can use that knockback chance

01:12.280 --> 01:17.710
to see if there was a successful knockback and then some damage abilities will not have knockback,

01:17.740 --> 01:20.590
their knockback chance will be zero, and so on.

01:20.620 --> 01:24.160
Now before your turns and walks away they say.

01:24.160 --> 01:29.530
Oh, and by the way, here's a hint use launch character and not add impulse.

01:29.530 --> 01:36.370
And then they turn and walk away, at which point you turn to your coworker and say, hey, why should

01:36.370 --> 01:39.000
we use launch character instead of add impulse?

01:39.010 --> 01:45.550
And your coworker turns to you and says, well, I think it's because you can use launch character without

01:45.550 --> 01:51.760
having to simulate physics and ragdoll the character and you say, oh, okay, that makes sense.

01:51.880 --> 01:55.780
So for this quest, you're going to implement knockback.

01:55.810 --> 02:00.730
There are a lot of steps to this, and you may find yourself needing to make some of the decisions,

02:00.730 --> 02:02.320
but I think you're capable of it.

02:02.320 --> 02:06.220
So pause the video and conquer knockback now.

02:09.440 --> 02:11.750
Okay so we need knockback.

02:11.780 --> 02:14.480
I'm going to start in the ability.

02:14.480 --> 02:20.150
So I'm going to close all tabs and go to my aura damage gameplay ability.

02:20.360 --> 02:23.720
So I'll go ahead and get the header file open.

02:24.140 --> 02:28.790
And I'm going to add a couple of parameters for knockback.

02:28.820 --> 02:34.670
Now we have a death impulse magnitude I'm going to have a knockback force magnitude.

02:34.670 --> 02:40.790
So whereas death impulse is an impulse are knockback is going to be a force.

02:40.790 --> 02:44.600
So I'm going to say knockback force magnitude.

02:46.020 --> 02:51.060
And it turned out that 60 was too low for death impulse.

02:51.060 --> 02:54.750
So I'm going to set those both to a thousand.

02:56.100 --> 02:59.400
But we'll almost certainly need to tweak this.

02:59.430 --> 03:02.220
Now we can also have a knock back chance.

03:02.220 --> 03:07.980
So if we want to do that we can say float, knock back chance.

03:08.790 --> 03:12.270
And I'm going to set it to zero by default.

03:12.270 --> 03:17.790
So it's more like something you enable rather than something that's enabled by default.

03:18.580 --> 03:22.060
If it's zero, then there's no need for knockback.

03:22.540 --> 03:26.170
Okay, so now we have a knockback magnitude.

03:26.170 --> 03:33.610
And just like death impulse, we're going to have a couple of parameters in our damage effect params.

03:33.700 --> 03:37.610
And that's going to be in our aura ability types.

03:37.630 --> 03:39.280
So let's open that.

03:40.990 --> 03:48.520
And right here in damage effect params, we're going to go ahead and add not only a knockback force

03:48.520 --> 03:52.090
magnitude, but a knockback force vector.

03:52.090 --> 03:56.470
So I'm just going to copy both the death impulse magnitude and death impulse.

03:56.470 --> 04:00.250
And this will be knockback force magnitude.

04:01.930 --> 04:04.820
By the way, it's okay if you didn't call yours the same.

04:04.840 --> 04:06.910
You could have just said knock back magnitude.

04:06.910 --> 04:07.990
That's totally fine.

04:07.990 --> 04:11.880
And instead of death impulse, we're going to have knock back force.

04:11.890 --> 04:13.420
A force is a vector.

04:13.900 --> 04:14.290
Okay.

04:14.290 --> 04:16.120
So we have those properties.

04:16.150 --> 04:20.740
Now we know that we're going to need something in the effect context right.

04:20.740 --> 04:22.600
For the knock back force.

04:22.690 --> 04:29.290
So really what we're going to do is just copy the knock back force here and paste it down in our effect

04:29.290 --> 04:32.070
context, just under death impulse.

04:32.080 --> 04:39.250
And once we have this set in the in the effect context, we know that it's going to have the correct

04:39.250 --> 04:41.100
magnitude by this time.

04:41.140 --> 04:46.210
Now because we have knock back force, we're going to have to handle it in.

04:46.210 --> 04:47.380
Net serialize.

04:47.380 --> 04:51.510
And by this point this is a pretty well known process.

04:51.520 --> 04:55.840
We're going to take the next bit in our rep bits.

04:55.840 --> 04:57.010
That's going to be 15.

04:57.010 --> 05:00.040
We're going to flip that bit and we're checking knock back force.

05:00.040 --> 05:02.380
Now to see if it's zero.

05:02.380 --> 05:06.400
And then we come down and check if that bit was flipped.

05:07.260 --> 05:09.660
Just like we did with Death Impulse.

05:10.200 --> 05:12.450
So we're checking the 15th bit.

05:13.460 --> 05:19.010
And then we're taking knockback force and calling net serialize on it.

05:19.040 --> 05:20.150
Piece of cake.

05:20.900 --> 05:26.830
And we have to make sure that we don't forget to scroll back up to serialized bits.

05:26.840 --> 05:33.380
And now that we're flipping 15 bits, we have to serialize all 15 of those bits.

05:33.380 --> 05:39.170
So this is something that we'll have to come back to each time we add to the effect context and update

05:39.170 --> 05:40.070
that as well.

05:40.430 --> 05:41.120
Okay.

05:41.390 --> 05:45.680
Now our effect context is going to need a getter and setter for this.

05:45.680 --> 05:52.940
So we're going to make a getter that returns an f vector called get knockback force.

05:53.660 --> 05:56.630
And it's going to return knockback force.

05:57.260 --> 06:02.090
And we'll have a setter void set knockback force.

06:04.130 --> 06:09.050
Which takes a const f vector reference called enforce.

06:11.640 --> 06:15.450
And we'll set knockback force equal to n force.

06:17.150 --> 06:18.890
And we have those now.

06:18.920 --> 06:24.330
Now we also are going to want a couple functions on our ability system library.

06:24.350 --> 06:27.020
So we'll go up to get death impulse.

06:27.230 --> 06:28.580
We'll copy it.

06:29.350 --> 06:32.920
We'll paste it and we'll have get knockback force.

06:35.170 --> 06:41.680
And we can go ahead and define this and we'll define it just like get death impulse.

06:42.280 --> 06:47.170
The only difference is we're going to call get knockback force on the effect context.

06:47.170 --> 06:51.370
And then we can scroll down to get set death impulse.

06:51.370 --> 06:55.900
And we can make one for set knockback force.

06:55.900 --> 06:58.990
So we'll call it set knockback force.

06:58.990 --> 07:02.290
And we'll call the input parameter in force.

07:02.440 --> 07:06.160
And we'll go ahead and generate the definition.

07:06.160 --> 07:08.770
Looks like Ryder gave me an inline one.

07:08.770 --> 07:12.460
So I'm going to cut it and put it into the cpp file.

07:12.550 --> 07:14.590
We're going to find set death impulse.

07:14.620 --> 07:18.430
We'll copy set knockback force just underneath it.

07:18.790 --> 07:23.830
Copy the contents from Set Death Impulse and change this to.

07:24.860 --> 07:25.310
Set.

07:25.340 --> 07:27.910
Knockback force passing in.

07:27.920 --> 07:29.510
In force.

07:30.540 --> 07:33.720
Now we have those functions on the ability system library.

07:34.200 --> 07:35.430
Okay, great.

07:35.460 --> 07:41.760
Next we need to make sure that our effect params carries that knockback force magnitude.

07:41.760 --> 07:46.130
And then also that we set the knockback force in it when we should set it.

07:46.140 --> 07:49.370
So back to aura damage gameplay ability.

07:49.380 --> 07:54.960
We're going to go into the cpp file to make damage effect params from class defaults, and we'll set

07:54.960 --> 07:56.420
that knockback force.

07:56.430 --> 07:59.460
We'll get it from the ability.

07:59.460 --> 08:07.530
So we're going to say params dot knockback force equals knockback force magnitude.

08:07.770 --> 08:10.320
And in fact we have to set the magnitude.

08:10.320 --> 08:15.060
Actually knockback force magnitude equals knockback force magnitude.

08:15.060 --> 08:18.690
Now we also have the knockback force chance right.

08:18.690 --> 08:21.480
We also made a knockback chance actually.

08:21.480 --> 08:25.560
So we could add that as well in aura ability types.

08:25.560 --> 08:33.000
In damage effect params we can just add another float for the knockback chance also.

08:33.000 --> 08:40.380
So I'm going to go ahead and make that two knockback chance equals zero.

08:41.930 --> 08:47.330
And we'll set that here in make damage effect params from class defaults.

08:47.330 --> 08:50.780
So we'll say params dot knockback chance.

08:52.430 --> 08:54.230
Equals knockback chance.

08:56.560 --> 08:57.460
There we go.

08:58.400 --> 09:05.780
So now we can start the whole thing rolling by setting the knockback force in the effect context.

09:05.780 --> 09:09.130
And I'm going to do this in the aura projectile.

09:09.140 --> 09:11.840
So I'm going to go ahead and get that open.

09:12.350 --> 09:17.390
I'll get the CP file open for it or a projectile.

09:17.840 --> 09:19.550
And we'll see that right here.

09:19.550 --> 09:21.320
We're setting death impulse.

09:21.470 --> 09:24.020
We can also set the knockback force.

09:24.140 --> 09:30.230
Let's calculate that though we're going to say const f vector knockback force.

09:30.910 --> 09:34.000
Equals get actor forward vector.

09:36.280 --> 09:37.270
Times.

09:37.270 --> 09:37.990
Damage effect.

09:37.990 --> 09:38.560
Params.

09:38.770 --> 09:39.340
Knockback.

09:39.340 --> 09:40.180
Force.

09:40.300 --> 09:41.680
But here's the thing.

09:41.680 --> 09:43.570
We have a knockback chance, don't we?

09:43.600 --> 09:46.090
So what we should do is roll the dice.

09:46.090 --> 09:48.970
We should see if we should get a knockback.

09:48.970 --> 09:56.650
So we're going to say const bool be knockback equals f math rand range.

09:58.940 --> 10:00.680
From 1 to 100.

10:01.640 --> 10:04.520
We'll see if that's less than damage effect params.

10:04.730 --> 10:05.330
Knockback.

10:05.330 --> 10:06.350
Chance.

10:06.650 --> 10:10.310
And we'll only do this if b knockback is true.

10:10.340 --> 10:17.750
So if B knockback is true, then we should calculate knockback force and we can take our damage effect

10:17.750 --> 10:20.570
params dot knockback force.

10:20.570 --> 10:24.020
And we can set that here equal to knockback force.

10:24.050 --> 10:30.590
Then when we call apply damage effect we'll be passing in the knockback force along with that.

10:30.590 --> 10:37.490
So that's only if we got a successful knockback and then apply damage effect can handle what happens.

10:37.490 --> 10:47.200
So an aura ability system library we can go into apply damage effect and we can set that knockback force.

10:47.210 --> 10:49.430
We'll do it right after setting the death impulse.

10:49.430 --> 10:51.170
So set knockback force.

10:51.350 --> 10:58.700
We'll get the effect context handle and we'll get damage effect params dot knockback force.

10:58.700 --> 11:01.580
So now that's set on the context handle.

11:01.700 --> 11:06.770
At that point we'll be applying the damage effect with a knockback force.

11:06.770 --> 11:13.220
And the last piece of this puzzle is to use that knockback force in the attribute set.

11:13.250 --> 11:20.570
Of course we need to add the capability there of using it, but we can go to the attribute set and at

11:20.570 --> 11:24.050
least find out where we should be reacting here.

11:24.050 --> 11:30.170
So I'm going to go into aura attribute set dot cp find handle incoming damage.

11:30.170 --> 11:31.130
Here it is.

11:31.130 --> 11:33.800
And find where we have be fatal.

11:33.800 --> 11:37.970
And right here is where we do the death impulse stuff.

11:37.970 --> 11:41.780
And in the else case is where we can do the knockback force.

11:41.780 --> 11:47.870
So we're doing the effects dot hit react while there hit reacting.

11:47.900 --> 11:50.360
They might be knocking back right.

11:50.360 --> 11:52.850
But we could also take over.

11:52.850 --> 11:56.330
Make sure they don't hit react if there's a knockback force.

11:56.330 --> 11:57.410
But that's up to us.

11:57.410 --> 11:58.780
It doesn't really matter.

11:58.790 --> 12:03.050
The the animations being played while in knockback while in the air.

12:03.050 --> 12:05.900
That just depends on what we want to be played.

12:05.900 --> 12:13.220
But either way, we're going to handle knockback here, and what we need to do is see if that knockback

12:13.220 --> 12:16.130
force is greater than zero.

12:16.130 --> 12:22.070
So we're going to check if and we're going to get that effect context.

12:22.070 --> 12:25.310
So from props we'll get the effect context handle.

12:25.310 --> 12:28.100
And how do we get that knockback force.

12:28.130 --> 12:30.530
Actually we have a function for that.

12:30.530 --> 12:35.900
So I'm going to cut what I just wrote and use your aura ability system library.

12:35.900 --> 12:41.240
Get knockback force passing in the effect context handle.

12:42.410 --> 12:47.690
Now this returns actually a knockback force which is a vector.

12:47.690 --> 12:53.630
So I'm just going to make a const f vector reference called knockback force.

12:54.380 --> 12:56.600
And I'll just set that equal to this.

12:56.600 --> 13:00.620
That way I don't have too long of a conditional in here.

13:00.620 --> 13:06.050
And then I'm going to check the knockback force and see if it's not zero.

13:06.050 --> 13:11.300
So I'll get knockback force and I'll call I'll use is nearly zero.

13:11.480 --> 13:13.460
And I'll put a tolerance in there.

13:13.460 --> 13:18.290
Something that's small but not that small, something like ten.

13:18.290 --> 13:26.810
So if knockback force is near zero with this tolerance, we could even make it smaller like one.

13:26.810 --> 13:31.310
Either way, if it's almost zero, we won't get into this if statement.

13:31.310 --> 13:34.910
But if it is zero, then we know what we can do.

13:34.910 --> 13:36.410
We can launch the character.

13:36.410 --> 13:43.220
Now in this case we have the character already and the function launch character is already on the character

13:43.220 --> 13:44.030
class.

13:44.030 --> 13:49.550
So we could just take props, dot target character and simply call launch character on it.

13:49.550 --> 13:52.370
No need to go through the trouble to make interface functions.

13:52.370 --> 13:54.050
If you did, that's fine.

13:54.470 --> 13:58.490
It was good practice, but you don't actually need to.

13:58.490 --> 14:05.150
In this case, you can just call launch character directly on the character and pass in launch velocity,

14:05.180 --> 14:12.680
we're going to pass in knockback force for the launch velocity and x y override along with z override.

14:12.680 --> 14:15.890
This is how we can control the knockback force a little bit.

14:15.890 --> 14:21.320
If we wanted to launch the character in the x y direction, we would pass in true.

14:21.320 --> 14:25.850
And if we don't want to launch the character in the Z, we would pass in false there.

14:25.850 --> 14:31.130
But I do want to launch the character in the Z as well, so I'm going to pass in both true true for

14:31.130 --> 14:32.270
launch character.

14:32.270 --> 14:38.390
Now this is going to be basically in the direction that the Firebolt was flying.

14:38.390 --> 14:44.030
But I'd like knockback to have a little bit of a pitch override.

14:44.120 --> 14:51.020
In other words, I like my knockback force to be angled up just a bit so we could really enjoy seeing

14:51.020 --> 14:52.940
those enemies fly all around.

14:52.940 --> 14:57.950
And for that reason, I'm going to go back to Aura Projectile when we're setting our.

14:58.090 --> 14:59.490
Knockback force.

14:59.500 --> 15:06.550
And as we got our actor forward vector here, we can rotate that actors forward vector.

15:06.640 --> 15:16.330
I'd like to say const f vector knockback direction equals get actor forward vector.

15:16.360 --> 15:23.260
But on this vector I'm going to call rotate angle axis, which will allow me to rotate the vector about

15:23.260 --> 15:25.420
some axis by some angle.

15:25.420 --> 15:30.550
And I'd like to rotate it upward by oh say 45 degrees.

15:30.550 --> 15:36.190
And the axis I'd like to rotate it about is the right vector.

15:36.220 --> 15:38.310
Get actor right vector.

15:38.320 --> 15:46.000
And if we want this to be a basically pitch override completely, we could zero out the forward vector.

15:46.000 --> 15:47.500
So that's one way to do it.

15:47.500 --> 15:52.240
But we could also say get actor rotation.

15:52.600 --> 15:56.230
And from that rotation we can get the vector.

15:56.230 --> 15:59.800
And if we want it get actor rotation.

15:59.800 --> 16:03.820
We could create an F rotator called rotation.

16:04.150 --> 16:09.730
And we could take this rotation dot pitch and set it to 45 degrees.

16:09.730 --> 16:12.520
So it's pointing 45 degrees up.

16:12.520 --> 16:17.080
And then we could take that knockback direction and make it out of rotation.

16:17.080 --> 16:22.000
We could say that knockback direction equals rotation vector.

16:22.210 --> 16:23.410
That would work too.

16:23.410 --> 16:28.600
And then we could take knockback direction and use it instead of the forward vector for our fireball.

16:28.600 --> 16:30.220
That's another thing we could do.

16:30.220 --> 16:34.240
And I'm just seeing now that I use knockback force.

16:34.330 --> 16:38.140
This should actually be knockback force magnitude, right?

16:38.140 --> 16:45.610
Because otherwise we'd be setting knockback force to knockback force times knockback direction.

16:45.610 --> 16:47.590
Knockback force is a zero vector.

16:47.590 --> 16:49.360
So we'd be setting this to zero.

16:49.690 --> 16:52.600
So now we're setting this to a knockback force.

16:52.630 --> 16:54.310
Let's go ahead and test this out.

16:55.520 --> 16:56.060
Okay.

16:56.060 --> 17:00.890
So let's go into Firebolt and let's change the knockback chance to 100.

17:01.250 --> 17:03.890
So 100% chance to knock back.

17:03.890 --> 17:05.570
And let's just see what happens.

17:07.220 --> 17:08.570
Ooh, look at that.

17:10.340 --> 17:11.780
Awesome.

17:13.720 --> 17:15.030
All right.

17:15.040 --> 17:16.930
Oh, and I just realized something.

17:16.930 --> 17:22.870
If we have knockback now, enemies can fly over, and we need to take care of that, don't we?

17:22.900 --> 17:29.470
Either the enemy should die shortly after falling off the edge, or they should just bounce and come

17:29.470 --> 17:30.310
back in.

17:30.430 --> 17:35.590
I personally like the option of having them bounce and come back in, because if you can knock an enemy

17:35.590 --> 17:40.000
over and kill them that way, it's kind of something that could be exploited in a way.

17:40.000 --> 17:42.760
So I kind of don't like that possibility.

17:42.760 --> 17:46.630
But there goes an enemy and he's flying away and his head's on fire.

17:46.660 --> 17:47.890
Cool.

17:47.890 --> 17:53.020
So okay, so knockback force magnitude of 1000 is a bit much.

17:53.020 --> 17:55.900
I think we can put it to 500 or so.

17:55.900 --> 18:01.840
And if we set the knockback chance down to say 20, then we won't always get a knockback.

18:01.840 --> 18:03.760
But every once in a while we will.

18:04.650 --> 18:06.060
Pretty cool.

18:06.620 --> 18:10.550
Now if we want to see knock back on aura two, we can do that.

18:10.550 --> 18:18.800
And all we'd have to do is go into blueprints, ability system, enemy abilities and check out melee

18:18.800 --> 18:22.460
and ranged attack and give them a knockback chance.

18:22.460 --> 18:30.020
I'd like the melee attack to maybe have a knockback chance of 20 with a knockback force magnitude of

18:30.020 --> 18:31.040
500.

18:31.070 --> 18:32.780
We'll do the ranged attack.

18:32.930 --> 18:39.350
The ranged attack will be a knockback chance of 10% knockback force magnitude of 400.

18:39.350 --> 18:47.630
But before we go on and move on with our lives, I'm going to set the melee knockback chance to 100

18:47.630 --> 18:51.470
just for testing and see what aura looks like knocked back.

18:53.550 --> 18:56.520
Okay not seeing the knockback happen.

18:57.260 --> 19:01.040
Oh, and of course, we're not setting the knockback vector, are we?

19:01.070 --> 19:06.050
We're only setting the knockback vector in the projectile on sphere overlap.

19:06.050 --> 19:10.070
So it's up to us to set that knockback force.

19:10.070 --> 19:17.420
So for example, here in melee attack, if we're about to say cause damage for example, that would

19:17.420 --> 19:20.570
be a good spot to set that knockback force.

19:20.570 --> 19:25.370
So here we have cause damage in the aura damage gameplay ability.

19:25.460 --> 19:26.870
Why don't we take a look at that.

19:26.870 --> 19:31.880
Let's go to Aura Damage gameplay ability I'm going to find cause damage.

19:31.880 --> 19:32.920
Here it is.

19:32.930 --> 19:38.570
So here is where we know we're going to cause damage.

19:38.570 --> 19:45.740
This would be an appropriate place to perhaps do it, but rather than just setting a knockback force

19:45.740 --> 19:51.320
for every damage gameplay ability, I'd like this to be custom per damage gameplay ability.

19:51.320 --> 19:58.430
So really cause damage would be a little bit easier to work with when it comes to setting things like

19:58.430 --> 20:04.010
parameters on the effect context, it would be a lot easier if caused damage could take in an effect

20:04.010 --> 20:05.030
context.

20:05.030 --> 20:10.580
So if we go back to our Aura ability system library, for example, and look at applied damage effect,

20:10.610 --> 20:11.390
we'll see that.

20:11.390 --> 20:14.000
First we make an effect context handle.

20:14.000 --> 20:14.540
Right.

20:14.540 --> 20:23.420
And then we make a spec handle using not only the damage gameplay effect class, but also the ability

20:23.420 --> 20:26.120
level and the effect context handle.

20:26.120 --> 20:34.160
So making a spec handle this way we could specify the effect context using an effect context handle.

20:34.160 --> 20:41.390
So using that cause damage function, we kind of bypass the effect context altogether.

20:41.780 --> 20:45.650
So there are a number of ways we can handle something like this.

20:46.260 --> 20:52.800
For one, we could make some damage effect params and we can go through the pipeline we created for

20:52.800 --> 20:55.980
aura projectile, namely make these params.

20:55.980 --> 21:05.430
First we can set the target for our damage effect and then we can use our ability system blueprint library

21:05.430 --> 21:07.710
function apply damage effect.

21:07.800 --> 21:13.380
If we wanted to make it a little bit easier to set that knockback force and any other things that we

21:13.380 --> 21:14.130
want to set.

21:14.130 --> 21:21.570
So really, if we're going to make a damage effect params from class defaults, we could expose this

21:21.570 --> 21:22.830
function to blueprint.

21:22.830 --> 21:26.640
For example, we can make it a blueprint pure.

21:28.540 --> 21:30.790
Why don't we see what happens if we do that?

21:30.790 --> 21:34.290
So I'm going to go ahead and close the editor.

21:34.300 --> 21:39.940
We'll save everything first and we'll launch after having made this blueprint here.

21:39.940 --> 21:46.690
And once we have damage effect params, we know that the ability system library has applied damage effect.

21:46.810 --> 21:49.360
So we could go about this a number of ways.

21:49.510 --> 21:56.830
We can make those damage effect params in blueprint, expose them to blueprint and set that knockback

21:56.830 --> 22:00.730
force in blueprint and then call Apply Damage effect in blueprint.

22:00.730 --> 22:05.470
Or we could make a blueprint callable function to do all of that for us.

22:05.590 --> 22:07.510
I'd like to show both solutions.

22:07.660 --> 22:12.700
So in aura ability types I'd like to expose all of these to blueprint.

22:12.700 --> 22:15.850
So I'll make them all blueprint read right.

22:15.850 --> 22:25.630
So for world context object damage effect class source ASC and target ASC base damage ability level

22:25.660 --> 22:35.110
damage type debuff chance debuff damage duration, frequency, impulse magnitude, death impulse, knockback

22:35.110 --> 22:39.160
force magnitude, knockback force chance, and knockback force.

22:39.160 --> 22:45.640
Now we could set those in the blueprint if we wanted to, but in addition to that, I'd like a function

22:45.640 --> 22:47.650
that can do all this for us.

22:47.650 --> 22:54.310
In fact, we can calculate that knockback force at least its direction if we know the knockback force

22:54.310 --> 23:03.880
magnitude and the effect params based on the avatar actor's location and the target actor's location.

23:03.880 --> 23:04.660
Right?

23:04.660 --> 23:11.350
In other words, what we could do is we could have a function on or a damage gameplay ability like this.

23:11.350 --> 23:19.270
Make damage effect params from class defaults that takes the target actor if it's not a null pointer,

23:19.270 --> 23:26.050
and calculates the knockback direction and the death impulse direction, and then if we don't set those

23:26.050 --> 23:32.680
later and overwrite them, then they'll at least have direction set for them.

23:32.680 --> 23:34.840
So here's what I'm going to do.

23:34.840 --> 23:40.780
If target actor is not a null pointer, then way down here.

23:41.200 --> 23:45.190
First we'll check if we'll see if it's valid is valid.

23:45.220 --> 23:47.710
Target actor first and foremost.

23:47.740 --> 23:56.650
And if it is valid, then I'd like to calculate a direction from the enemy to the target actor.

23:56.710 --> 24:03.100
Now the enemy is going to be the avatar actor of the owning ability system component.

24:03.100 --> 24:07.780
So we can call get avatar actor from actor info.

24:07.900 --> 24:14.830
And I'd like to get a vector from the avatar to the target, which will be a const f vector.

24:14.860 --> 24:27.040
We'll call it to target and it'll be target actor get actor location minus get avatar actor from actor

24:27.040 --> 24:29.440
info get actor location.

24:33.470 --> 24:35.960
Now this is not a normalized vector.

24:35.960 --> 24:42.830
So I'm going to wrap it in parentheses and call get safe normal.

24:43.850 --> 24:51.470
So we have a two target which is a normalized vector with the direction from the avatar to the target.

24:51.650 --> 24:57.500
Now if we wanted to give it a pitch override we could we could do it in a number of ways.

24:57.500 --> 25:02.210
We could make this a f rotator called rotation.

25:02.210 --> 25:04.910
And instead of calling get safe normal.

25:06.550 --> 25:15.280
We could call rotation, take rotation pitch and set that to 45.

25:16.360 --> 25:17.680
Just override it.

25:17.680 --> 25:20.650
That could be a parameter and the damage effect params.

25:20.650 --> 25:23.110
And then we can say const f vector.

25:24.190 --> 25:27.940
To target equals rotation vector.

25:29.460 --> 25:31.110
That's something we could do.

25:31.110 --> 25:34.350
And then we could set our knockback force and our death impulse.

25:34.350 --> 25:39.300
If we like, we can say params dot death impulse.

25:39.300 --> 25:43.560
We'll do that first equals to target.

25:44.640 --> 25:55.710
Times death impulse magnitude and we can say params dot knockback force equals to target times knockback

25:55.710 --> 25:57.090
force magnitude.

26:00.440 --> 26:08.720
So really, we're just making this set those directions to a default with a pitch override of 45 from

26:08.720 --> 26:12.770
the avatar to the target, but only if that target actor is set.

26:12.770 --> 26:15.980
And then we wouldn't have to go in and set it right.

26:15.980 --> 26:22.490
So we know that these will be set, of course, for the fireball we override those, but at least they're

26:22.490 --> 26:24.800
set by default if there is a target.

26:25.010 --> 26:33.800
So what I'm going to do in the melee attack here is I'm going to call make damage effect params from

26:33.800 --> 26:35.030
class defaults.

26:35.030 --> 26:40.250
And I know that this has a knockback force, but I exposed these parameters.

26:40.250 --> 26:45.080
If I wanted to say break damage effect params, I could.

26:45.110 --> 26:51.590
I could expand it and see all of them and if I wanted, I could drag off of one and say make damage

26:51.590 --> 27:00.110
effect params and then I could go in and take my knockback force and calculate it here in blueprint.

27:00.110 --> 27:06.710
If I wanted to do that, and then plug it in right here and then anything that I want to take from what's

27:06.710 --> 27:14.030
created by this function here, which we made blueprint pure, we could just pass it on in and overwrite

27:14.030 --> 27:17.480
anything here that we want to overwrite like this.

27:17.480 --> 27:20.120
So I figured I'd show you this way too.

27:20.150 --> 27:22.100
So we have flexibility in blueprint.

27:22.100 --> 27:28.100
But at the same time I know my knockback force is set so I don't have to break it.

27:28.100 --> 27:33.560
After all, I can just take it and then we can use an ability system component.

27:33.590 --> 27:38.330
Apply damage effect is what it's called and that takes the damage effect params.

27:38.330 --> 27:43.850
We have it there and when we make the damage effect params from class defaults.

27:43.850 --> 27:48.500
Here in the for loop we have the array element which is our target actor.

27:48.500 --> 27:50.660
We are passing in to cause damage.

27:50.660 --> 27:56.480
Now we can pass that in to make damage effect params from class defaults and instead of causing damage

27:56.480 --> 28:02.810
with cause damage, we can cause damage with apply damage effect on the ability system blueprint library.

28:02.810 --> 28:05.900
And now we know the knockback force will be applied.

28:05.900 --> 28:07.910
So let's test that out.

28:11.470 --> 28:17.980
Boom, and we have a knock back and we can do the same thing for the ranged attack as well.

28:17.980 --> 28:25.660
So the ranged attack, I believe, is spawning a projectile actually, and that is using spawn projectile

28:25.660 --> 28:30.580
on the aura projectile spell, which is actually making those effect parameters.

28:30.580 --> 28:33.220
So we could set a knockback force of 100 here.

28:33.220 --> 28:37.360
And we should see that knockback force from the slingshot rocks.

28:38.000 --> 28:39.050
And we do.

28:39.410 --> 28:40.200
Cool.

28:40.220 --> 28:46.400
So now that we know that's working, the only thing left is, well, it kind of looks funny for aura

28:46.400 --> 28:47.570
when she's in the air.

28:48.110 --> 28:48.680
Right.

28:48.680 --> 28:52.790
I'm not a big fan of her doing the running animation while she's in the air.

28:52.820 --> 28:54.650
We need to fix that.

28:54.650 --> 28:56.240
And we'll fix that real quick too.

28:56.270 --> 29:00.530
So we'll go to assets, characters, aura animations.

29:00.530 --> 29:03.980
And no, we need to go to blueprints.

29:03.980 --> 29:05.090
Character.

29:05.090 --> 29:05.990
Aura.

29:07.250 --> 29:08.070
AB aura.

29:08.090 --> 29:09.050
That's what I need.

29:09.080 --> 29:10.940
Her animation blueprint.

29:10.940 --> 29:17.110
And in the event graph, we should be calculating whether or not Ora is in the air.

29:17.120 --> 29:19.580
And we can get that from character movement.

29:19.940 --> 29:23.540
So I'm just going to make this a sequence node.

29:25.310 --> 29:31.280
The first thing we do is the stuff that we're doing here set the ground speed and should move.

29:31.460 --> 29:38.900
But in addition to this, I'd like to get the character movement and call is falling, and if is falling

29:38.900 --> 29:41.750
is true, then we'll use a different animation.

29:41.750 --> 29:46.640
So I'm going to promote this to a variable called is falling.

29:47.320 --> 29:49.090
And we'll be setting that too.

29:49.510 --> 29:56.440
And then we can go into main states, and we can have a state here for when or is in the air.

29:56.620 --> 30:00.580
So if or is in the air I want to play an in air animation.

30:00.580 --> 30:01.600
Here's one.

30:01.600 --> 30:03.610
I think this one will work.

30:03.610 --> 30:07.450
So I'm going to go ahead and drag that in and get a state machine for in air.

30:07.690 --> 30:14.130
And really if aura is falling, if that is falling Boolean is true.

30:14.140 --> 30:20.170
I want to transition into an air whether we're idling, whether we're running either one.

30:20.170 --> 30:22.120
I want a transition to in air.

30:22.150 --> 30:30.310
Now I could drag from idle to an air and from running to in air and add the same transition rule is

30:30.310 --> 30:31.600
falling for those.

30:31.600 --> 30:32.860
That's one way.

30:32.860 --> 30:35.980
Another way is to right click and use a state alias.

30:36.010 --> 30:40.510
We can call this to in air and bring it into an air.

30:40.510 --> 30:45.670
And then to an air can serve as an arrow coming from any number of nodes.

30:45.670 --> 30:48.310
By checking the checkboxes over here.

30:48.310 --> 30:54.760
So if we check running an Idle then this is the same as having two arrows coming to an air, both of

30:54.760 --> 30:57.220
which will have the same transition rule.

30:57.460 --> 31:03.490
Now I can open that transition rule and I can use is falling for that.

31:03.730 --> 31:05.440
So that makes it easier.

31:05.470 --> 31:08.560
Of course we need to transition out of in air.

31:08.860 --> 31:12.460
So if we're no longer falling we'll transition back.

31:12.460 --> 31:15.220
And this can be for is falling.

31:15.220 --> 31:17.200
Not so not boolean.

31:18.630 --> 31:20.490
We can transition there.

31:21.330 --> 31:28.170
We could even have a to idol as well if we wanted one of those, and then we could transition to idol

31:28.170 --> 31:29.430
from any states.

31:30.290 --> 31:31.610
I'll just show you what that looks like.

31:31.610 --> 31:40.280
We'll just do a state alias called to idle, and this goes to idle, and it'll have that transition

31:40.280 --> 31:40.970
rule there.

31:41.000 --> 31:44.900
That's fine if you want to do it either way, I'm just going to have one here.

31:44.900 --> 31:50.870
And use is falling with a not boolean hooked in there.

31:52.500 --> 31:54.780
And now when is falling?

31:54.930 --> 31:56.340
We should see.

31:57.400 --> 31:58.120
There we go.

31:58.150 --> 31:59.170
We're in the air.

32:00.250 --> 32:01.210
All right.

32:01.680 --> 32:02.100
Now.

32:02.100 --> 32:05.160
It's a little annoying when the enemies have 100% knockback.

32:05.190 --> 32:06.660
That's not what I want.

32:06.690 --> 32:08.550
That's just for testing purposes.

32:08.550 --> 32:10.800
We'll be setting that knockback chance down.

32:10.800 --> 32:17.190
And realistically, for games you would have like 0% knockback chance for most of your enemies and then

32:17.190 --> 32:19.890
some of your special enemies would have knockback, right?

32:19.950 --> 32:23.220
So you don't have to have knockback on all enemies.

32:23.220 --> 32:29.770
You could subclass your abilities for individual enemies and set those parameters differently for them.

32:29.790 --> 32:35.520
I'm going to have a knockback chance of, let's say 10% for the ranged attacker, but the knockback

32:35.520 --> 32:41.490
force magnitude could be a little higher 500 and the melee attack can have a knockback chance.

32:41.490 --> 32:47.280
And that's going to be probably, I'd say 1,520%.

32:47.550 --> 32:49.800
And with that we have knockback.

32:49.800 --> 32:52.410
And knockback works both ways.

32:52.410 --> 32:54.750
And auras.

32:54.750 --> 32:56.670
Firebolt spell.

32:56.940 --> 32:59.970
I'd like to have at least a little bit more knockback than that.

33:03.950 --> 33:08.870
So in GA firebolts knockback chance, I think 20 actually is fine.

33:08.870 --> 33:14.000
We'll leave it at 20 and 20% of the time we'll see them knock back.

33:16.010 --> 33:17.630
There was a knock back.

33:17.780 --> 33:18.680
Great.

33:18.800 --> 33:24.740
And the last, last, last thing I know, this lecture is getting long, but the very last thing is

33:24.740 --> 33:28.940
I wanted to make sure that enemies can't fly off the map.

33:28.940 --> 33:32.060
And for that, I'm going to get a blocking volume.

33:33.870 --> 33:35.400
So I'm going to get volumes.

33:35.400 --> 33:36.960
We're going to get a blocking volume.

33:36.960 --> 33:45.090
I'm going to drag one in and I'm just going to go to perspective top and get that blocking volume.

33:46.520 --> 33:47.960
Right about there.

33:48.200 --> 33:51.680
I don't want it encroaching into the play area.

33:51.680 --> 33:53.090
So it's going to be here.

33:55.300 --> 33:57.580
And I'm going to make it this big.

33:57.760 --> 34:00.430
I'm going to duplicate it and bring one down here.

34:01.120 --> 34:06.430
I'm going to duplicate it again with snapping on and bring one up here.

34:07.470 --> 34:08.660
And one here.

34:08.670 --> 34:12.570
I just don't want them flying off the edge, that's all.

34:12.600 --> 34:16.950
So going back to perspective, we can see we got some blocking volumes.

34:16.980 --> 34:21.810
Oh and I'm going to need to make them bigger in the Z dimension as well.

34:21.810 --> 34:24.360
So I'll go ahead and select all four.

34:25.580 --> 34:27.500
Not that volume.

34:31.700 --> 34:33.890
One, two, three.

34:35.630 --> 34:40.640
For press R and we'll scale them up nice and big.

34:45.020 --> 34:46.040
That should do it.

34:46.740 --> 34:53.520
And with that now we won't have the problem of enemies flying off the edge.

35:02.450 --> 35:03.310
All right.

35:03.320 --> 35:07.250
Awesome job in this lecture and I'll see you in the next one.
