WEBVTT

00:06.860 --> 00:07.970
Welcome back.

00:08.150 --> 00:11.490
We now have a hit React and that's a gameplay ability.

00:11.510 --> 00:18.770
I'd now like to implement death for when an enemy has its health reduced down to zero.

00:18.800 --> 00:26.030
In other words, here in the attributes set when be fatal is true, we want to call some sort of function

00:26.030 --> 00:27.920
for the character to die.

00:28.070 --> 00:32.370
Now, death is something that ora and enemies should share.

00:32.390 --> 00:35.960
So I'd like to add a function to the combat interface.

00:35.960 --> 00:43.910
So I'm going to go ahead and close all tabs for now and open the interaction folder and get my combat

00:43.910 --> 00:45.470
interface open here.

00:45.470 --> 00:48.870
And I'm going to declare a new function here.

00:48.890 --> 00:54.200
It's going to be a virtual function void, and I'm going to call it Die.

00:54.500 --> 01:01.700
I'll go ahead and make it a pure virtual function so that it has to be implemented and we'll first implement

01:01.700 --> 01:04.520
this in our character base.

01:04.640 --> 01:10.620
So I'm going to go into the character folder and open or a character base and all the way up at the

01:10.620 --> 01:13.440
top, I'm going to override it here.

01:13.470 --> 01:18.300
Virtual void die override, and we can handle what happens here.

01:18.480 --> 01:21.570
Now, in Die, I'd like to drop the weapon.

01:21.570 --> 01:23.310
That's something we can do in Die.

01:23.310 --> 01:25.620
But I'd also like to ragdoll the enemy.

01:25.620 --> 01:29.880
This allows us to get away with not really needing to play a death montage.

01:29.880 --> 01:32.000
We know how to play montages.

01:32.010 --> 01:38.280
In fact, we could just make a death gameplay ability that does pretty much the same thing that our

01:38.280 --> 01:39.480
hit React does.

01:39.660 --> 01:44.500
But for death, I'm going to decide to implement this differently.

01:44.520 --> 01:47.190
I'd like to ragdoll the enemy instead.

01:47.220 --> 01:52.570
Now, if we ragdoll the enemy, we're going to need to do things on the server and on the client.

01:52.590 --> 01:57.510
So for that reason I'm going to create a multicast RPC.

01:58.520 --> 02:02.900
So this function is going to also be a virtual function.

02:02.930 --> 02:04.490
Virtual void.

02:04.550 --> 02:09.290
And I'm going to call this multicast handle death.

02:10.140 --> 02:16.190
So we can override this in child classes if we want to do things in child classes specifically.

02:16.200 --> 02:23.880
But this is going to be what we use to handle what happens on all clients whenever a character dies.

02:23.910 --> 02:26.160
Now this needs to be a new function.

02:26.160 --> 02:34.410
If we're going to make this a multicast RPC, we need to add net multicast to the function and specify

02:34.410 --> 02:37.140
whether it should be reliable or unreliable.

02:37.260 --> 02:39.720
I think death should be reliable.

02:39.840 --> 02:46.260
Now I'm going to implement this function and when I generate the definition, writer is going to make

02:46.260 --> 02:51.930
the definition have implementation that's required for the multicast RPC.

02:51.960 --> 02:58.350
It has to have that implementation there so we can handle what happens on all machines, client and

02:58.350 --> 03:06.150
server in the multicast handle death implementation and then the die function can handle what happens

03:06.150 --> 03:10.690
specifically on the server and then we'll only call die on the server.

03:11.050 --> 03:18.220
So the die function is going to call multicast handle death so we can put that there.

03:18.520 --> 03:23.020
And before we call multicast handle death, we can detach the weapon.

03:23.020 --> 03:31.300
I'd like to drop the weapon so we can take that weapon variable and call detach from component.

03:31.930 --> 03:40.930
And this requires f detachment transform rules so we can make one f detachment transform rules and the

03:40.930 --> 03:43.000
F detachment transform rules.

03:43.000 --> 03:47.200
Struct has a constructor that requires an E detachment rule.

03:47.470 --> 03:52.450
I'm going to pass one in so E detachment rule I'm going to use keep world.

03:52.570 --> 04:02.050
So the weapon can keep the world transform and we have a bool be in call modify that we can pass in

04:02.050 --> 04:03.130
true for.

04:03.490 --> 04:10.360
So this will result in detaching the weapon and that detachment is something that will automatically

04:10.360 --> 04:12.550
be a replicated action.

04:12.550 --> 04:17.380
So if we detach on the server, we don't have to detach on clients.

04:17.380 --> 04:23.770
But there are a number of things I want to do that we can't just do on the server we have to do on the

04:23.770 --> 04:25.000
server and clients.

04:25.000 --> 04:30.190
That's why we're calling multicast handle death and in multicast handle death.

04:30.190 --> 04:33.350
This is where I'd like to ragdoll the character.

04:33.350 --> 04:38.330
In other words, simulate physics for the character and the weapon for that matter.

04:39.050 --> 04:42.020
So in multicast, handle death, we're going to take the weapon.

04:42.020 --> 04:45.290
We're going to call, set, simulate physics passing in.

04:45.290 --> 04:46.040
True.

04:46.040 --> 04:48.020
And I'm going to enable gravity.

04:48.020 --> 04:51.710
So we're going to call, set, enable gravity passing in.

04:51.710 --> 04:55.150
True, making sure that that weapon drops.

04:55.160 --> 05:00.470
Now, we can also enable collision for the weapon as it's not going to have collision.

05:00.470 --> 05:02.990
We've set that to no collision by default.

05:02.990 --> 05:09.380
But now we can set collision enabled and we can pass in collision enabled.

05:10.520 --> 05:17.180
And we can choose physics only as we don't really care about any spatial queries, no overlap events,

05:17.180 --> 05:18.170
anything like that.

05:18.170 --> 05:19.570
We just want physics.

05:19.580 --> 05:24.020
Now our weapon provided that it has a physics asset.

05:24.020 --> 05:28.430
If it's a skeletal mesh, which it is, we'll bounce around on the ground.

05:28.430 --> 05:30.380
And that's the effect I'm going for.

05:30.650 --> 05:36.650
Now I'd like to ragdoll the mesh as well, which means I'm going to need to call, get mesh and enable

05:36.650 --> 05:41.060
gravity on the mesh so we can call, set, enable gravity.

05:41.090 --> 05:43.160
We can enable physics as well.

05:43.160 --> 05:44.330
So get mesh.

05:46.020 --> 05:49.170
Set simulate physics passing in.

05:49.170 --> 05:49.500
True.

05:49.500 --> 05:51.040
And just to be consistent.

05:51.060 --> 05:55.380
I'm going to call, set, simulate physics first, just like I did up here with the weapon.

05:55.380 --> 05:57.660
It doesn't matter which order we call these in.

05:58.620 --> 06:04.290
And what I'd like to do is get the capsule and disable collision for the capsule.

06:04.290 --> 06:11.790
So I'm going to call get capsule component and call set collision enabled.

06:11.790 --> 06:12.690
Passing in.

06:12.900 --> 06:14.150
Collision enabled.

06:14.160 --> 06:15.300
No collision.

06:17.640 --> 06:25.020
So that way the capsule will not be blocking other characters or other objects from passing through

06:25.050 --> 06:25.380
it.

06:25.410 --> 06:32.340
Now, in addition to this, I'd like to use set collision enabled passing in physics only for the mesh

06:32.340 --> 06:33.150
as well.

06:33.180 --> 06:39.360
So we'll do all the things we want to do to the mesh first before messing with the capsule.

06:39.390 --> 06:48.180
So after set enabled gravity, we'll call, get mesh and call set collision enabled using physics only.

06:48.180 --> 06:54.180
So we'll go ahead and do that as the mesh has no collision by default, just like the weapon.

06:54.940 --> 07:01.660
And I'd like to set the collision response to the world static channel for the mesh to block.

07:01.690 --> 07:12.280
So we're going to call get mesh, set, collision response to channel and we'll use EC world static

07:12.580 --> 07:16.210
as that's going to be the walls and the floors and things like that.

07:16.240 --> 07:23.530
We're going to set the response to block and then later, if we wish to implement some kind of impulse,

07:23.530 --> 07:27.280
then we can fling the body in a specific direction.

07:27.280 --> 07:29.980
So that's something we can think about doing later.

07:29.980 --> 07:32.920
But for now, we're just ragdolling the enemy.

07:33.430 --> 07:40.060
So now we have this nice interface function, Di and it's implemented here in Aura Character base.

07:40.090 --> 07:47.470
We can override it to get additional behavior in child classes such as Aura Enemy, for example.

07:47.470 --> 07:49.180
And I'd like to do that as well.

07:49.190 --> 07:55.970
I'm going to copy virtual void die override from the character base and go into Aura Enemy.

07:56.150 --> 08:00.890
And here for the combat interface, I'm going to override die.

08:01.550 --> 08:03.380
We're going to generate the definition for it.

08:03.410 --> 08:04.940
We do want to call super Die.

08:04.970 --> 08:07.100
There's lots of good stuff happening there.

08:07.370 --> 08:11.110
But for the enemy, I'd like to set its lifespan.

08:11.120 --> 08:18.740
So we're going to call set lifespan and we can set the lifespan to some value, say five seconds, or

08:18.740 --> 08:25.660
we can make this a parameter on the enemy and set it to that, since parameters in general are better,

08:25.670 --> 08:28.670
let's just really quickly add a parameter.

08:28.670 --> 08:35.750
We'll copy base, walk speed and we'll create a float called Lifespan.

08:36.110 --> 08:42.860
We'll set it to five by default and I'd like this to be edit anywhere.

08:44.610 --> 08:48.210
And we'll leave it at Blueprint read only it can be in category combat.

08:48.240 --> 08:49.530
That's fine.

08:49.530 --> 08:52.500
And we'll use this here in Die.

08:52.710 --> 08:59.010
So we're going to set the lifespan and then call super die, which will result in the ragdolling.

08:59.610 --> 09:00.360
Okay.

09:01.200 --> 09:06.000
I'm going to compile really quick just to make sure there aren't any compiler errors that I may have

09:06.000 --> 09:06.780
missed.

09:08.350 --> 09:09.790
And it looks like we're good.

09:09.880 --> 09:17.230
So now we have an interface function that we can use, and I'd like to use this in my attribute set.

09:17.230 --> 09:20.920
So I'm going to go into Ora attribute set dot CPP.

09:21.340 --> 09:25.030
And here we know if the damage caused was fatal.

09:25.330 --> 09:30.430
If it is fatal, then we can easily call that interface function.

09:30.850 --> 09:33.850
Now let's take a look at our props struct.

09:33.850 --> 09:37.210
It's called f effect properties.

09:37.540 --> 09:42.780
Now we didn't bother adding a pointer to the interface, the combat interface.

09:42.790 --> 09:44.000
That's fine.

09:44.020 --> 09:49.060
We can call this function if the target actor implements the interface.

09:49.180 --> 09:52.450
So here's what I'll do is I'll say if be fatal.

09:54.560 --> 09:56.420
And then we'll have an else case.

09:56.810 --> 10:03.020
And then this stuff that was in the if not be fatal that can go just in the else case.

10:03.230 --> 10:08.360
And then we don't have to check if not be fatal, we can just check if be fatal.

10:08.480 --> 10:10.380
Then here we're fatal.

10:10.400 --> 10:12.710
Otherwise we're hit reacting.

10:12.710 --> 10:17.060
And if we're fatal, we can get the target actor from props.

10:17.090 --> 10:20.930
Props Dot, Target, Avatar actor.

10:21.170 --> 10:23.750
And we can see if it implements the interface.

10:24.200 --> 10:27.020
So we can say I combat interface.

10:29.170 --> 10:33.250
Combat interface equals cast to AI.

10:33.280 --> 10:34.720
Combat interface.

10:36.010 --> 10:37.600
And we'll cast props.

10:37.930 --> 10:38.440
Target.

10:38.440 --> 10:39.010
Avatar.

10:39.010 --> 10:39.730
Actor.

10:42.760 --> 10:53.590
And if the thing being damaged is a combat interface, we can call combat interface die just like that.

10:53.740 --> 10:58.840
And then once damage is fatal, we should see the character ragdoll.

10:58.870 --> 11:01.460
So now we can compile and test this out.

11:01.480 --> 11:08.350
But our firebolt has ability level one, so it's only doing five damage.

11:08.440 --> 11:14.560
We can up the amount of damage we're doing so we can test death a little easier by going to abilities

11:14.560 --> 11:16.480
or a projectile spell.

11:16.480 --> 11:24.740
And instead of passing in the ability level again, we can pass in a higher value for our scaled damage.

11:24.760 --> 11:32.050
Why don't we pass in a value of, say, ten and that way we'll have a higher value for damage and we

11:32.050 --> 11:34.240
can get to that death a lot easier.

11:34.540 --> 11:39.850
So let's compile and launch this and see if we can trigger that death function.

11:41.390 --> 11:43.150
Okay, we're back in the editor.

11:43.160 --> 11:47.990
I'm going to click open, although I don't think I need any of these assets.

11:48.020 --> 11:51.320
All I really want to do is test out death.

11:51.320 --> 11:58.190
So I'm going to launch a fireball, do some damage, and let's see if we can get this guy down to zero

11:58.190 --> 11:58.940
Health.

11:59.180 --> 12:00.860
One more should do it.

12:00.980 --> 12:03.680
And they ragdoll Look at that.

12:05.330 --> 12:08.900
And of course we set the lifespan to five seconds as well.

12:08.900 --> 12:11.210
So that's another cool thing that we're doing.

12:11.300 --> 12:14.720
We see that they're dropping the weapon as well.

12:14.930 --> 12:17.870
So this is looking pretty nice.

12:18.920 --> 12:24.650
Okay, so we now have a death mechanic working and of course we have a few more things we're going to

12:24.650 --> 12:25.880
want to implement.

12:25.910 --> 12:28.850
Of course we're going to want to gain experience points.

12:28.850 --> 12:33.800
When something dies, we're going to get to all those important RPG mechanics.

12:33.800 --> 12:41.690
But in the meantime, we'll take care of showing a few more really cool cosmetic effects, such as dissolving

12:41.690 --> 12:43.130
the character away.

12:43.130 --> 12:45.860
And we'll get to those things in the videos to come.

12:45.860 --> 12:49.160
So excellent job and I'll see you soon.
