WEBVTT

00:06.990 --> 00:08.220
Welcome back.

00:08.280 --> 00:18.060
So now that we have a spread of 90 degrees and we're launching five projectiles, we'd like to start

00:18.060 --> 00:20.280
making these projectiles a little more interesting.

00:20.280 --> 00:24.630
For one, I think I'd like to add gravity to them.

00:24.960 --> 00:26.160
And that's pretty easy.

00:26.160 --> 00:28.350
I can go to my Firebolt blueprint.

00:28.380 --> 00:29.520
Here it is.

00:29.520 --> 00:35.670
And I can take my projectile movement component and set its projectile gravity scale to one.

00:36.180 --> 00:38.190
And with that we have gravity.

00:38.190 --> 00:43.650
Let's see what that looks like okay, so yeah, they fall straight down.

00:43.650 --> 00:47.880
But again we have pitch override and spawned projectiles.

00:47.880 --> 00:51.390
We can set that to something high like 65.

00:51.390 --> 00:53.970
And we can see what that looks like okay.

00:53.970 --> 00:57.570
So we have an arc now which looks pretty cool.

00:58.700 --> 01:01.850
So that's kind of the first thing I'd like to do.

01:01.880 --> 01:09.080
65 is a little high, maybe 45 is okay, and the Firebolt could probably get some higher speed now,

01:09.110 --> 01:13.520
maybe 750, but we can tweak that as well.

01:16.670 --> 01:17.270
There we go.

01:17.270 --> 01:17.870
Cool.

01:17.900 --> 01:21.200
Now, the thing about having gravity.

01:21.850 --> 01:22.420
Is now.

01:22.420 --> 01:24.670
We don't have infinite reach, right?

01:26.030 --> 01:31.730
And something we can do that can sort of make things a little bit better for us is to make these homing

01:31.730 --> 01:32.750
projectiles.

01:32.780 --> 01:34.520
Now here's the behavior I'd like.

01:34.550 --> 01:40.490
If I'm hovering over an enemy and I click on it, I want to set the homing projectile target to that

01:40.490 --> 01:41.120
enemy.

01:41.150 --> 01:48.080
In other words, when I launch, I want all of these fireballs to fly out, but then arc towards the

01:48.080 --> 01:48.740
enemy.

01:48.890 --> 01:56.510
But if I clicked on the ground, like over here holding shift and left clicking, well, then I want

01:56.510 --> 02:02.600
to home in on that place that I clicked on, which is kind of hard to see because we're not showing

02:02.600 --> 02:05.240
any particle effect for that.

02:05.270 --> 02:11.600
Now we could spawn a Niagara system right there, wherever we click, every time we click.

02:11.630 --> 02:15.600
As long as we didn't click on an enemy, we can make that happen.

02:15.620 --> 02:22.310
But for now, let's focus on the homing projectiles and then we can focus on.

02:23.820 --> 02:25.170
Playing some particles.

02:25.170 --> 02:28.710
So homing projectiles, how do we do it?

02:28.860 --> 02:35.730
Well, we know that in our Firebolt ability, when we call spawn projectiles, there's a homing target.

02:35.760 --> 02:41.040
Now, the homing target is an actor that we pass in, and what we pass in could be an enemy.

02:41.040 --> 02:42.090
It could not.

02:42.120 --> 02:43.650
What are we going to pass in?

02:43.650 --> 02:45.550
Well, we have a hit result, don't we?

02:45.570 --> 02:50.700
And if we take that hit result, it has a hit actor and we can promote that to a variable.

02:50.730 --> 02:53.010
So I'd like to promote it to a variable.

02:54.190 --> 03:00.820
I'm going to remove this on end ability for now and take the hit actor, promote to a variable and call

03:00.820 --> 03:04.630
this mouse hit actor because our mouse hit it.

03:04.990 --> 03:12.400
I'll go ahead and collapse that hit result, and we'll make sure that we set mouse head actor.

03:12.400 --> 03:17.440
And by the time we call spawn projectiles, we can pass in that mouse hit actor.

03:17.740 --> 03:21.310
Now the question is what do we do with mouse hit actor?

03:21.340 --> 03:23.830
Well, let's close the editor and go back to C plus.

03:23.830 --> 03:27.460
Plus to our spawn projectiles function.

03:27.490 --> 03:35.740
Now we could just code this for homing projectiles, or we can pass in a boolean for whether or not

03:35.740 --> 03:37.870
we should spawn homing projectiles.

03:37.870 --> 03:41.830
Or we could have a boolean on the Aura Firebolt ability.

03:41.860 --> 03:42.400
Really?

03:42.400 --> 03:43.460
It doesn't matter.

03:43.480 --> 03:47.260
I'm just going to make them homing projectiles by default.

03:47.290 --> 03:49.600
We know how to make booleans and set them.

03:49.600 --> 03:56.950
So we're going to first take that mouse hit actor, which we passed in as homing target.

03:57.160 --> 04:02.440
And I'm going to check to see if it is an enemy if it implements the combat interface.

04:02.440 --> 04:05.770
So if it's an enemy or another player character.

04:05.770 --> 04:10.330
So I'm going to say if homing target.

04:12.210 --> 04:15.900
Implements you combat interface.

04:17.770 --> 04:24.010
So we know if it implements the combat interface that we're not clicking on the floor or a wall or something

04:24.010 --> 04:24.730
like that.

04:24.730 --> 04:28.420
If that's the case, then I'm going to take my projectile.

04:32.320 --> 04:34.300
And set something on it.

04:34.300 --> 04:40.360
And of course, that means we need to be in the for loop where the projectile is in scope.

04:40.570 --> 04:45.010
And on top of that, we have to be in here before we finish spawning.

04:45.800 --> 04:52.130
So I'm going to take the projectile in this case and get its projectile movement component.

04:52.130 --> 04:56.930
And the projectile movement component is of course an incomplete type.

04:57.110 --> 05:02.150
So I can go ahead and include that that exists in game framework.

05:02.540 --> 05:05.180
So I'm going to include game framework.

05:06.780 --> 05:08.760
Projectile movement component.

05:09.710 --> 05:16.460
Now that it's not an incomplete type, the projectile movement component has something called a homing

05:17.210 --> 05:18.830
target component.

05:18.860 --> 05:23.210
Notice it's a weak object pointer to a scene component.

05:23.240 --> 05:29.510
Now it's weak because the projectile movement component doesn't want to affect the reference counting

05:29.510 --> 05:33.320
for garbage collection if it's holding on to something, right.

05:33.350 --> 05:38.900
Let's say we set the projectile homing target to some object in the world.

05:38.900 --> 05:45.680
We don't want that object just staying alive just because our projectile movement component's homing

05:45.710 --> 05:48.230
target component points to it.

05:48.260 --> 05:53.270
Just know that things can become null up from under a weak object pointer.

05:53.270 --> 05:54.560
So something to be aware of.

05:54.590 --> 05:58.670
But we can take this homing target component and we can set it to a component.

05:58.700 --> 06:00.350
Now it's a scene component.

06:00.350 --> 06:03.950
And we know that we have a homing target which is an actor.

06:03.950 --> 06:06.490
And all actors have a root component.

06:06.500 --> 06:13.730
So if we get that root component we can assign an that value to the homing target component on the projectile.

06:13.880 --> 06:16.400
But what if we hit the floor or a wall.

06:16.400 --> 06:21.980
Well, that's not going to pass this check because it doesn't implement combat interface.

06:21.980 --> 06:23.720
So we need an else case.

06:23.870 --> 06:26.840
Now how are we going to handle the else case.

06:26.840 --> 06:32.900
Because if we just do what we did here and set the homing target to the root component of the actor

06:32.900 --> 06:33.470
we hit.

06:33.500 --> 06:34.910
Well, think about that.

06:34.910 --> 06:42.530
If it's a static mesh actor, like a big floor tile, then the location of that root component is basically

06:42.530 --> 06:45.650
wherever that mesh origin is.

06:45.680 --> 06:47.840
It's not necessarily where you clicked.

06:47.870 --> 06:55.940
So what we need to do is figure out how we can get a component in the location of our mouse hit from

06:55.940 --> 06:57.950
our line trace under our mouse cursor.

06:57.950 --> 06:58.420
Right.

06:58.430 --> 06:59.990
So how do we get that.

07:00.020 --> 07:03.290
Well we could simply create a new scene component.

07:03.470 --> 07:09.830
So what I'm going to do is take my projectile and get its projectile movement component and get that

07:09.860 --> 07:15.670
homing target component and set it equal to a new object that I create with new object.

07:15.680 --> 07:18.140
And I'm just going to make a new scene component.

07:19.650 --> 07:21.300
Now this requires a class.

07:21.300 --> 07:26.040
So I'm just going to use you seen component static class.

07:27.390 --> 07:30.360
And that's just going to create a new you seen component.

07:30.360 --> 07:33.840
And it's going to set it to the homing target component.

07:33.870 --> 07:39.150
Now here's the thing though homing target component is a weak pointer.

07:39.330 --> 07:46.830
That means when the projectile dies in homing target component goes out of scope, this new object is

07:46.830 --> 07:48.450
not going to be cleaned up.

07:48.510 --> 07:50.840
So how do we get garbage collection?

07:50.850 --> 07:55.110
Because we don't want to just spawn a bunch of new you seen components and never have them cleaned up,

07:55.110 --> 07:55.680
right?

07:55.920 --> 08:01.020
Well, we could make a variable on our projectile class.

08:01.050 --> 08:04.170
We can go to actor or a projectile.

08:04.320 --> 08:06.840
We can make a scene component pointer.

08:06.870 --> 08:08.550
We'll just make it public.

08:08.670 --> 08:10.890
We'll make it a t object pointer.

08:10.920 --> 08:19.470
Use scene component and we'll just call this homing target scene component.

08:21.900 --> 08:26.310
And if we give it a new property, it'll be garbage collected.

08:26.340 --> 08:28.690
The aura projectile gets destroyed.

08:28.710 --> 08:30.030
So will this.

08:30.120 --> 08:32.580
And we don't even have to set it to anything.

08:32.610 --> 08:34.470
Now an aura Firebolt.

08:34.530 --> 08:43.140
We can take our projectile and get its homing target scene component and set that to the new object.

08:43.170 --> 08:44.310
Now.

08:46.010 --> 08:51.770
It'll be garbage collected, and then we can just set the homing target component to the projectiles

08:51.770 --> 08:53.450
homing target scene component.

08:53.450 --> 08:54.530
And there we go.

08:57.120 --> 08:58.710
Make sure we have those parentheses there.

08:58.740 --> 08:59.430
Okay.

08:59.460 --> 09:01.950
So we created a new scene component.

09:01.950 --> 09:04.230
And we set the homing target component to that.

09:04.260 --> 09:08.820
Now after this our projectile now has a homing target.

09:08.820 --> 09:12.990
And we can set its homing acceleration magnitude.

09:13.020 --> 09:18.480
Basically how fast do we want those fireballs to turn and arc towards their target.

09:18.630 --> 09:22.320
Well let's get our projectile get our projectile movement component.

09:22.320 --> 09:26.340
And from the projectile movement component we can type homing.

09:26.340 --> 09:29.100
And here's homing acceleration magnitude.

09:29.250 --> 09:31.020
And we can set that to a value.

09:31.140 --> 09:37.440
Now we can make a couple of parameters and have a random number between a minimum and a maximum.

09:37.470 --> 09:39.060
I think I like that idea.

09:39.060 --> 09:44.370
So our Aura Firebolt can get two floats.

09:44.400 --> 09:48.540
We're going to have one float called.

09:50.560 --> 09:58.180
Homing acceleration men, and I'll give it a value by default of 1600 f.

09:58.990 --> 10:03.730
I'm also going to have one for the max, so we'll have a homing acceleration max.

10:05.020 --> 10:07.420
And this will be 3200.

10:09.160 --> 10:10.540
We'll play with these.

10:11.000 --> 10:15.010
But then in Aura Firebolt, I'm going to set this equal to F math.

10:16.390 --> 10:24.640
And I'm going to use f rand range, the float version of rand range, and use homing acceleration min

10:24.640 --> 10:28.810
for the min and homing acceleration max for the max.

10:28.990 --> 10:32.290
And now we have our homing acceleration magnitude.

10:32.380 --> 10:38.470
Now we also need to tell the Projectile's movement component that this is a homing projectile.

10:39.310 --> 10:45.790
So we can get our projectile, get its projectile movement and set the boolean on it.

10:45.820 --> 10:49.660
B is homing projectile to true.

10:50.080 --> 10:53.050
And again you could make a boolean here.

10:53.050 --> 10:54.490
In fact why not.

10:54.490 --> 10:59.410
Since we're making parameters and or a firebolt we'll go ahead and make one more.

11:01.630 --> 11:07.360
It'll be a bool called B launch homing projectiles.

11:08.440 --> 11:10.150
True by default.

11:10.930 --> 11:14.080
And we'll use that right here.

11:15.200 --> 11:17.120
And now we can turn it on and off.

11:17.450 --> 11:18.830
Let's give this a try.

11:21.340 --> 11:22.230
All right.

11:22.240 --> 11:23.620
Moment of truth.

11:24.220 --> 11:25.710
Ooh, look at that.

11:25.720 --> 11:28.150
I'll go ahead and open our asset editors as well.

11:28.150 --> 11:30.160
But did you see that?

11:30.820 --> 11:32.320
Let's see that again.

11:35.850 --> 11:36.450
Okay.

11:36.450 --> 11:37.440
So.

11:38.130 --> 11:39.660
It looks like.

11:40.880 --> 11:43.910
Our projectiles are definitely homing towards something.

11:45.970 --> 11:48.640
But they seem to all be homing towards.

11:49.240 --> 11:51.000
The wrong location.

11:51.010 --> 11:53.350
Let me try launching at an enemy.

11:58.310 --> 12:00.740
So they do go towards the enemy.

12:00.770 --> 12:02.150
So that's good.

12:03.570 --> 12:05.460
And if I'm close enough.

12:07.330 --> 12:08.170
Whoa, there.

12:08.170 --> 12:09.430
That looks good.

12:13.860 --> 12:18.450
We don't have radial damage with the fall off or anything like that.

12:20.250 --> 12:26.400
But we can see that our projectiles are arcing towards their locations.

12:26.400 --> 12:31.260
Now that depends on that homing acceleration magnitude, of course.

12:31.590 --> 12:37.890
But we've got an issue here and that's that when I'm not on a target.

12:38.750 --> 12:41.690
We're going to the wrong location, I think.

12:41.690 --> 12:44.810
So we need to figure out what's going on there.

12:45.570 --> 12:51.300
In other words, if the homing target does not implement the combat interface well, we need to see

12:51.330 --> 12:53.070
what's happening here.

12:53.220 --> 12:56.520
And I see what's happening right now.

12:56.520 --> 13:00.630
We never actually set the location of that homing target.

13:00.660 --> 13:02.130
We need to do that.

13:02.430 --> 13:08.350
So we're going to take that homing target scene component that we just created.

13:08.370 --> 13:10.590
We need to set its world location.

13:10.590 --> 13:15.990
So to set a component's world location we use set world location.

13:16.790 --> 13:21.080
And we already have a projectile target location we can use.

13:21.410 --> 13:23.570
So that's going to fix that problem.

13:23.570 --> 13:27.680
So we can close and relaunch and test this properly.

13:29.110 --> 13:30.100
All right.

13:30.980 --> 13:32.480
Let's check this out.

13:35.010 --> 13:36.360
That's much better.

13:36.390 --> 13:37.770
Look at that.

13:41.250 --> 13:44.610
Now our firebolts don't go that far.

13:45.770 --> 13:48.020
So we can change that in a number of ways.

13:48.020 --> 13:50.030
We can change the velocity.

13:50.060 --> 13:55.130
We can also change the pitch override.

13:55.130 --> 13:58.310
We can make it a little higher 55 degrees.

13:58.310 --> 14:05.060
We could take our Firebolt, get that projectile movement component, set its velocity to say 850.

14:10.960 --> 14:12.100
There we go.

14:16.570 --> 14:17.680
All right.

14:18.970 --> 14:23.110
So when I'm this far away, that guy is out of reach.

14:24.560 --> 14:27.800
But you know, we know how to tweak parameters, don't we?

14:28.280 --> 14:29.780
And we don't want to be too op.

14:33.530 --> 14:34.490
Excellent.

14:35.440 --> 14:39.850
Really nice, looks great, and we have gravity working.

14:39.850 --> 14:42.400
And of course that's another thing you can play with.

14:42.430 --> 14:45.520
You can set that projectile gravity scale to a lower value.

14:45.550 --> 14:47.080
You can set it to zero.

14:47.980 --> 14:51.130
And then things are not going to be slowed down at all.

14:51.130 --> 14:53.170
So that's another thing.

14:53.170 --> 14:58.510
You know, if you take gravity out of the equation, well then there is really no limit.

14:58.540 --> 14:59.290
We can.

14:59.950 --> 15:01.600
We can get way far away.

15:01.600 --> 15:04.600
I'm going to get really, really far away without gravity.

15:06.060 --> 15:07.530
It's almost off the screen.

15:07.710 --> 15:10.680
And we definitely we definitely hit them.

15:10.680 --> 15:13.020
So I actually kind of like it without gravity.

15:13.020 --> 15:14.610
So I'm going to leave it off.

15:14.610 --> 15:18.360
And am I okay with that pitch?

15:25.340 --> 15:30.140
I think the pitch can be 45, and I do think the firebolts a little fast.

15:30.170 --> 15:32.840
650 would probably do.

15:36.460 --> 15:37.120
All right.

15:37.150 --> 15:39.130
Things are looking great.

15:39.370 --> 15:47.260
Okay, so before we wrap up, the last thing I want to do is not have a default of five projectiles.

15:47.260 --> 15:55.570
I just want to have that projectile parameter Max num projectiles for the number of times we level up.

15:55.570 --> 15:58.180
Every time we level up, I want to get one more.

15:59.010 --> 16:05.010
So in other words, I'm going to come back into my spawn projectiles.

16:05.280 --> 16:10.320
And there was a line that I commented out and I must have deleted it.

16:10.350 --> 16:13.620
It was where we calculated the number of projectiles.

16:13.650 --> 16:14.460
It's gone.

16:14.460 --> 16:22.620
But now when we call evenly spaced rotators, we need to use a different number than num projectiles.

16:22.620 --> 16:29.640
So we're going to have an int 32 called effective num projectiles.

16:29.640 --> 16:36.810
And it's going to be the result of an F math min between num projectiles.

16:38.260 --> 16:40.120
And get ability level.

16:41.710 --> 16:46.720
And then we're going to use effective num projectiles instead of num projectiles.

16:47.360 --> 16:48.740
This can be const.

16:50.430 --> 16:51.980
Now here's the cool thing.

16:51.990 --> 16:54.210
We'll start at level one, right?

16:54.210 --> 16:59.040
And if we level up, we can spend a point on our Firebolt spell.

16:59.040 --> 17:04.970
And once we spend a point, it'll be level two and then we'll be spawning two projectiles.

17:04.980 --> 17:09.630
So now we have an incentive to level up our ability.

17:10.660 --> 17:12.610
Which is actually really nice.

17:12.790 --> 17:13.780
Let's check it out.

17:13.780 --> 17:16.830
So I'm going to press play.

17:16.840 --> 17:18.700
We get one projectile.

17:18.730 --> 17:19.450
Big deal.

17:19.480 --> 17:20.020
Cool.

17:20.020 --> 17:21.040
But.

17:21.970 --> 17:24.220
Let's kill one of these things.

17:24.730 --> 17:25.870
And level up.

17:25.870 --> 17:30.460
Now that we've leveled up, we can get our ability spend a point on it.

17:30.460 --> 17:34.480
And now our description says launch is two bolts of fire, right?

17:36.100 --> 17:37.870
And we actually do.

17:39.600 --> 17:43.290
If that doesn't make you happy, you have no feelings.

17:43.410 --> 17:44.400
All right.

17:44.400 --> 17:45.600
This is looking great.

17:45.600 --> 17:52.380
And of course, we can rain twice as much damage on things, which is really exciting, if you ask me.

17:52.380 --> 17:55.140
And let's just test leveling up again.

17:56.320 --> 17:57.350
I ran out of mana.

17:57.370 --> 17:58.600
I almost said ammo.

17:58.630 --> 17:59.980
I ran out of mana.

17:59.980 --> 18:01.840
And why did I run out of mana?

18:01.870 --> 18:02.410
All of a sudden?

18:02.410 --> 18:09.550
Because my Firebolt cost 12 mana instead of two at the next level.

18:10.580 --> 18:12.140
That might be a little harsh.

18:12.410 --> 18:18.920
And as we start progressing more and leveling up more and testing more, we're going to find that some

18:18.920 --> 18:24.340
of those starting ballpark values that we gave some of our stats might need to be tweaked.

18:24.350 --> 18:26.450
So we'll do that as we go.

18:26.480 --> 18:30.440
We can go to ability system data set cost.

18:30.470 --> 18:32.120
Here's our Firebolt cost.

18:32.150 --> 18:34.580
We're going from 2.5 to 12.5.

18:34.610 --> 18:35.820
That's a little harsh.

18:35.840 --> 18:41.420
We can go from 2.5 to 3 to 3.5.

18:41.450 --> 18:46.130
3.4 is fine to 5 to 7.

18:46.820 --> 18:48.170
To 11.

18:48.290 --> 18:49.970
To 15.

18:50.330 --> 18:50.770
Wow.

18:50.780 --> 18:52.370
I went really up there, didn't I?

18:52.400 --> 18:57.290
We'll go up to 20, 25, 35.

18:59.720 --> 19:01.340
So there's our step curve.

19:03.600 --> 19:04.470
All right.

19:06.820 --> 19:08.110
So leveling up.

19:10.740 --> 19:16.290
Oh, didn't mean to hit equip, but I did level it up in our Manacost is now three.

19:17.210 --> 19:18.680
Launching to.

19:24.400 --> 19:25.540
Let's see if they give us.

19:25.540 --> 19:28.360
I don't know how much XP.

19:28.390 --> 19:31.090
I don't remember, I think they gave us 300 each.

19:31.120 --> 19:32.500
Yeah, that was enough to level up.

19:32.500 --> 19:36.730
So now I can go up to level three and launch three.

19:36.760 --> 19:37.630
Look at that.

19:38.700 --> 19:39.720
Excellent.

19:40.490 --> 19:44.150
So I guess it makes sense that it should cost more mana.

19:44.180 --> 19:52.250
I'll probably go and nerf this ability in the future by changing those mana costs, but that's fine.

19:52.310 --> 19:53.960
The important thing is it works.

19:53.960 --> 19:55.430
Everything's looking great.

19:55.430 --> 19:57.230
Firebolt is looking great.

19:58.870 --> 20:07.030
I'm going to give you a extra challenge if you want to go in here and add more info to this if you want,

20:07.060 --> 20:08.830
make this more descriptive.

20:08.860 --> 20:14.980
Now, before we finally wrap up for the last time, I'm going to go ahead and show you one issue.

20:14.980 --> 20:17.890
And that's if we are launching Firebolts.

20:17.890 --> 20:21.430
And then we go and click I'm going to shift click over here.

20:21.460 --> 20:23.200
Oh what's going on.

20:23.200 --> 20:29.950
Well our homing target is null because we didn't click on anything that gave us a hit result because

20:29.950 --> 20:33.580
those blocking volumes don't actually block the visibility channel.

20:33.640 --> 20:39.400
So in that case well that means homing target being null is a legitimate possibility.

20:39.400 --> 20:41.470
It's not an error or anything.

20:41.470 --> 20:47.140
It's just something that we can run into which for that reason, we need to make sure homing target

20:47.140 --> 20:48.910
is not a null pointer.

20:49.030 --> 20:50.230
So we'll check that here.

20:50.230 --> 20:51.760
We'll say homing target.

20:53.080 --> 20:54.010
And.

20:55.170 --> 20:59.370
So if homing target is valid and it implements the interface.

20:59.460 --> 21:01.050
Either of those is false.

21:01.050 --> 21:02.850
Then we just make a new homing target.

21:02.850 --> 21:03.360
Right.

21:03.360 --> 21:07.020
And next time we play test we'll test out that scenario.

21:07.200 --> 21:08.310
Excellent job.

21:08.340 --> 21:10.110
I'll see you in the next video.
