WEBVTT

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

00:07.800 --> 00:12.390
We now have a melee attack ability that draws debug spheres.

00:12.390 --> 00:13.880
How exciting.

00:13.890 --> 00:15.630
Now we want to do more than that.

00:15.630 --> 00:18.090
We want to cause damage at least.

00:18.090 --> 00:18.570
Right?

00:18.570 --> 00:22.230
So let's take a look at our current state.

00:22.260 --> 00:29.190
Our melee enemy comes up to us and hits us and we know that it's got all live players within radius

00:29.190 --> 00:34.410
because we're drawing a debug sphere at those players locations.

00:34.410 --> 00:35.790
So we have Aura.

00:35.820 --> 00:41.130
Now we want to cause damage, which means we want to apply a gameplay effect.

00:41.130 --> 00:48.540
And we know that our melee attack is based on aura melee attack, which is based on aura damage ability

00:48.540 --> 00:54.960
actually, or a damage gameplay ability is what it's called and that in turn is based on aura gameplay

00:54.960 --> 00:55.500
ability.

00:55.530 --> 01:03.270
Now, because of this inheritance hierarchy, we have a damage effect class that we can set and we've

01:03.270 --> 01:07.510
created this damage effect, which is actually pretty nice.

01:07.510 --> 01:11.470
I'm going to set this damage effect class to damage effect.

01:11.500 --> 01:12.160
Why?

01:12.190 --> 01:20.470
Because if we browse to it and open it up, we'll see that this is a gameplay effect with instant duration,

01:20.470 --> 01:22.360
with no modifiers.

01:22.360 --> 01:27.120
That takes a calculation class and we're using exec calc damage.

01:27.130 --> 01:34.690
Now, what exec calc damage does is it loops through all of the damage types that exist.

01:34.690 --> 01:42.940
So if we go to exec calc damage and take a look at execute implementation, we have this for loop that

01:42.940 --> 01:50.980
loops through the damage types to resistances map and we have damage types and resistance gameplay tags.

01:50.980 --> 01:57.310
And for each of these we attempt to get the set by caller magnitude for that damage type and then we

01:57.310 --> 02:02.470
add that to the damage that's going to be subtracted from the health of the target.

02:02.470 --> 02:09.550
So if we add a set by caller magnitude to a gameplay effect where the key is one of the damage types,

02:09.550 --> 02:13.300
it will be taken into account in this exact calc.

02:13.300 --> 02:20.440
And in fact the resistance will be captured from the target and we'll have a little bit of damage reduction

02:20.440 --> 02:21.790
for the resistance.

02:21.790 --> 02:31.390
So the cool thing is all we have to do is use this G damage type and apply a set by caller magnitude

02:31.390 --> 02:32.080
to it.

02:32.080 --> 02:34.270
So that's pretty handy.

02:34.270 --> 02:42.490
So really all we'd have to do is create a gameplay effect spec so we can use make outgoing spec and

02:42.490 --> 02:46.450
notice that the ability class, the gameplay ability has a function.

02:46.450 --> 02:48.820
Make outgoing gameplay effects spec.

02:48.850 --> 02:54.700
We've seen that we can take an ability system component and call make outgoing spec, but the ability

02:54.700 --> 02:58.930
itself has this function make outgoing gameplay effects spec.

02:58.960 --> 03:04.420
Now that's because the ability knows how to access its own ability system component.

03:04.420 --> 03:05.920
It's smart enough to do that.

03:05.920 --> 03:11.740
Now we can use a gameplay effect class and our class default has damage effect class.

03:11.740 --> 03:19.120
If we search for it damage effect class, we can get it because we exposed it to the event graph and

03:19.120 --> 03:21.250
we can set its level if we like.

03:21.250 --> 03:27.970
We're going to leave it at one because our damage gameplay effect does not depend on level at all.

03:28.120 --> 03:34.150
Now, once we've created the outgoing gameplay effects spec, we can apply a set by caller magnitude

03:34.780 --> 03:41.800
by calling, assign tag set by caller magnitude and that requires a gameplay tag.

03:41.800 --> 03:49.150
Now, if this is a melee attack, then the set by caller magnitude will take the damage type tag and

03:49.150 --> 03:54.100
that damage type tag will be damage physical because it's a melee attack.

03:54.160 --> 03:57.530
Now we also need to know how much damage to cause, don't we?

03:57.550 --> 04:03.730
Well, we do have in our class defaults damage types, which is an array.

04:03.730 --> 04:12.910
And in the array we can add an element and each element has a key that's a gameplay tag and a value

04:12.910 --> 04:14.740
that's a scalable float.

04:14.770 --> 04:16.810
The key is going to be the damage type.

04:16.810 --> 04:21.310
So we're going to add physical here and the value is going to use a curve table.

04:21.310 --> 04:27.100
Now we have CT damage, but we have to select a curve and we only have a curve for Firebolt.

04:27.100 --> 04:32.200
So what we can do is we can add a curve for damage for Melee.

04:32.200 --> 04:39.010
Now it's up to you if you want multiple damage curves for melee, for different types of warriors,

04:39.010 --> 04:44.530
you can get as complex as you like with this, but I'm going to browse to CT damage and I'm going to

04:44.530 --> 04:47.110
add a curve and I'm going to call this curve.

04:47.110 --> 04:57.010
I'm going to rename it to Abilities Dot Melee, and I'm just going to add a new key here for level one

04:57.400 --> 05:00.610
and it's going to be five.

05:00.610 --> 05:02.530
And I'm going to zoom out.

05:02.830 --> 05:04.450
I'm going to add another key.

05:04.480 --> 05:06.100
It's going to be for level.

05:06.150 --> 05:12.410
To and I'd like it to be 7.5 damage like that.

05:12.420 --> 05:17.310
And I think I'll go ahead and just make one last key.

05:17.550 --> 05:25.670
It's going to be for level, let's say 40 and we'll make it 50 damage.

05:25.680 --> 05:27.930
So we have a trend like this.

05:28.140 --> 05:32.340
And if we want, we can make this a smooth curve by changing it to auto.

05:32.370 --> 05:36.330
If we want to do that and we can even mess with it.

05:36.330 --> 05:39.690
So it looks something like this, that's fine.

05:39.690 --> 05:46.500
But now we have a damage curve for melee, so we can save this and go back to melee attack and we can

05:46.500 --> 05:48.480
select the melee curve.

05:48.990 --> 05:51.660
And now we have our damage types.

05:51.660 --> 05:58.470
So what we could do here is we can loop through damage types and we can assign the set by column magnitude.

05:58.470 --> 06:04.320
So this is something that I think should be just inherent in or a damage gameplay ability.

06:04.320 --> 06:10.680
There should just be a function called cause damage that will loop through all of our damage types.

06:10.680 --> 06:18.540
It will take an effect spec and assign all the set by column magnitudes and just apply that gameplay

06:18.540 --> 06:21.360
effect to some target.

06:21.360 --> 06:24.780
I think that that is something that we should just have built in.

06:24.780 --> 06:32.760
So what we can do is we can go into aura damage gameplay ability and we can make a function here for

06:32.790 --> 06:33.390
that.

06:33.390 --> 06:40.440
This can be a public function and it's going to just be a function for causing damage.

06:40.440 --> 06:47.280
So we're going to say void cause damage and it'll just take an actor pointer called Target.

06:47.310 --> 06:49.090
We'll call it Target actor.

06:49.090 --> 06:51.370
Now this will be a new function.

06:51.370 --> 06:57.490
I'm going to make it blueprint callable and cause damage is going to take care of all that stuff that

06:57.490 --> 06:58.690
I was just talking about.

06:58.690 --> 07:01.150
Loop over all of the damage types.

07:01.180 --> 07:04.330
We have this team map called damage types.

07:04.390 --> 07:11.920
I'd like to loop over all of the pairs in this and assign a set by color magnitude to an effect spec.

07:11.920 --> 07:15.950
So the first thing I need to do is make that effect spec, right?

07:15.970 --> 07:22.030
So we saw that the gameplay ability class has make outgoing gameplay effects spec.

07:22.060 --> 07:27.880
This requires a gameplay effect class and our damage gameplay ability has that.

07:27.880 --> 07:30.970
It's a damage gameplay effect class.

07:30.970 --> 07:32.800
We're going to pass that in.

07:33.130 --> 07:35.590
It requires a level.

07:35.590 --> 07:42.700
We're not going to worry about a level we're going to pass in one and we'll store this in a local variable

07:42.700 --> 07:44.890
and it's a spec handle.

07:44.890 --> 07:49.090
So we're going to say EF gameplay effect spec handle.

07:50.160 --> 07:57.990
We'll call it damage spec handle and we just need to loop over our damage.

07:58.890 --> 07:59.550
Types.

07:59.600 --> 08:00.360
Team map.

08:00.360 --> 08:11.760
So we're going to say for we know this is a T tuple and it's mapping F gameplay tag to a scalable float,

08:11.760 --> 08:12.170
right?

08:12.210 --> 08:13.860
F scalable float.

08:16.980 --> 08:21.750
So we're going to call this pair and it's in damage types.

08:22.590 --> 08:29.220
And for each of these pairs, we're going to assign a set by caller magnitude using this gameplay tag

08:29.220 --> 08:30.300
for damage type.

08:30.300 --> 08:37.460
Now we assign a tag set by caller magnitude with you ability system blueprint library.

08:37.470 --> 08:45.870
So we get that include included and we're going to call assign tag set by caller magnitude, which requires

08:45.870 --> 08:46.530
a spec handle.

08:46.530 --> 08:48.900
We're going to pass in damage spec handle.

08:49.050 --> 08:57.030
It requires a gameplay tag we're going to pass in pair key and the last input is the magnitude itself.

08:57.030 --> 09:03.240
So we need a float called damage magnitude and we can get that from our scalable float.

09:03.270 --> 09:04.380
Now how do we do that?

09:04.380 --> 09:08.760
Well, if we go back to Aura Projectile Spell, we can see how we did it there.

09:08.790 --> 09:10.830
We looped through damage types.

09:10.860 --> 09:19.000
We got a const float called Scaled Damage and we evaluated the curve at the level of the ability.

09:19.150 --> 09:24.580
I'm just going to copy that line and come back to our damage ability and just paste it here.

09:24.580 --> 09:30.880
So we'll just call it scaled damage and we'll pass that in as the magnitude.

09:30.880 --> 09:39.490
So we're looping through all the damage types that exist in our map of tags to scalable floats in our

09:39.490 --> 09:40.300
ability.

09:40.390 --> 09:46.630
And once we've done all that, we can apply that ability to the target actor.

09:46.840 --> 09:50.950
So we need the ability system component of the target actor of course.

09:50.950 --> 09:59.350
So we're going to access you ability system blueprint library, get ability system component passing

09:59.350 --> 10:05.170
in target actor So we have the ability system component and then we can apply the gameplay effect.

10:05.380 --> 10:12.910
Now we can apply the gameplay effect to self on this ability system component, or we can get the ability

10:12.910 --> 10:20.290
system component that owns this ability with get ability system component from actor info and from this

10:20.290 --> 10:26.140
we can call apply gameplay effect spec to target.

10:26.140 --> 10:32.320
And for this function we pass in the gameplay effect spec and the ability system component.

10:32.350 --> 10:42.160
So for the effects back we have our spec handle we need to take damage spec handle dot data dot get

10:42.190 --> 10:46.240
remember data is the gameplay effect spec and that's a pointer.

10:46.240 --> 10:51.880
So we have to dereference it and for the AC we're going to pass in the target AC.

10:52.850 --> 10:59.150
And this function will then result in applying that damage gameplay effect to the target.

10:59.360 --> 11:05.150
So now that we have this cause damage function, we can call it here in our gameplay effect.

11:05.150 --> 11:07.850
So we don't need these three nodes anymore.

11:07.880 --> 11:12.920
All we have to do is call it here, but I have to close the editor and compile and launch again.

11:12.920 --> 11:18.710
So I'm going to save all and run this from writer hitting debug.

11:20.390 --> 11:24.230
And we'll go ahead and open up our melee attack.

11:24.230 --> 11:30.200
And as we loop through all the live players within radius, we can cause damage.

11:30.410 --> 11:34.750
So we have our now blueprint callable function caused damage.

11:34.760 --> 11:40.100
We'll do this in the loop body to all players within radius using the array element.

11:40.100 --> 11:43.470
That's the actor passing that in.

11:43.490 --> 11:45.950
We don't need the actor location anymore.

11:45.980 --> 11:49.040
We're now causing damage instead.

11:49.040 --> 11:56.140
And because our class defaults are set, we have our damage types, we have our damage effect class.

11:56.150 --> 12:01.880
We should see five damage being caused with each hit of the spear.

12:01.910 --> 12:03.320
Let's save this.

12:03.620 --> 12:06.560
Let's save all actually and press play.

12:06.560 --> 12:10.580
And let's let that enemy come over and hit us and look at our health globe.

12:10.610 --> 12:13.190
Hopefully it changes and it does.

12:13.190 --> 12:22.090
So as we get hit from the spear, we see our damage be taken and our health goes down.

12:22.110 --> 12:24.150
Now, here's the cool thing.

12:24.180 --> 12:30.690
This enemy starts off at level one, but if we change that, let's search for level and its details

12:30.690 --> 12:34.380
panel and I change it to say 40.

12:34.440 --> 12:41.250
Well, we know that our gameplay ability is granted at the level of the enemy, which means this melee

12:41.250 --> 12:49.040
attack will now be level 40 and at level 40 we should be causing 50 damage thanks to our handy slider

12:49.050 --> 12:52.110
for the preview for this scalable float.

12:52.110 --> 12:56.100
So let's see if we take 50 damage now.

12:58.410 --> 13:02.280
Here comes the little guy and boom, 50 damage.

13:03.420 --> 13:04.380
Excellent.

13:05.670 --> 13:06.300
All right.

13:06.300 --> 13:11.010
So I'm going to stick this guy's level down, back to one, and we're done.

13:11.010 --> 13:16.980
Now, there's one actually, last thing that I noticed is that we're not actually getting those floating

13:17.010 --> 13:20.010
text damage numbers when Aura gets hit.

13:20.010 --> 13:22.260
So let's just find out why real quick.

13:23.430 --> 13:27.200
Now we're showing the damage numbers in aura attributes set.

13:27.210 --> 13:33.750
So if we go to Aura, attribute set and take a look at show floating text, let's see why we're not

13:33.750 --> 13:36.960
getting auras damage numbers when she gets hit.

13:37.550 --> 13:40.670
Well, for one, we're checking the source character.

13:40.670 --> 13:42.980
That's the character causing the damage.

13:43.010 --> 13:46.610
The Target character is the character getting hit.

13:46.610 --> 13:51.620
So we're actually using the player controller of the source character.

13:51.620 --> 13:56.870
We're actually casting that to or a player controller that will fail for the enemies.

13:56.870 --> 14:01.370
So we actually need to do this for the target character as well.

14:01.370 --> 14:08.000
So if the source character cast to or a player controller fails, then we won't make it inside this

14:08.030 --> 14:09.020
if statement.

14:09.020 --> 14:14.540
And if that happens, I'd like to cast for our target character.

14:14.540 --> 14:18.110
So I'm going to copy the If statement, but change what we're casting.

14:18.110 --> 14:23.450
We're going to cast Target character instead and then everything else will be the same.

14:23.450 --> 14:30.500
And if we make it into the first if statement, well, that means that the source character is the player

14:30.500 --> 14:31.490
controlled character.

14:31.490 --> 14:34.100
So we don't need to continue at that point.

14:34.100 --> 14:35.340
We'll just return.

14:35.360 --> 14:42.810
So if we make it inside here, we'll show the damage number because the damage causer is the player

14:42.810 --> 14:44.100
controlled character.

14:44.100 --> 14:50.070
But if we don't make it inside this one, that means the damage causer is an enemy, at which point

14:50.070 --> 14:53.160
we'll cast the target of the damage.

14:53.160 --> 14:56.850
We'll get that player controller and show the damage number for that.

14:56.850 --> 14:58.680
So this should fix everything.

14:58.680 --> 15:02.760
We should see damage numbers when Ora gets hit by a goblin.

15:02.760 --> 15:03.780
Let's try it out.

15:04.970 --> 15:08.210
Okay, I'm going to go ahead and press play and get hit.

15:08.940 --> 15:10.650
And there's the damage number.

15:10.650 --> 15:15.960
Looks like we're suppressing some of that damage because we have some physical damage, resistance.

15:15.960 --> 15:18.930
And this is physical damage, after all.

15:18.970 --> 15:21.000
Looks like I just got a block there, too.

15:21.030 --> 15:21.750
Cool.

15:22.110 --> 15:23.040
All right.

15:23.040 --> 15:25.340
So things are looking pretty good.

15:25.350 --> 15:29.730
We still have some work to do and we'll continue with this in the next video.

15:29.850 --> 15:31.020
I'll see you soon.
