WEBVTT

00:06.830 --> 00:08.060
Welcome back.

00:08.650 --> 00:10.510
So things are coming right along.

00:10.510 --> 00:12.550
We have our enemies approaching.

00:12.550 --> 00:20.320
We have our melee enemies attacking, but so far it just plays an attack montage, although we do have

00:20.350 --> 00:29.650
that location at the tip of the spear, as indicated by our debug red sphere, what I'd like to do is

00:29.650 --> 00:39.010
use that location and get all actors within the radius of that point, that spear point, so that we

00:39.010 --> 00:43.120
can do things to them like apply gameplay effects and so on.

00:43.120 --> 00:47.080
Now this is going to involve some kind of query.

00:47.110 --> 00:54.880
We need to see what actors exist within some sphere of a particular radius.

00:55.030 --> 01:03.040
Now finding all actors or players within a given sphere is quite useful.

01:03.040 --> 01:09.080
It's one of those types of things that you would add to a blueprint function library because because

01:09.080 --> 01:11.090
you could use it for multiple purposes.

01:11.090 --> 01:14.030
You could use it for what we want to use it for here.

01:14.030 --> 01:22.190
In our case, we'd like to say cause a damage gameplay effect to all actors inside of the sphere, but

01:22.190 --> 01:24.350
we could use it for a number of things.

01:24.350 --> 01:28.940
You could probably think of 4 or 5 different use cases for something like this.

01:28.940 --> 01:34.670
So we're going to make a nice static function to add to our function library for this.

01:34.700 --> 01:43.250
Now I'd like to have this function check to see if any actors within that radius are still alive, because

01:43.250 --> 01:48.140
I don't really care about any actors within the radius that have already died.

01:48.140 --> 01:52.370
Now we've already introduced the concept of death to our project.

01:52.610 --> 02:00.050
In fact, our combat interface has a die function and it'd be handy if we could have interface functions

02:00.050 --> 02:06.980
to check to see if we have died, to see if the thing that implements that interface has died.

02:07.220 --> 02:14.840
Now, another thing that I think would be extremely useful is if our combat interface could return the

02:14.840 --> 02:22.340
Avatar actor, the actor associated with the combat interface that implements it, basically its owner.

02:22.370 --> 02:24.440
So that would be nice.

02:24.440 --> 02:31.010
And we've seen that when we make these functions Blueprint Native event that we could execute the static

02:31.010 --> 02:35.660
function, the execute version of it without having to cast to the interface.

02:35.660 --> 02:41.300
We saw this in our projectile spell we had execute get combat socket location.

02:41.300 --> 02:44.720
This exists because we made that blueprint native event.

02:44.750 --> 02:52.220
We can do that same thing for functions on the combat interface to get whether our actor has died and

02:52.220 --> 02:56.090
to also get the actor itself an avatar, if you will.

02:56.090 --> 03:01.700
Now for that reason, I'd like to make two blueprint callable functions.

03:01.700 --> 03:07.910
One to get whether or not the player or character has died and one for getting the avatar.

03:08.000 --> 03:18.590
So the first one I'm going to get is a boolean called is Dead So Is Dead will be Blueprint Native event

03:18.590 --> 03:19.910
Blueprint Callable.

03:19.910 --> 03:26.480
Let's go ahead and mark it as such and the next one will return an A actor pointer and this is going

03:26.480 --> 03:29.120
to be called get Avatar.

03:30.930 --> 03:36.960
So get Avatar will also be Blueprint Native event Blueprint callable.

03:37.170 --> 03:43.340
Now these are simple getters, so there's really no reason that they can't be const functions.

03:43.350 --> 03:44.760
Let's go ahead and mark them both.

03:44.760 --> 03:45.450
Const.

03:49.500 --> 03:52.140
And we just need to override these.

03:52.140 --> 03:55.470
We can override them in the or a character base class.

03:55.470 --> 03:57.840
So let's go there and override them.

03:57.840 --> 04:01.620
Here we're going to have a virtual BOOL.

04:01.620 --> 04:07.320
Returning function is dead, but we have to override the implementation version and we're also going

04:07.320 --> 04:11.970
to have a virtual a actor returning function called Get Avatar.

04:12.000 --> 04:16.800
That's also the implementation version We must override.

04:16.830 --> 04:21.270
These, by the way, are functions belonging to the combat interface.

04:21.270 --> 04:28.440
So just like we did in our enemy class or an enemy where we have this combat interface, we could do

04:28.440 --> 04:31.410
the same thing in or a character base.

04:31.410 --> 04:37.110
We can say this is the combat interface and right here is the end of the combat interface.

04:37.110 --> 04:38.070
We could do that.

04:38.100 --> 04:41.550
That would allow us to put those functions there.

04:41.580 --> 04:43.320
These are all public, by the way.

04:43.320 --> 04:47.310
And here we have get hit, react montage.

04:47.340 --> 04:50.650
We have die and get player level.

04:50.650 --> 04:53.380
These are all functions belonging to this interface.

04:53.380 --> 05:00.310
We could move them into this comment and again, they're public so we could actually move these all

05:00.310 --> 05:02.980
up to the public section.

05:02.980 --> 05:08.440
So I'm just going to quickly do that, move these up to the public section like so, and if we missed

05:08.440 --> 05:10.300
any, we can move them in there later.

05:10.300 --> 05:13.000
But we do need to implement these two functions.

05:13.000 --> 05:19.990
So we're going to generate function definitions and what are we going to return for is dead and get

05:19.990 --> 05:20.530
Avatar.

05:20.530 --> 05:22.780
Well, get Avatar is the easiest one.

05:22.780 --> 05:24.670
It's going to return this.

05:25.030 --> 05:33.730
And in fact this can't be const as the function cannot convert from const A or a character base pointer

05:33.730 --> 05:35.590
to type a actor.

05:35.740 --> 05:43.690
So we'll go ahead and just remove const from this and from the declaration here and from combat interface.

05:45.080 --> 05:46.550
That'll take care of that.

05:47.060 --> 05:48.680
Now for is dead.

05:48.890 --> 05:51.200
Now we have a die function, don't we?

05:51.200 --> 06:00.770
And if we want is dead to return that status, we can have a variable for whether or not this particular

06:00.770 --> 06:02.720
character has died.

06:02.750 --> 06:06.020
So we can go ahead and just add that variable here.

06:06.050 --> 06:08.570
I'll go ahead and make it right here in the protected section.

06:08.610 --> 06:10.310
Bool, be dead.

06:11.440 --> 06:19.160
We'll set it to false by default and we have a handy is dead function that will return that.

06:19.190 --> 06:21.210
Let's go ahead and return that here.

06:21.230 --> 06:23.870
Return be dead.

06:24.140 --> 06:27.830
Now be dead is never set so we can always set that.

06:27.830 --> 06:31.590
We only really need to set it to true if the character dies.

06:31.610 --> 06:35.170
Now we don't have to make this a replicated variable.

06:35.180 --> 06:40.010
If we set it in multicast, handle death because then it will be set everywhere.

06:40.010 --> 06:41.540
Clients and server.

06:41.540 --> 06:43.070
So we can just set it here.

06:43.100 --> 06:44.970
Be dead equals.

06:44.970 --> 06:45.660
True.

06:46.400 --> 06:50.330
So now we have two nice blueprint native events.

06:50.370 --> 06:54.770
They're blueprint callable is dead and get Avatar.

06:55.860 --> 06:56.990
Let's just compile.

06:57.030 --> 07:00.030
Make sure we haven't done anything too reckless.

07:00.330 --> 07:07.200
And with a successful compile, we're ready to head over to our Blueprint function library, where we

07:07.200 --> 07:14.510
can make use of these functions and create a function for getting all live players within a radius.

07:14.520 --> 07:16.520
So let's go to that.

07:16.530 --> 07:25.080
I'm actually going to close all tabs at this point and go to public ability system or ability system

07:25.080 --> 07:26.640
library dot H.

07:26.670 --> 07:30.240
We're going to make a new static function to add to our library.

07:30.750 --> 07:34.890
So what exactly is this function going to return?

07:34.890 --> 07:36.290
What's it going to take?

07:36.300 --> 07:44.540
Well, a function to get all live players within a radius is clearly going to need a world context object.

07:44.550 --> 07:48.360
I'd also like to pass in an array of actors that we can fill out.

07:48.390 --> 07:51.510
So this will be a static void function.

07:52.800 --> 07:57.850
I'm going to call it get live players within radius.

07:58.550 --> 08:04.040
I'd like it to be blueprint callable, so I'm going to give it that new function macro right off the

08:04.040 --> 08:04.760
bat.

08:04.880 --> 08:12.200
And for category, I'm just going to call this category gameplay mechanics as I don't really have a

08:12.200 --> 08:13.790
better name for it.

08:14.240 --> 08:19.340
Now get live players within radius will take a world context object.

08:19.370 --> 08:21.470
We're definitely going to need that.

08:22.510 --> 08:27.970
I'm also going to want to fill in a t array of actor pointers, so we're going to pass that in by reference.

08:28.000 --> 08:32.350
T array of type A actor pointer.

08:33.490 --> 08:37.550
We're going to pass it in by reference and I'm going to call this out.

08:37.570 --> 08:40.660
Overlapping actors.

08:41.860 --> 08:46.840
Now, whenever doing something like this, we can always ignore some actors.

08:46.840 --> 08:50.590
We can provide a t array of actors that we can ignore.

08:50.770 --> 08:59.560
So I'm going to provide a const reference to a t array of actor pointers called actors to ignore.

08:59.590 --> 09:02.860
That way, if we do want to ignore any actors, we can.

09:02.920 --> 09:07.420
Now we're going to get all live players within a radius, so we're going to need that radius.

09:07.420 --> 09:15.700
So I'll pass in radius and we need all live players within radius of some location, right?

09:15.700 --> 09:21.400
So we're going to pass in a const vector reference called Sphere location.

09:22.390 --> 09:26.560
So we're getting all live players within some invisible sphere.

09:26.590 --> 09:35.270
We need that sphere location more specifically, it actually is a sphere origin, the center of some

09:35.300 --> 09:36.740
imaginary sphere.

09:37.220 --> 09:41.960
So now all that's left is to decide how to implement this function.

09:41.960 --> 09:44.330
Let's generate the definition for it.

09:44.990 --> 09:52.190
Get all live players within radius and let's decide how we're going to do this.

09:52.490 --> 10:00.110
So the way I'd like to do this is to perform some kind of query, some kind of check for a sphere in

10:00.110 --> 10:01.130
the world.

10:01.160 --> 10:05.630
And first of all, get all actors inside of that sphere.

10:05.870 --> 10:07.700
So how do we do that?

10:08.220 --> 10:14.790
Well, I know of some functions that exist in the engine, but a lot of people ask me when I just come

10:14.790 --> 10:17.910
up with this magic function that exists in the engine.

10:17.910 --> 10:19.260
How did you know that?

10:19.560 --> 10:21.210
How did you figure that out?

10:21.360 --> 10:27.390
So for something like this, if I just give you the function, I should tell you, Well, how did I

10:27.390 --> 10:28.200
figure that out?

10:28.200 --> 10:30.750
How do I already know that?

10:30.960 --> 10:37.110
Well, the first thing I do, if I don't already know, is I try to think what exists in the engine

10:37.110 --> 10:40.350
that I do know about that does something similar.

10:40.440 --> 10:44.910
Now, I personally already know about a couple of things in the engine.

10:44.910 --> 10:49.260
So if I say, Well, I know about this function and you didn't know about that.

10:49.260 --> 10:51.900
Well, yes, that's something I knew that you didn't.

10:51.900 --> 10:54.030
But that comes with experience.

10:54.270 --> 10:59.460
So the more experience you get, the more things you will do, the more functions, you know, that

10:59.460 --> 11:00.630
exist in the engine.

11:00.630 --> 11:04.950
So, you know, with practice, you start to gain that kind of knowledge.

11:04.950 --> 11:13.000
But one of the things that I know exists in the engine is a nice function for applying radial damage

11:13.000 --> 11:14.350
with a fall off.

11:14.440 --> 11:20.770
You see, if you want to apply radial damage with a fall off in Unreal Engine, that's clearly going

11:20.770 --> 11:28.180
to involve seeing what actors are nearby and applying damage to each of those according to their distance

11:28.180 --> 11:31.420
from some origin, some sphere origin.

11:31.420 --> 11:38.470
So it would make sense that a function for applying radial damage with a fall off would query some kind

11:38.470 --> 11:41.870
of sphere to see what actors are overlapping.

11:41.890 --> 11:46.030
Now in writer I can hit shift twice and I can search.

11:46.030 --> 11:51.910
In Visual Studio it's control shift F where I could search the whole solution and I'm going to search

11:51.910 --> 11:56.140
for apply radial damage.

11:56.680 --> 11:58.150
With fall off.

11:59.830 --> 12:02.080
And I'll see the gameplay statics pops up.

12:02.080 --> 12:04.360
First thing, I'm going to double click on that.

12:04.810 --> 12:07.900
And here we have apply radial damage with falloff.

12:07.900 --> 12:15.040
So here's an example of a function that's already doing, at least in part, some of what we want to

12:15.040 --> 12:15.970
do, right?

12:16.000 --> 12:19.660
Let's look through this function line by line and see what it's doing.

12:19.960 --> 12:24.940
First, it's creating a struct of something called F collision query params.

12:24.940 --> 12:31.240
Now it's calling it sphere params interesting, and it's taking in something called scene query.

12:31.240 --> 12:33.130
Stat looks like a macro, right?

12:33.130 --> 12:40.870
And it says in stat id along with a boolean called Trace complex, which it's set to false.

12:40.870 --> 12:47.560
And then this damage causer looks like it's an actor, so sphere params might be something we want to

12:47.560 --> 12:48.280
create.

12:48.310 --> 12:49.450
Now check this out.

12:49.450 --> 12:57.040
Sphere params has add ignored actors taking in a const array reference called in ignore actors.

12:57.040 --> 13:01.130
So we have an array of actors we'd like to ignore.

13:01.130 --> 13:03.920
So that's a nice function to know about as well.

13:04.600 --> 13:12.160
Now the next line says query scene to see what we hit and it has a t array of something called F overlap

13:12.160 --> 13:12.940
result.

13:13.610 --> 13:16.420
Sounds kind of like F hit result, right?

13:16.420 --> 13:18.070
It's called overlaps.

13:18.070 --> 13:26.050
And this function gets the world with get world from context object and from that world it calls overlap

13:26.050 --> 13:28.090
multi by object type.

13:28.180 --> 13:34.720
Now what this does is it passes in that overlaps that t array of overlap results.

13:34.750 --> 13:39.610
It also takes a position looks like origin is passed in here.

13:39.790 --> 13:47.920
It takes a rotation in the form of a quaternion and also an f collision object query params.

13:47.920 --> 13:50.110
And what's being passed in here?

13:50.110 --> 13:57.250
Well, it looks like it's being created right here in f collision object query params which seems to

13:57.250 --> 14:06.800
have a constructor that takes in this f collision object query params init type all dynamic objects.

14:06.800 --> 14:07.850
Interesting.

14:07.850 --> 14:12.200
Now after that input it takes an f collision shape.

14:12.230 --> 14:19.910
So there's this f collision shape type and it looks like it has a static function make sphere which

14:19.910 --> 14:21.470
takes a radius.

14:21.650 --> 14:25.430
So that's how we can specify that this function overlap.

14:25.430 --> 14:33.350
Multi by object type can create some invisible sphere and check to see if any actors overlap with it.

14:33.350 --> 14:41.240
And then that last input is an f collision query params for which sphere params is passed in.

14:41.270 --> 14:44.480
That's that sphere params that was created here.

14:44.480 --> 14:52.100
So really this overlap multi by object type is performing most of the work here with a few parameters

14:52.100 --> 14:53.120
that are set.

14:53.570 --> 14:56.660
Now that's pretty much all we're interested in here.

14:56.660 --> 15:02.510
The rest of this stuff appears to be related to actually causing damage.

15:02.600 --> 15:05.090
All that we really cared about was this right?

15:05.090 --> 15:08.270
We wanted to overlap with stuff.

15:08.270 --> 15:15.680
So now that we've seen an example of how to get all overlapping actors in some kind of a radius, we

15:15.680 --> 15:19.310
can do something similar in our static function library.

15:19.310 --> 15:21.680
So let's think about how to do that.

15:21.710 --> 15:25.610
Now I'm going to keep gameplay statics open so we can use it as a reference.

15:25.640 --> 15:29.390
The first thing it does is creates an f collision query params.

15:29.600 --> 15:34.310
Now the most important thing that I see here is be trace complex.

15:34.310 --> 15:36.650
We don't want to trace against complex collision.

15:36.650 --> 15:37.850
I rarely do.

15:37.970 --> 15:43.730
I want to trace against simple collision things like the physics asset and what have you.

15:43.880 --> 15:51.530
Now it is taking in a damage causer actor for this collision query params constructor, but I suspect

15:51.530 --> 15:57.890
that there are multiple constructors for this collision query params there usually are for most types

15:57.890 --> 16:03.380
in the engine, so let's see what we can get away with creating our own collision query params called

16:03.380 --> 16:04.460
sphere params.

16:04.550 --> 16:11.150
So I'm going to make an f collision query params called sphere params.

16:11.480 --> 16:18.230
Now if I just hit semicolon I see that well look, it has a default constructor.

16:18.230 --> 16:24.830
I don't have to really pass anything into it, but if I right click on this type and I go to it.

16:25.210 --> 16:28.180
Then I see that it has a few different things.

16:28.300 --> 16:30.850
It has a number of variables.

16:30.940 --> 16:36.610
And if we scroll down enough, we can see that it has a constructor.

16:36.610 --> 16:41.830
It actually has a constructor that takes a number of inputs, but they all have default values.

16:41.830 --> 16:44.350
So we can get away with not passing any in.

16:44.380 --> 16:46.060
That's what's happening here.

16:46.090 --> 16:48.340
Now what do we care about?

16:48.370 --> 16:53.830
Well, we do want to trace against only simple collision, but that's already set there.

16:53.950 --> 16:55.780
We have a mobility type.

16:55.780 --> 16:56.890
What does that do?

16:56.920 --> 16:59.500
Well, it's an E query mobility type.

16:59.500 --> 17:06.880
And if we're really interested in that, we can go to the definition of that and see that we have any

17:06.880 --> 17:08.530
static and dynamic.

17:08.530 --> 17:11.950
Static says any shape that's considered static by physics.

17:11.980 --> 17:13.150
Static mobility.

17:13.150 --> 17:20.710
So this is actually an old comment that dates back to the time when Unreal Engine used physics as its

17:20.710 --> 17:21.760
physics engine.

17:21.790 --> 17:26.330
Unreal Engine now uses chaos as its physics engine, so this is interesting.

17:26.330 --> 17:29.870
It's one of those relics of code that was never updated.

17:29.870 --> 17:39.410
But nevertheless, for any objects that are simulating physics, if they're static or dynamic, we can

17:39.410 --> 17:45.560
only trace for those kinds of objects based on their mobility, or we can trace for any.

17:45.590 --> 17:45.920
Right.

17:45.950 --> 17:47.600
So that's interesting.

17:47.600 --> 17:50.270
We can set that mobility type.

17:50.660 --> 17:54.590
Okay, back to our collision query params.

17:54.620 --> 18:01.310
It's in this same header file so I can search for f collision query params and go back down to this

18:01.310 --> 18:02.360
constructor here.

18:02.360 --> 18:04.340
So we have mobility type.

18:04.340 --> 18:06.440
We also have a trace tag.

18:06.470 --> 18:11.990
It says tag used to provide extra information or filtering for debugging of the trace.

18:11.990 --> 18:13.940
I'm not too concerned with that.

18:13.970 --> 18:17.870
We have find initial overlaps that's set to true by default.

18:17.870 --> 18:21.680
It says whether we want to find out initial overlap or not.

18:21.710 --> 18:23.480
If true, we'll return.

18:23.480 --> 18:26.840
If this was an initial overlap, that's something we do want.

18:26.870 --> 18:32.870
True because we're going to do the query and if anything was already overlapping, we want that.

18:33.020 --> 18:40.850
Now there's a number of other things, and I think the most important thing here is tracing complex

18:40.850 --> 18:42.530
and the mobility type.

18:42.530 --> 18:45.080
I'm not really too concerned with any of this other stuff.

18:45.080 --> 18:48.730
So what I'm going to do is set these two properties.

18:48.750 --> 18:51.710
It looks like they're the first two, so I could pass in a false.

18:51.710 --> 18:55.850
And let's just say I only want dynamic objects.

18:55.850 --> 18:56.360
Really.

18:56.360 --> 18:58.370
I could just leave it at any if I want to.

18:58.400 --> 19:03.950
We're going to check those objects anyway, make sure that they implement our interface and that they're

19:03.950 --> 19:04.750
alive.

19:04.760 --> 19:07.280
So yeah, really, it doesn't matter.

19:07.280 --> 19:12.380
We don't have to set any of these, so I'm just going to leave it at sphere params.

19:12.380 --> 19:16.370
It has its settings set to my liking already.

19:16.400 --> 19:21.410
Now, I may have spoken too soon because we do have our actors to ignore, don't we?

19:21.440 --> 19:24.170
So that's really the only thing that I'd like to set.

19:24.170 --> 19:31.550
I'm going to take my sphere params and call that function, add ignored actors and pass in actors to

19:31.550 --> 19:32.660
ignore for that.

19:34.900 --> 19:37.210
And after that I have my sphere params.

19:37.240 --> 19:40.900
All right, let's go back to gameplay statics and see the next thing we did.

19:40.900 --> 19:43.960
So after add ignored actors.

19:43.990 --> 19:52.420
Next there was a t array of f overlap results and we then called overlap multi by object type on the

19:52.420 --> 19:53.380
world.

19:53.410 --> 19:56.320
So that's what we're going to want to do.

19:56.320 --> 20:05.080
So I'm just going to copy the line declaring the t array and come back to my function and paste it.

20:05.080 --> 20:09.160
So I have this overlaps and I'm going to want to get the world.

20:09.160 --> 20:15.820
So I'm going to have an if statement and make a const New World Pointer and I'm going to call it World

20:15.820 --> 20:18.790
and set it equal to what was the function.

20:18.790 --> 20:19.900
Let's go look.

20:19.900 --> 20:21.550
It's getting it from engine.

20:21.550 --> 20:25.270
It's saying G engine, get world from context object.

20:25.300 --> 20:31.030
Now, this function requires a world context object as well as an E get world error mode.

20:31.030 --> 20:36.290
So if it fails to get the world this s error mode determines what to do.

20:36.290 --> 20:39.440
In response to that, it says log and return null.

20:39.470 --> 20:46.280
That sounds to me like it's going to log something, an error perhaps, and return a null pointer.

20:46.310 --> 20:47.720
That's the behavior I'd like.

20:47.720 --> 20:52.760
So I'm going to copy the function call, come back to my function, call it there.

20:52.760 --> 20:56.980
And if we make it inside this if statement, we have the world.

20:56.990 --> 21:03.050
Now, once the world has been acquired, we have overlap multi by object type.

21:03.050 --> 21:07.490
With all these parameters, let's just copy the whole line.

21:08.440 --> 21:10.580
And we'll call that function here.

21:10.600 --> 21:13.960
Now, of course, we're going to need to change some things, right?

21:13.990 --> 21:15.850
Let's see what we need to change.

21:15.940 --> 21:19.390
The first input is the t array of overlap results.

21:19.390 --> 21:21.460
We can pass that in now.

21:21.460 --> 21:24.150
The next input is origin.

21:24.160 --> 21:28.360
That's going to be our sphere origin, so we can go ahead and pass that in.

21:28.510 --> 21:30.160
Now, next is a rotation.

21:30.160 --> 21:37.150
I don't care about a rotation for a sphere, so we're going to leave that at identity for the F collision

21:37.150 --> 21:38.560
object query params.

21:38.560 --> 21:43.540
I think all dynamic objects is fine for the f collision shape.

21:43.540 --> 21:49.810
We're going to make a sphere, but it needs a radius and our function has a radius input.

21:49.810 --> 21:51.880
So we're going to pass in the radius.

21:51.880 --> 21:59.710
And finally we get our sphere params pass that in and after this our array should have some overlaps.

21:59.950 --> 22:00.880
All right.

22:01.630 --> 22:07.650
Now, what I really like to do is loop over this array so I can make a for loop.

22:07.660 --> 22:11.050
Now, what are these items in overlaps?

22:11.050 --> 22:14.140
Well, they're overlap results, right?

22:14.140 --> 22:17.290
So I'm going to use overlap result.

22:17.380 --> 22:19.540
I'm going to use a reference for it.

22:19.540 --> 22:21.850
I'm going to call it overlap result.

22:22.300 --> 22:23.650
I'll just call it overlap.

22:24.310 --> 22:26.830
And we're going to loop through the overlaps array.

22:27.670 --> 22:29.710
And for each of these, what am I going to do?

22:29.710 --> 22:30.970
Well, overlap.

22:30.970 --> 22:36.640
If I type overlap dot, then we have a number of functions including get actor.

22:36.670 --> 22:43.210
That's really the only one I care about because this actor is what I'd like to check for one to see

22:43.210 --> 22:46.000
if it implements my combat interface to.

22:46.000 --> 22:48.550
I want to see if it is dead.

22:48.550 --> 22:56.680
And three, I want to add that actor to my out overlapping actors array, and then my function has done

22:56.680 --> 22:57.700
its job.

22:57.880 --> 23:03.890
So what I'm going to do is first check to see if the actor implements my combat interface.

23:04.040 --> 23:08.210
Now, one way we can do this is we can call implements.

23:08.270 --> 23:14.000
Implements is a template function that requires the type of the interface you're interested in.

23:14.030 --> 23:20.870
Now, unlike when we say cast the actor to our interface, we don't use the I combat interface.

23:20.870 --> 23:24.650
We use the you combat interface instead.

23:25.040 --> 23:32.480
So this is going to return a Boolean whether or not this actor implements the interface so I can make

23:32.480 --> 23:39.350
a local const bull called implements Combat interface, for example.

23:39.350 --> 23:43.940
And it'll be true if the actor does in fact implement it.

23:43.970 --> 23:48.770
Now, in addition to that, I want to know if the actor's dead, so I'm going to make another const

23:48.770 --> 23:55.850
bool called is I'll make it is alive and I'll set it to true if the actor is dead.

23:55.850 --> 24:02.930
Now for that I can use the static function on I combat interface, which is the execute version of is

24:02.930 --> 24:03.470
dead.

24:03.500 --> 24:09.440
But this of course requires the object that implements that interface that's going to be overlapped.

24:09.470 --> 24:10.520
Get actor.

24:10.940 --> 24:18.020
So now I know both whether or not the interface is implemented and if that actor is alive and I can

24:18.020 --> 24:23.420
check these conditions, I'm going to check first implements combat interface, but I'm also going to

24:23.420 --> 24:25.820
check with an and is alive.

24:25.820 --> 24:31.190
And I almost made a logical error here because this is checking is dead.

24:31.220 --> 24:36.830
We want a negation operator here because if it's not dead, it's alive.

24:36.950 --> 24:41.390
So we only want to do anything if it's, first of all, implementing the interface.

24:41.390 --> 24:43.820
And second of all, not dead.

24:43.850 --> 24:46.160
Now, at this point, it's pretty simple.

24:46.160 --> 24:52.280
What we need to do, we need to add that actor to our out overlapping actors.

24:52.280 --> 25:00.500
So I'm going to take out overlapping actors and I'm going to use Add Unique so we don't get any duplications.

25:00.500 --> 25:10.400
And I can simply use overlap dot get actor or if I want to, I could take that interface I combat interface

25:10.400 --> 25:20.330
and call execute get Avatar as we created that as a nice function to get the avatar we can pass in overlap

25:20.330 --> 25:21.410
dot get actor.

25:21.410 --> 25:28.160
I know it's a little bit of a roundabout way if we already have the actor well we have it so you know

25:28.160 --> 25:31.700
you don't really have to call this execute get avatar.

25:31.700 --> 25:34.370
We can just pass in overlap get actor.

25:34.370 --> 25:43.460
But either way, we should now have our out overlapping actors filled in with all live avatars controlled

25:43.460 --> 25:45.320
by players or AI.

25:45.350 --> 25:53.810
So with that we can go ahead and play, test this and see if we actually get all overlapping actors

25:53.810 --> 25:55.970
and we can do something to them.

25:57.140 --> 25:58.790
Okay, I'm going to click open.

25:58.820 --> 26:00.530
Go back to my game.

26:00.590 --> 26:02.180
Melee attack.

26:02.270 --> 26:07.340
And I'm going to see if I can call my new static function.

26:07.640 --> 26:10.370
Get live players within radius.

26:10.550 --> 26:11.960
Here it is.

26:11.990 --> 26:13.730
Now we need a sphere origin.

26:13.730 --> 26:16.220
That's going to be the combat socket location.

26:16.250 --> 26:17.900
We need a radius.

26:17.900 --> 26:20.540
I'm just going to pass in 45 for now.

26:20.570 --> 26:22.450
We need actors to ignore.

26:22.460 --> 26:29.410
I'm going to get the avatar actor of this melee attack and hook it straight into actors to ignore.

26:29.420 --> 26:31.190
That's going to create an array.

26:31.280 --> 26:39.890
We need a world context object we can pass in self or we can pass in the Avatar actor directly.

26:39.920 --> 26:41.690
Either way is fine.

26:41.690 --> 26:45.920
And what are we going to do with our out overlapping actors?

26:45.950 --> 26:49.610
Well, we could for now just draw debug spheres.

26:49.610 --> 26:56.040
I know debug spheres are less exciting than say causing real damage, but we'll get to that.

26:56.060 --> 27:03.530
So let's go ahead and draw debug spheres for each of our overlapping actors.

27:03.550 --> 27:08.460
In fact, we could loop through these with a for each loop.

27:11.660 --> 27:14.900
And for the loop body we could draw the debug sphere.

27:16.120 --> 27:17.590
Using the array element.

27:17.590 --> 27:18.790
This is an actor.

27:18.820 --> 27:24.670
We'll get actor location and we'll just draw a debug sphere at the actor's location.

27:24.820 --> 27:27.220
This will be a different color.

27:27.220 --> 27:33.430
Let's make it greenish, greenish blue and I'll go ahead and draw this smaller.

27:33.430 --> 27:36.370
We'll make it radius 15.

27:36.670 --> 27:37.420
Okay.

27:37.510 --> 27:45.010
And we also want to end the ability not after drawing the first debug sphere, we'll only end the ability

27:45.010 --> 27:46.600
when we complete the loop.

27:46.720 --> 27:50.260
But really this for each loop is just for debug purposes.

27:50.260 --> 27:53.890
We only care that we're getting any live players within the radius.

27:53.890 --> 27:56.440
So let's see if we're doing that.

27:57.730 --> 27:58.670
Save all.

27:58.690 --> 27:59.740
Press play.

28:00.890 --> 28:02.510
Let's see if we get hit.

28:02.510 --> 28:03.530
And there we go.

28:04.290 --> 28:10.380
So we don't want to see that sphere at the tip of the spear anymore necessarily.

28:10.410 --> 28:17.180
We just want to see the sphere at the actor's location, which is the center of aura.

28:18.580 --> 28:19.540
There we go.

28:20.310 --> 28:20.720
Okay.

28:20.730 --> 28:23.280
Now we got a exception here.

28:23.400 --> 28:28.060
And I suspect that I know what it's from, but let's take a look.

28:28.080 --> 28:30.240
We're failing this check here.

28:30.270 --> 28:36.210
That's checking implements, interface passing in you combat interface, static class.

28:36.420 --> 28:44.880
So we see that right here after calling execute is dead and passing in an object here called AU.

28:44.910 --> 28:48.090
That AU has get class called.

28:48.090 --> 28:54.720
And from that class we're calling implements interface with you combat interface static class.

28:54.990 --> 28:58.890
We see that AU is BP test actor.

28:59.340 --> 29:01.530
So that's a problem.

29:01.560 --> 29:09.150
BP test actor does not implement the interface and because test actor does not implement the interface,

29:09.150 --> 29:17.160
then this check fails because our test actor after calling implements interface will return zero here.

29:17.160 --> 29:25.240
So execute is dead is not going to allow us to even check anything that doesn't implement the interface.

29:25.420 --> 29:32.650
Now that's a pretty easy fix we don't even want to try to execute is dead if we don't implement the

29:32.650 --> 29:33.650
interface.

29:33.670 --> 29:41.200
So one easy thing we could do is check implements interface first and only continue.

29:41.230 --> 29:48.370
We could make an if statement here and then we'll never try to execute is dead unless the actor implements

29:48.370 --> 29:49.090
the interface.

29:49.090 --> 29:50.140
That's one.

29:50.140 --> 29:55.080
Or we can make this more compact and just check overlap.

29:55.390 --> 30:04.030
Get actor implements first in our if statement here and if this first part of the if statement fails,

30:04.030 --> 30:10.750
then the and will never check the second one and that second one can be not execute is dead.

30:10.870 --> 30:12.220
We can replace that.

30:12.220 --> 30:15.280
And then we don't need these two temporary booleans.

30:15.700 --> 30:21.490
We'll first check and make sure that we implement the interface and then check to make sure we're dead.

30:21.490 --> 30:22.150
But we don't.

30:22.150 --> 30:28.450
Check is dead unless we make it pass this first check and then we'll never get that exception.

30:28.450 --> 30:33.480
So with that, let's go ahead and hit stop and we'll debug this.

30:33.490 --> 30:35.320
This should take care of that.

30:35.320 --> 30:37.180
Just a logic error there.

30:38.190 --> 30:39.030
Okay.

30:39.300 --> 30:41.550
I'm going to go ahead and open up my.

30:42.360 --> 30:44.100
Melee attack again.

30:44.100 --> 30:46.380
Looks like everything is still there.

30:47.090 --> 30:48.920
I'm going to go ahead and press play.

30:49.340 --> 30:53.360
We're going to get close to the effect actor that was causing the problem.

30:53.360 --> 30:57.410
And now the problem is no more.

31:00.010 --> 31:02.680
Yeah, and we're definitely overlapping with this effect.

31:02.680 --> 31:06.550
Actor And no problems are occurring.

31:06.910 --> 31:08.050
Perfect.

31:08.350 --> 31:11.940
Now, this time we got this other enemy, right?

31:11.950 --> 31:14.440
It was overlapping in that radius too.

31:14.470 --> 31:16.630
Let's see if we can make it happen again.

31:17.140 --> 31:18.160
There we go.

31:18.160 --> 31:21.850
We got two spheres, one for me and one for the other enemy.

31:21.970 --> 31:30.100
So if we wanted to only affect Aura and not the enemies, or if it's aura doing it, we only want to

31:30.100 --> 31:34.040
affect the enemies and not aura and other friendly players.

31:34.060 --> 31:39.940
Well, we could also check those tags that we gave our aura character and our enemy.

31:39.940 --> 31:42.370
We have tags, aura and enemy.

31:42.370 --> 31:44.590
That's something that we could look into.

31:44.620 --> 31:47.330
For now, I think this is working just fine.

31:47.350 --> 31:50.140
We are getting all live players within Radius.

31:50.170 --> 31:57.820
We're now ready to start doing cool things like damage and parameterizing some of these values in melee

31:57.850 --> 32:01.400
attacks so we can reuse it with a bunch of different types of enemies.

32:01.400 --> 32:04.400
So things are starting to look great.

32:04.550 --> 32:07.670
Excellent job and I'll see you in the next video.
