WEBVTT

00:07.310 --> 00:08.320
Welcome back.

00:08.330 --> 00:15.770
Now, in our electrocute spell, we've just added a gameplay cue on an actor, but this time it depends

00:15.770 --> 00:20.750
on what our mouse hit actor is and whether it implements the combat interface.

00:20.750 --> 00:26.090
If it does, then we're adding this gameplay cue to the mouse hit actor.

00:26.090 --> 00:29.960
If it doesn't, then we're adding it to the avatar actor instead.

00:30.680 --> 00:36.850
Now, as soon as we've done that, I want to add more cues to more actors.

00:36.860 --> 00:39.700
I want to get more actors that are close by.

00:39.710 --> 00:42.100
I want to store additional targets.

00:42.110 --> 00:49.310
In other words, I want to generate an array of actors and create target gameplay queue parameters for

00:49.310 --> 00:53.600
each one, and apply our electric beam to each one.

00:53.630 --> 01:02.000
Now, compiling an array of actors generally involves loops, and I'm going to get actors that are nearby.

01:02.030 --> 01:04.610
So we're going to be performing some kind of query.

01:04.640 --> 01:06.920
This is all stuff that we should do in C plus plus.

01:06.920 --> 01:09.530
So I'm going to make a C plus plus function.

01:09.680 --> 01:13.760
So saving all I'm going to open Aura Beam spell.

01:13.760 --> 01:16.790
And we'll be making another blueprint callable function.

01:16.790 --> 01:18.080
It's going to be void.

01:18.080 --> 01:22.280
And I'm going to call this store additional targets.

01:22.880 --> 01:27.800
Now I'd like to pass in a T array by reference non-const.

01:27.830 --> 01:30.800
It'll be a t array of a actor pointers.

01:32.240 --> 01:35.750
So passed in by reference, and I'm going to call it out.

01:35.870 --> 01:37.400
Additional target.

01:37.400 --> 01:41.810
So it's an out parameter and it's going to be blueprint callable.

01:44.010 --> 01:44.310
Oops.

01:44.310 --> 01:45.690
Didn't mean to build.

01:45.690 --> 01:47.040
I'm going to cancel that build.

01:47.040 --> 01:49.920
And we're going to generate a definition for this.

01:50.370 --> 01:54.610
So we need to think about what this is going to do for us.

01:54.630 --> 01:58.830
Now I want this function to generate a t array of actors.

01:58.830 --> 02:04.410
And I want them to be nearby actors that implement the combat interface.

02:04.710 --> 02:07.620
On top of that, I want them to not be dead either.

02:07.800 --> 02:12.990
Now, if we go into our ability system blueprint library.

02:14.500 --> 02:20.650
Or ability system library, and we take a look at get live players within radius.

02:20.680 --> 02:23.710
We can take a look at its implementation.

02:25.540 --> 02:29.110
This performs a query with sphere params.

02:29.110 --> 02:30.940
We have a given radius.

02:31.030 --> 02:38.800
We have a check to see if the actors that are overlapping a sphere of the given radius implement the

02:38.800 --> 02:40.180
combat interface.

02:40.210 --> 02:42.190
It even checks to see if they're dead.

02:42.400 --> 02:44.380
If they're not dead.

02:44.410 --> 02:47.770
Then we add them to the out overlapping actors.

02:47.770 --> 02:50.170
So this is the perfect function for us.

02:50.170 --> 02:52.720
So I'd like to call that function.

02:53.020 --> 02:58.060
So I'm going to call you Ora ability System Library.

02:58.930 --> 03:01.600
Get live players within radius.

03:01.630 --> 03:04.840
Now this requires a world context object.

03:04.930 --> 03:07.240
I'm just going to pass in the avatar actor.

03:07.240 --> 03:14.380
So get avatar actor from actor info and we need a t array of actors.

03:14.410 --> 03:17.350
Now I'm not going to pass in out additional targets.

03:17.350 --> 03:20.050
That's going to be what this function returns.

03:20.050 --> 03:26.980
But this function will get us all players, or at least all things that implement the combat interface

03:26.980 --> 03:28.570
within radius.

03:28.570 --> 03:31.030
And that's not what I want.

03:31.060 --> 03:34.750
I only want the first few that are closest.

03:34.750 --> 03:37.570
So we're going to have to call out the closest ones.

03:37.570 --> 03:43.030
So for that reason I'm going to make a local t array of actor pointers.

03:43.840 --> 03:46.870
And this is going to be overlapping actors.

03:48.410 --> 03:50.930
So I'm going to pass in overlapping actors.

03:52.460 --> 03:58.580
Now, in addition to that array, we need to have an array of actors to ignore.

03:58.670 --> 04:00.800
So I'm going to go ahead and make that.

04:01.340 --> 04:07.040
I'm going to copy this array and rename it to Actors to Ignore.

04:07.040 --> 04:13.190
And in fact I'm going to make this first so that overlapping actors is the closest thing to the function

04:13.190 --> 04:13.760
call.

04:13.760 --> 04:19.880
And I'm going to take actors to ignore and add the avatar.

04:19.880 --> 04:22.700
So get avatar actor from actor info.

04:23.210 --> 04:25.910
Now we won't even have to filter that out.

04:26.000 --> 04:31.670
Now, in addition to the avatar actor, I'm going to add the mouse hit actor as well.

04:31.670 --> 04:34.940
So that way we're only getting additional targets.

04:34.970 --> 04:37.520
We don't care about the mouse hit actor anymore.

04:37.550 --> 04:42.650
We're already adding a gameplay cue to that one, so I'm going to take actors to ignore.

04:44.740 --> 04:47.740
And add mouse hit actor.

04:48.970 --> 04:52.660
And with that, I can pass in actors to ignore.

04:53.440 --> 04:53.800
All right.

04:53.800 --> 04:57.880
At this point I'm going to put these inputs on their own lines.

04:58.210 --> 05:01.120
And let's see what our next input needs to be.

05:01.760 --> 05:03.380
It needs to be a radius.

05:03.410 --> 05:10.550
Now it's going to be a pretty big radius, and the aura beam spell could scale the radius with the level.

05:10.550 --> 05:15.650
You know how to do that with curve tables, you could use a mathematical formula.

05:15.680 --> 05:17.630
I'm going to hard code 850.

05:18.020 --> 05:20.840
But you know how to parameterize that.

05:21.050 --> 05:26.120
And for the sphere origin we're going to use the mouse hit actors location.

05:26.120 --> 05:30.440
So mouse hit actor get actor location.

05:33.050 --> 05:40.610
So after calling, this function will have an array of actors that are within 850 units away.

05:40.640 --> 05:46.880
Now we need to get the closest few and or a beam spell should have a maximum for that.

05:46.910 --> 05:52.640
Now, as I mentioned, we're going to be shocking more and more nearby goblins and monsters depending

05:52.640 --> 05:54.350
on the level of this ability.

05:54.350 --> 05:56.390
And we should go up to a max.

05:56.390 --> 06:00.770
So or a beam spell is going to get a max number of shock targets.

06:00.770 --> 06:07.430
So we'll have a variable int 32 max num.

06:07.580 --> 06:12.200
We'll call it shock targets and we'll set it to five.

06:12.860 --> 06:18.650
It could really be anything, but we'll give that a property with edit defaults only.

06:19.730 --> 06:23.690
And of course you property gets a Y at the end.

06:25.050 --> 06:25.560
There we go.

06:25.560 --> 06:27.030
So edit defaults only.

06:27.030 --> 06:30.150
And that'll be in the category of beam as well.

06:30.810 --> 06:32.610
And we'll use that.

06:32.610 --> 06:41.040
And what we'll do in or a beam spell is we'll have an INT 32 called num additional targets.

06:41.460 --> 06:47.760
And we'll use F math and take the minimum between the ability level.

06:47.760 --> 06:52.620
So get ability level and max num shock targets.

06:52.620 --> 06:56.250
And looks like that is missing a parentheses.

06:56.250 --> 06:57.150
There we go.

06:57.540 --> 06:58.080
There.

06:58.080 --> 06:58.800
That's better.

06:58.800 --> 07:03.570
So num additional targets will be whatever ability level we're at.

07:03.660 --> 07:08.130
But of course I'm going to use ability level minus one.

07:08.960 --> 07:14.600
And that way we get the ability level number of beams total up to a maximum.

07:14.600 --> 07:20.960
Now I'm going to comment that out and use this line when we're finished with everything.

07:20.960 --> 07:27.620
But for testing purposes, I'd like to set a max number of five.

07:28.040 --> 07:30.590
So I'm going to call this local num.

07:30.620 --> 07:35.930
Additional targets local variable I'm going to set it to five.

07:37.570 --> 07:41.650
So now that I have overlapping actors, we could have 20 or 30 actors.

07:41.650 --> 07:47.590
We probably won't have that many, but we could have a lot of enemies nearby, and we're going to need

07:47.590 --> 07:54.040
to get the closest few, and we'll need a function to get the closest few.

07:54.070 --> 08:00.610
We can call it get closest targets, and we can make a static function in our ability system library

08:00.610 --> 08:02.350
to get the closest targets.

08:02.440 --> 08:05.770
So that'll be just under get live players within radius.

08:05.770 --> 08:09.190
It'll be static and it'll be void.

08:09.190 --> 08:13.210
And I'm going to call it Get closest Targets.

08:14.410 --> 08:20.680
So we'll have an INT 32 called Max targets.

08:21.010 --> 08:22.900
That's how many targets we need.

08:23.500 --> 08:25.540
We're going to have a const t array.

08:27.310 --> 08:28.210
Of a actor.

08:28.210 --> 08:29.140
Pointers.

08:30.490 --> 08:34.600
We'll pass it in by reference const reference called actors.

08:34.750 --> 08:41.530
And then we'll pass in a non const t array of actors pointers of course.

08:41.920 --> 08:47.260
And we'll pass this one in by non-const reference called out closest targets.

08:47.650 --> 08:52.450
So we'll pass in two arrays one filled with actors and the other will be empty.

08:52.450 --> 08:55.390
And it will have the closest targets.

08:55.420 --> 08:58.270
It'll be this mini Max targets.

09:00.000 --> 09:06.090
And if we're going to calculate the distance from anything, we need to know the distance from what.

09:06.120 --> 09:14.030
So this function gets a const f vector that we can use to calculate the distance from.

09:14.040 --> 09:15.420
We'll call it origin.

09:15.420 --> 09:18.480
So it'll be the origin of this algorithm.

09:18.900 --> 09:21.060
All right let's generate the definition.

09:21.620 --> 09:25.670
Now, how do we get the closest number of targets?

09:25.820 --> 09:29.090
That number being max targets out of an array.

09:29.360 --> 09:38.210
How do we create an array of actors that contains only that number of actors from the actors array?

09:38.420 --> 09:45.950
Assuming that the actors array has more actors than max targets, well, this could be done in a number

09:45.950 --> 09:50.750
of ways, and I'd like to challenge you to give it a shot.

09:50.870 --> 09:56.030
I want you to at least brainstorm and think about how you could possibly do it, and even give it a

09:56.030 --> 09:56.870
try.

09:56.990 --> 10:03.260
So if you're up to that challenge, pause the video now and implement Get closest Targets.

10:07.280 --> 10:10.790
Okay, so how are we going to do this?

10:10.820 --> 10:19.400
Well, first of all, if my actor's array, let's just say it has five actors in it and we pass in seven

10:19.400 --> 10:20.630
for max targets.

10:20.630 --> 10:27.020
Well, actors doesn't have seven, so it already contains the closest actors.

10:27.020 --> 10:29.980
We can't return an array of seven actors.

10:29.990 --> 10:31.490
We have to return actors.

10:31.490 --> 10:32.060
Right.

10:32.090 --> 10:35.840
So actors has to be bigger than max targets.

10:35.840 --> 10:37.760
Otherwise we just return actors.

10:38.430 --> 10:42.480
So we're going to check if actors dot num.

10:43.730 --> 10:49.760
Now if actors num is smaller than or equal to max targets.

10:51.770 --> 10:57.920
Then we can just set out closest targets to actors and return.

10:59.300 --> 11:08.150
There's no point in trying to find the closest max targets targets if actors doesn't even have max targets

11:08.150 --> 11:10.670
in it, so we can return early in that case.

11:11.630 --> 11:18.420
However, if we make it past that now, we need to search through actors for the closest ones.

11:18.440 --> 11:20.330
So here's how I'm going to do it.

11:20.630 --> 11:25.490
I'm first going to make a copy of actors that's not const.

11:25.520 --> 11:28.700
That way I can remove elements from it and things.

11:28.700 --> 11:33.710
So I'm going to make a t array not const of a actor pointers.

11:34.400 --> 11:38.780
And I'm going to call this actors to check and set it equal to actors.

11:38.780 --> 11:40.640
So I'm making a copy of it.

11:41.000 --> 11:46.790
After that I'm going to make a local INT 32 called num targets found.

11:47.000 --> 11:54.560
That way I can keep track as soon as I find an actor that I know is one of the closest ones, then I

11:54.560 --> 12:02.900
can increment this integer, and then I'm going to use a while loop, and I'm going to continue looping

12:02.960 --> 12:08.570
as long as my num targets found is less than max targets.

12:10.520 --> 12:18.560
Now this should work because as long as max targets is greater than the number of actors in our array,

12:18.590 --> 12:20.900
then we'll find enough actors.

12:21.200 --> 12:23.930
If not, we've already returned out of the function.

12:24.740 --> 12:34.160
Now I'm going to make a double called closest distance, and I'm going to keep updating this to the

12:34.160 --> 12:38.060
closest distance that I find as I loop through this array.

12:38.090 --> 12:45.710
And in order to check to see if something is closer than closest distance, I need to start closest

12:45.710 --> 12:48.180
distance off at a really big number.

12:48.200 --> 12:52.070
In fact, I can make it the biggest it can possibly be for a double.

12:52.100 --> 13:00.200
I can use t numeric limits specifying double, and there's a function on this called max, and this

13:00.200 --> 13:03.800
returns the maximum possible value that a double can be.

13:03.890 --> 13:08.320
So that's what I'm starting double off as the biggest it possibly can be.

13:08.330 --> 13:12.320
And after that I'm going to loop through actors to check.

13:13.410 --> 13:16.410
So I know actors to check contains our actors.

13:16.530 --> 13:24.570
So I'm going to say for a actor pointer potential target in actors to check.

13:24.750 --> 13:30.390
So we're looping through every single one and I'm going to calculate the distance.

13:30.510 --> 13:34.320
I'll make a const double distance.

13:35.100 --> 13:41.360
And I'll calculate the distance between the potential target and my origin.

13:41.370 --> 13:49.530
So I'm going to say potential target get actor location minus origin.

13:49.710 --> 13:56.030
I'll get that vector and get its length and store that in distance.

13:56.040 --> 14:01.950
So for each actor in actors to check I'm calculating its distance to the origin.

14:01.950 --> 14:06.150
And I'm going to check to see if that distance is less than closest distance.

14:06.150 --> 14:11.310
So I'm going to say if distance is less than closest distance.

14:12.370 --> 14:12.700
Then.

14:12.700 --> 14:15.430
Now my closest distance is this distance.

14:15.640 --> 14:18.820
So I'll say closest distance equals distance.

14:20.070 --> 14:26.880
And I'm going to make a closest actor that I'm going to set to the potential target here.

14:27.240 --> 14:36.120
So before looping, I'm going to create, along with my closest distance, an a actor called Closest

14:36.120 --> 14:36.900
Actor.

14:38.610 --> 14:48.240
And as I loop through this array of actors to check each time, their distance to the origin is smaller

14:48.240 --> 14:54.150
than my closest distance, I update closest distance and I also update closest actor.

14:54.990 --> 14:59.040
I set it equal to this potential target.

15:01.190 --> 15:10.790
So by the end of this for loop, my closest actor is going to be the closest in this entire array to

15:10.790 --> 15:11.930
the origin.

15:12.230 --> 15:21.290
And by the time I finish my for loop, my closest actor being the closest one can be removed from actors

15:21.290 --> 15:22.130
to check.

15:22.760 --> 15:24.860
So I'll say actors to check.

15:24.980 --> 15:28.040
Dot remove closest actor.

15:28.730 --> 15:33.040
Now, on top of that, though, I need to remember that closest actor.

15:33.050 --> 15:37.430
I'm going to add that into my out closest targets.

15:37.430 --> 15:40.220
So I'm going to say out closest targets.

15:40.220 --> 15:42.080
And I'm going to add unique.

15:42.740 --> 15:46.280
That way we'll never add more than one of the same one.

15:48.340 --> 15:52.030
So now out closest targets gets that closest actor.

15:52.030 --> 15:57.490
And as soon as we've done this I'm going to increment num targets found.

16:00.590 --> 16:03.950
So I'm going to say plus plus num targets found.

16:04.460 --> 16:05.000
Okay.

16:05.000 --> 16:13.820
So what this is going to do is while num targets found is less than max targets, it starts off at zero.

16:13.850 --> 16:16.350
Let's say max targets is five.

16:16.370 --> 16:23.270
So as long as num targets found is less than max targets, this whole loop will keep iterating.

16:23.360 --> 16:26.620
So first it creates a really big double.

16:26.630 --> 16:29.510
It creates a closest actor.

16:29.510 --> 16:34.850
And then we loop over actors to check which is a copy of actors.

16:34.880 --> 16:42.020
We create a const double and set it equal to the length of the vector from the origin to each potential

16:42.020 --> 16:42.680
target.

16:42.710 --> 16:46.520
That's the distance of that potential target to the origin.

16:47.720 --> 16:52.070
If that distance is less than our closest distance, which starts off really big.

16:52.070 --> 16:59.240
So at first it will be, then closest distance becomes that number, closest actor now becomes that

16:59.240 --> 17:00.380
potential target.

17:00.380 --> 17:04.010
And then the for loop goes to the next actor.

17:04.010 --> 17:08.660
And the distance of that actor to the origin is calculated.

17:08.660 --> 17:15.830
If that's even smaller than the closest distance, which was the distance of the first actor, well

17:15.830 --> 17:18.620
then now closest distance is a little bit smaller.

17:18.620 --> 17:23.930
If it's not, then closest distance doesn't get updated and we go to the next actor.

17:23.930 --> 17:27.440
So we're checking all the actors in the array.

17:27.770 --> 17:34.310
But every time we find the closest actor in the whole array, we remove it from the array and add it

17:34.310 --> 17:39.650
to the out parameter array and increment num targets found.

17:39.650 --> 17:41.900
And then the while loop starts over.

17:41.900 --> 17:45.110
And this time actors to check is one less.

17:45.110 --> 17:49.430
And we keep doing this until we've found the number of targets we need.

17:49.670 --> 17:56.870
And of course if actors to check ever becomes empty, well then we can have a safeguard here.

17:56.870 --> 18:05.240
We can say if actors to check dot num equals zero, we can break.

18:05.480 --> 18:07.460
So we can have a safeguard there.

18:07.880 --> 18:12.710
Okay, so here's my algorithm and I'm really excited to see what you came up with.

18:12.710 --> 18:18.830
And I'd like you to share it in the discord and show how much better your algorithm is than mine.

18:18.830 --> 18:22.010
Because there are multiple ways to do this.

18:22.010 --> 18:25.910
And you could get more advanced, you could get more clever.

18:25.910 --> 18:28.430
So I'm interested in seeing what you came up with.

18:28.730 --> 18:35.870
But now that we have get closest targets, we have something that will fill in out closest targets and

18:35.870 --> 18:39.680
we can specify how many of the closest targets we want.

18:39.680 --> 18:44.990
So back in Aura Beam spell we can call this function and store additional targets.

18:45.170 --> 18:49.850
So I'm going to use your aura ability system library.

18:50.150 --> 18:54.740
Get closest targets which needs a max targets.

18:54.740 --> 18:58.820
I'm just going to pass in num additional targets.

18:59.300 --> 19:00.920
That's going to be five.

19:00.920 --> 19:07.220
I'm going to pass in our overlapping actors because we just got all live players within radius.

19:08.870 --> 19:13.160
So we're passing that in as the actors.

19:13.670 --> 19:18.020
Now we need our out parameter out closest targets.

19:18.020 --> 19:20.810
That's going to be out additional targets.

19:20.810 --> 19:24.320
That'll be whatever we pass in to store additional targets here.

19:24.650 --> 19:26.780
And finally we need the origin.

19:26.780 --> 19:32.990
And I'm going to find all actors closest to the mouse hit actor.

19:32.990 --> 19:34.970
So we're going to say mouse hit actor.

19:36.390 --> 19:38.280
Get actor location.

19:40.230 --> 19:46.620
After this out, additional targets will be filled in with the closest five.

19:46.650 --> 19:53.490
If there are five actors that implement the combat interface that are not dead and we can use that.

19:53.490 --> 19:56.280
So I'm going to go ahead and run and debug mode.

19:56.920 --> 20:01.090
And I'd like to just check to make sure that this is working.

20:01.180 --> 20:09.730
We can check by adding a whole bunch of goblins into the world, and then see what this function returns

20:09.730 --> 20:11.650
for us with some debug spheres.

20:13.110 --> 20:15.330
So I'm going to get my ability open.

20:15.330 --> 20:22.410
And as soon as an electrocute, we've added our first gameplay cue.

20:22.440 --> 20:29.220
I'm going to call our new function and hopefully I made it blueprint callable store additional targets.

20:29.490 --> 20:31.440
Yes, it's blueprint callable.

20:31.560 --> 20:37.860
So we're going to call store additional targets and this will return us a T array.

20:38.010 --> 20:41.400
So we'll go ahead and hook both of these up.

20:41.980 --> 20:45.730
And I'd like to create a for each loop.

20:47.670 --> 20:52.860
And each of these is an actor, and I'd like to get its location and show a debug sphere.

20:52.860 --> 20:56.190
So in the loop body draw debug sphere.

20:59.770 --> 21:01.630
We're going to get our array element.

21:01.630 --> 21:03.310
Get actor location.

21:03.880 --> 21:05.940
Hook that into the sphere center.

21:05.950 --> 21:13.840
I'm going to make it red and make the duration 20s and the thickness we'll leave it zero.

21:15.750 --> 21:22.650
And with that, I'd like to create a whole bunch of these goblins and.

21:23.980 --> 21:27.310
We'll see if we get the closest five.

21:27.610 --> 21:30.460
So I'm going to copy each of these a couple times.

21:40.640 --> 21:41.540
Like so.

21:41.960 --> 21:43.340
And.

21:44.000 --> 21:45.260
We'll do a couple more.

21:48.100 --> 21:48.970
There we go.

21:53.660 --> 21:57.290
And with that, I'm going to save all and press play.

21:59.950 --> 22:03.220
Okay, so those spheres are too big.

22:05.950 --> 22:07.420
Let's make the radius.

22:07.420 --> 22:09.340
Oh, I didn't change the radius.

22:09.340 --> 22:11.110
I'm going to make it about 15.

22:12.720 --> 22:19.440
And as soon as I release their one, two, three, four, five we got the five closest.

22:19.440 --> 22:22.950
And this is within an 850 radius.

22:22.950 --> 22:27.360
So we can also draw a single sphere when completed here.

22:28.750 --> 22:33.850
We can draw a white one and this could be a radius of 850.

22:36.490 --> 22:39.550
And we're drawing it at mouse hit location.

22:39.550 --> 22:41.800
That's the location of the mouse hit actor.

22:41.890 --> 22:45.370
So we'll draw that for a duration of 20 as well.

22:45.370 --> 22:48.940
And that'll show us the radius that we're querying here.

22:48.940 --> 22:50.110
It's quite big.

22:50.110 --> 22:55.840
So we're getting the closest five actors to the thing we're shocking.

22:55.840 --> 22:58.720
So right there let's try a different one.

22:58.720 --> 23:00.130
We'll try this one here.

23:01.140 --> 23:02.130
And we're getting those.

23:02.160 --> 23:03.960
Those are the closest five.

23:05.900 --> 23:07.790
And if we try over here.

23:10.200 --> 23:11.770
Those are the closest five.

23:11.790 --> 23:14.460
So our algorithm works.

23:15.810 --> 23:16.500
Okay.

23:16.500 --> 23:22.440
Now that we are getting additional targets, we got those five closest actors.

23:22.470 --> 23:27.600
It's now time to apply some gameplay cues to those actors.

23:27.600 --> 23:31.950
And then we also need to figure out how we can start doing some damage to those actors.

23:31.950 --> 23:33.810
So we're one step closer.

23:33.840 --> 23:36.660
Excellent job, and I'll see you in the next video.
