WEBVTT

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

00:07.910 --> 00:11.180
Now I've got my aura effect actor open here.

00:11.180 --> 00:14.210
I'm going to right click on it and close the other tabs.

00:14.360 --> 00:23.360
So I just have my CPP file and my aura effect actor here is actually kind of really specific.

00:23.390 --> 00:28.190
It has a sphere component, so we can't really change that.

00:28.190 --> 00:32.030
If we wanted a box, well, we'd be kind of out of luck.

00:32.030 --> 00:39.050
And when something overlaps with that sphere, well we see if the other actor implements the ability

00:39.050 --> 00:40.100
system interface.

00:40.100 --> 00:44.330
If it does, then we reach into its attribute set.

00:44.360 --> 00:51.500
We cast away the constness of the const pointer returned from get attribute set, which should give

00:51.500 --> 00:55.790
us a sort of dirty feeling like we're not doing something we should be doing.

00:55.790 --> 01:03.950
And then we directly set the health and the mana equal to what they were before, plus or minus some

01:03.950 --> 01:05.060
hardcoded value.

01:05.060 --> 01:11.760
So this is all a whole bunch of really rigid, restrictive things that doesn't make our aura effect

01:11.760 --> 01:18.780
actor good for really anything other than adding 25 to the health and subtracting 25 from mana.

01:18.960 --> 01:25.530
We have no flexibility, no modularity and well, this should be changed and that's what we're going

01:25.530 --> 01:26.730
to do in this video.

01:26.730 --> 01:32.940
We're going to make aura effect actor live up to the flexibility of its potential.

01:32.940 --> 01:35.640
We're going to make it a lot better.

01:35.640 --> 01:44.580
So what I'd like to do is rather than adding a static mesh and a sphere component in the C plus plus

01:44.580 --> 01:50.910
class, I'd like those to be things done in the designer domain on the blueprint side, because the

01:50.910 --> 01:58.500
visual representation of the actor and for that matter the shape of the overlap sphere could be determined

01:58.500 --> 01:59.790
by designers.

01:59.790 --> 02:03.450
Someone who works mostly on the blueprint side.

02:03.450 --> 02:12.840
And it's the technical details of what happens when we overlap or specifically when we'd like to apply

02:12.840 --> 02:16.920
some kind of effect that can be determined in C plus plus.

02:17.070 --> 02:18.960
So here's what I'm going to do.

02:18.960 --> 02:22.680
I'm going to actually remove the sphere and the mesh.

02:22.710 --> 02:25.650
We're going to go ahead and just remove both of those.

02:25.770 --> 02:33.360
I'm going to hit alt o and open up the header file and I'm going to remove both the sphere and the mesh.

02:34.750 --> 02:40.360
And for that matter, we really don't need on overlap and on end overlap.

02:40.360 --> 02:43.350
I'm going to remove both of these callbacks as well.

02:43.360 --> 02:49.120
And here in the CPP file, we can totally get rid of them altogether.

02:49.300 --> 02:55.780
And in Beginplay we no longer have a sphere to bind callbacks to its overlap event.

02:55.780 --> 03:01.630
So we're essentially stripping this actor almost completely clean.

03:02.020 --> 03:05.190
In fact, most of these headers aren't being used anymore.

03:05.200 --> 03:07.090
Now, why did I do that?

03:07.090 --> 03:14.170
Well, I'd like to still have functionality here in C plus plus, but I'd like to give the designer

03:14.170 --> 03:17.920
side some control over how this actor works.

03:17.920 --> 03:24.130
I'd like to make this actor really flexible and easily configurable on the blueprint side.

03:24.130 --> 03:31.540
So if we want to add a mesh or a sphere or a box or capsule component, we can do that and we can add

03:31.540 --> 03:33.210
it to the root component.

03:33.220 --> 03:42.860
So really I'm going to use create default Subobject with a simple scene component, you scene component

03:43.100 --> 03:51.050
and call this scene root and I'm going to set the root component to the result of this.

03:51.050 --> 03:58.430
So I'm going to call set root component setting the root component to the result of simply creating

03:58.430 --> 03:59.570
a scene component.

03:59.570 --> 04:00.620
And that's it.

04:00.620 --> 04:03.470
So if we compile and run this code.

04:04.670 --> 04:08.060
We can search for potion here.

04:08.060 --> 04:10.340
There's that BP health potion.

04:10.340 --> 04:14.030
It's been stripped of all that makes it a health potion.

04:14.030 --> 04:21.560
I'm going to delete it from the world and go into my blueprints folder into actor And here's BP health

04:21.560 --> 04:22.010
potion.

04:22.010 --> 04:26.900
If I open the full blueprint editor, there's that root component and there's nothing else.

04:26.900 --> 04:28.820
We've stripped it all clean.

04:28.850 --> 04:35.300
Now it seems like we've made this actor class less capable, but what we've actually done is we've made

04:35.300 --> 04:43.250
it more versatile by no longer restricting the visual representation or the overlap volume to the C

04:43.280 --> 04:44.300
plus plus side.

04:44.330 --> 04:49.520
We now have the freedom to choose and customize it here in the blueprint.

04:49.520 --> 04:58.100
So for the mesh, I can click add, I can add a static mesh to this and call this potion mesh and I

04:58.100 --> 05:00.230
can select the potion bottle.

05:01.110 --> 05:02.940
And I can change its scale.

05:02.940 --> 05:12.570
Let's put it down to 0.2 in all dimensions, and I haven't scaled the entire actor as the root component

05:12.570 --> 05:14.520
is still at a scale of one.

05:14.520 --> 05:17.130
We can't see it because it's not exposed.

05:17.130 --> 05:20.610
And if we wanted, we could set this to a U.

05:20.610 --> 05:22.980
Property variable with visible anywhere.

05:22.980 --> 05:25.020
But for now, I'm fine without that.

05:25.050 --> 05:27.930
We now have the ability to add things.

05:27.930 --> 05:33.180
In addition to the potion mesh, I can add a overlap volume.

05:33.180 --> 05:34.950
Let's say I want that sphere back.

05:34.950 --> 05:40.500
I can type in sphere, we can get a sphere collision and we'll call this sphere.

05:40.530 --> 05:41.520
We'll just call it sphere.

05:41.550 --> 05:42.450
That's fine.

05:42.450 --> 05:44.340
And there it is.

05:44.340 --> 05:48.540
And now I have control over what happens when the sphere gets overlapped.

05:48.690 --> 05:54.870
Now, since I added the potion mesh here in Blueprint, I have to configure collision settings in Blueprint.

05:54.870 --> 05:55.980
That's not a problem.

05:55.980 --> 06:02.230
All I need to do is come over here, come to Collision Presets and choose no collision as I don't want

06:02.230 --> 06:04.270
the mesh to collide with anything.

06:04.270 --> 06:08.980
And for the sphere, well, spheres automatically overlap all dynamic.

06:08.980 --> 06:10.120
I'm fine with that.

06:10.150 --> 06:17.710
Now we can go into the event graph and with the sphere selected I can use on component began overlap.

06:18.640 --> 06:21.780
For the sphere itself and do what I'd like here.

06:21.790 --> 06:28.060
So in many ways, taking some of that stuff out of C plus plus and moving it to the blueprint side makes

06:28.060 --> 06:29.530
this a lot better.

06:29.530 --> 06:33.520
And we'll see why once we start using this effect.

06:33.520 --> 06:35.960
Actor to apply effects.

06:35.980 --> 06:42.460
You see, what we'd like to do with the other actor is apply some sort of effect and our effect actor

06:42.460 --> 06:46.390
can have a variable for an effect to apply.

06:46.420 --> 06:50.560
That's what we're going to add and we're going to create a function to apply that effect.

06:50.590 --> 06:56.920
Now, again, doing this in blueprint versus C plus plus is a matter of choice.

06:56.920 --> 07:04.090
And in many ways, adding this functionality here in Blueprints gives us a little bit more control on

07:04.090 --> 07:05.380
this side of things.

07:05.380 --> 07:10.180
But we're going to do this on the C plus plus side for educational purposes.

07:10.180 --> 07:16.420
I think it's important for you to see how to do things both in C plus plus and blueprint so that way

07:16.420 --> 07:22.250
you can make the decision as in some cases it will be more appropriate to do in C plus plus and in some

07:22.250 --> 07:25.400
cases it'll be more appropriate to do here in blueprint.

07:25.430 --> 07:31.940
So what we're going to do is add a gameplay effect to this class in C plus plus and learn how we can

07:31.940 --> 07:37.820
apply that effect to the actor that overlaps with this sphere.

07:37.820 --> 07:45.620
And then we'll see later how we can derive from our effect actor and add any type of overlap volume

07:45.620 --> 07:46.400
we wish.

07:46.400 --> 07:53.090
And we'll really start to see how carefully choosing the balance between C plus plus and blueprints

07:53.120 --> 07:57.560
can allow us to have more choices in our game design.

07:57.560 --> 08:02.630
So I'm going to go ahead and save all and we're going to close out of this and we're going to make a

08:02.630 --> 08:09.830
function that we can call to apply an effect, and we're going to make an effect that we can apply.

08:09.860 --> 08:14.570
Now, I want to be able to set this effect from the blueprint side.

08:14.570 --> 08:22.540
I'm going to make this protected, and it's going to be a subclass of of type U gameplay effect.

08:23.170 --> 08:25.840
We're going to add a forward declaration for that.

08:25.870 --> 08:29.500
We no longer need the forward declaration for U sphere components.

08:29.500 --> 08:31.000
So we'll remove that.

08:31.000 --> 08:36.430
And I'm going to call this instant gameplay effect class.

08:36.910 --> 08:41.710
So it's the class for an instant gameplay effect that we'd like to apply.

08:41.740 --> 08:47.140
I'm going to add a U property to it and make it edit anywhere and give it the category.

08:48.610 --> 08:50.320
Applied effects.

08:51.600 --> 08:54.360
And if you want, you can just call it effects.

08:54.390 --> 08:55.110
It doesn't matter.

08:55.110 --> 08:56.820
I'm going to call it applied effects.

08:56.970 --> 09:05.280
And now that we have this class, I'd like to make a function that we can call to apply this gameplay

09:05.280 --> 09:06.030
effect.

09:06.270 --> 09:08.580
It's also going to be protected.

09:09.120 --> 09:10.440
It'll be void.

09:11.070 --> 09:16.890
And what I'd like to call this is apply effect to Target.

09:17.370 --> 09:21.060
And it's going to take an A actor as a target.

09:21.090 --> 09:33.000
We'll call it Target, and it'll also take a subclass of of type gameplay effect called gameplay effect

09:33.000 --> 09:33.900
class.

09:34.910 --> 09:39.050
And I'd like this function to be a new function with blueprint callable.

09:39.080 --> 09:42.470
That way we can call it from Blueprint whenever we want.

09:42.500 --> 09:44.870
I'm going to go ahead and generate the definition.

09:45.110 --> 09:48.740
And here's where we want to apply the effect to the target.

09:48.770 --> 09:56.090
Now, we've seen before that we can get the ability system of some actor by seeing if that actor implements

09:56.090 --> 09:57.710
the ability system interface.

09:57.800 --> 10:01.130
We say I ability system interface.

10:01.160 --> 10:08.080
We can call it as interface equals and then we take that other actor and cast it to the interface.

10:08.090 --> 10:13.790
We say cast to I ability system interface and we cast that actor.

10:13.790 --> 10:17.240
We're going to call this cast function on the target actor.

10:17.240 --> 10:25.160
And if this cast succeeds, then we have an ability system interface so we can say if AC interface.

10:27.190 --> 10:33.670
And then we have access to the interface by saying ASC interface and we call that function get ability

10:33.670 --> 10:34.790
system component.

10:34.810 --> 10:36.940
So that's one way to do it.

10:36.970 --> 10:42.910
Now there's another way, and that's by the use of a static function library.

10:42.940 --> 10:49.720
You should be familiar with things like gameplay statics and kismet math library and static function

10:49.720 --> 10:50.740
libraries like that.

10:50.740 --> 10:53.320
Well, there's one for gas as well.

10:53.320 --> 10:57.910
It's called you Ability System Blueprint Library.

10:58.480 --> 11:06.310
And there's a handy dandy function get ability system component, and it requires an actor we can pass

11:06.310 --> 11:07.270
in target.

11:07.270 --> 11:09.340
And what do you think this returns?

11:09.370 --> 11:16.240
Well it returns an ability system component and of course up here at the top rider included that header

11:16.240 --> 11:16.630
for me.

11:16.630 --> 11:21.010
So if you're not using rider, make sure you get that include up there.

11:21.040 --> 11:23.170
Now, how does this magic function work?

11:23.170 --> 11:32.150
Well, we can go to declaration or usages and we see that it just calls ability system globals get ability

11:32.150 --> 11:34.010
system component from actor.

11:34.040 --> 11:37.010
Let's dive deeper down the rabbit hole, shall we?

11:37.010 --> 11:43.850
We'll go to the declaration or usage of this and if the actor passed in is null we return null.

11:43.850 --> 11:45.470
And look at this.

11:45.500 --> 11:49.100
It's casting actor to ability system interface.

11:49.100 --> 11:56.210
And if that cast succeeds, it returns the ability system component on that interface.

11:56.210 --> 11:57.860
How nice.

11:57.890 --> 12:01.250
Well, it also has a boolean called look for component.

12:01.250 --> 12:08.960
And if that ability system interface cast fails, then it uses find component by class.

12:08.960 --> 12:15.620
So this function is a little bit better because, well, you might have actors in your world that don't

12:15.650 --> 12:20.030
implement the ability system interface we usually do, right?

12:20.030 --> 12:24.320
We mentioned earlier that we implement this interface because it's easy, right?

12:24.350 --> 12:30.050
We can always cast to that interface and call get ability system component and get the ability system

12:30.050 --> 12:31.070
component.

12:31.070 --> 12:37.760
But well, you know, not everybody follows those conventions and rules of thumb.

12:37.760 --> 12:45.770
And so the gas system has these global libraries that are designed to handle those edge cases.

12:45.770 --> 12:50.120
And here's one where the actor may not implement that interface.

12:50.120 --> 12:58.130
And if it doesn't, well, this function is designed to look for any component on the actor that has

12:58.130 --> 13:00.320
the type ability system component.

13:00.320 --> 13:03.740
If it does, it'll find that component and return it.

13:03.740 --> 13:07.400
So this is a little more sophisticated than what we were doing.

13:07.400 --> 13:13.850
And for that reason, well, maybe you might want to default to using that function instead of this

13:13.850 --> 13:14.300
method.

13:14.300 --> 13:19.520
We were doing simply casting to the interface and getting the ability system component.

13:19.520 --> 13:25.730
It's up to you if you're in the habit of implementing the interface for all the actors in your game

13:25.730 --> 13:26.420
project.

13:26.420 --> 13:30.140
Maybe that's a policy that your game company will set.

13:30.170 --> 13:36.350
You know, your whole dev team may get together, have a meeting and say, we will implement the interface

13:36.350 --> 13:37.370
no matter what.

13:37.400 --> 13:40.160
Then we can always cast to it and it works.

13:40.250 --> 13:45.410
Or you may decide, well, these actors over here aren't going to implement the interface for one reason

13:45.410 --> 13:45.830
or another.

13:45.830 --> 13:52.490
And in that case, for that reason you may opt to use the ability system, blueprint, library function,

13:52.490 --> 13:54.110
get ability system component.

13:54.110 --> 13:56.540
Either way you have options.

13:56.540 --> 14:02.270
And just so you know, this is blueprint callable and it's a very handy way to get an ability system

14:02.270 --> 14:04.970
component of any actor in blueprint.

14:04.970 --> 14:06.580
So there's that.

14:06.590 --> 14:11.360
So what we're going to do is use this instead of what we were doing before.

14:11.360 --> 14:17.300
So I'm going to replace this line with this one where we get an ability system component.

14:17.300 --> 14:24.470
I'm going to go ahead and store it in a new ability system component pointer called Target ASC.

14:25.550 --> 14:35.000
And if you're shaking your head and tsk tsking at me for having ASC in the name, I apologize for that.

14:35.000 --> 14:38.510
Feel free to call this target ability system component.

14:38.510 --> 14:43.880
And of course this returns a ability system component, not an aura ability system component.

14:43.880 --> 14:46.940
So I can't have aura in the type name there.

14:46.940 --> 14:53.090
And once we have this target ability system component, we can now apply effects.

14:53.090 --> 15:00.860
We can apply this game play effect, We have the class and there are many different options and ways

15:00.860 --> 15:02.300
to do things in gas.

15:02.300 --> 15:07.550
And by the end of this course you'll know just about a dozen ways to do any given thing.

15:07.550 --> 15:14.420
The first way that we'll learn how to apply a game play effect is as follows.

15:14.420 --> 15:16.730
The ability system component.

15:16.910 --> 15:26.060
Here we have Target ASC, which is an ability system component pointer has a function called apply gameplay

15:26.060 --> 15:26.660
effect.

15:26.700 --> 15:33.540
And before I finished typing, I want you to notice all of these options we have apply gameplay effect

15:33.540 --> 15:34.450
to self.

15:34.470 --> 15:37.530
We have apply gameplay effect to target.

15:37.560 --> 15:46.320
We have apply gameplay effect spec to self and apply a gameplay effect spec to target and of course

15:46.320 --> 15:48.180
blueprint versions of these.

15:48.210 --> 15:52.480
Now just so we don't get overwhelmed, we're just going to pick one of these.

15:52.500 --> 15:56.820
We're going to pick apply gameplay effect spec to self.

15:56.820 --> 16:06.360
So let's type that spec to self and we'll open the parentheses and we'll see that the first input parameter

16:06.360 --> 16:10.440
is a const reference to a gameplay effect spec.

16:10.650 --> 16:15.480
Now the other input parameter is a prediction key.

16:15.510 --> 16:20.260
Prediction has to do with prediction in a lag compensation sense.

16:20.280 --> 16:22.170
We'll get into prediction later.

16:22.200 --> 16:23.550
Don't worry about that.

16:23.550 --> 16:27.640
For now, it's an optional parameter, so we're going to leave it out for now.

16:27.670 --> 16:30.460
We just care about the gameplay effect spec.

16:30.460 --> 16:32.400
How do we get one of those?

16:32.410 --> 16:34.780
If we could just manage to pass one of those in.

16:34.810 --> 16:37.030
We can apply a gameplay effect, right.

16:37.210 --> 16:41.350
So we want to get an effect spec.

16:41.350 --> 16:47.250
Well we can make one and the ability system component has the ability to do that.

16:47.260 --> 16:52.960
We're just going to use the target's ability system component because any ability system component can

16:52.960 --> 16:56.920
make an effect spec given some gameplay effect class.

16:56.920 --> 16:59.710
So we're going to say Target ASC.

16:59.740 --> 17:02.170
We're going to get that ability system component.

17:02.200 --> 17:05.770
I'll go ahead and comment out this line until we're ready.

17:05.770 --> 17:14.230
And the ability system component has a function called make outgoing spec and make outgoing spec takes.

17:14.230 --> 17:18.580
Well, how about this a subclass of you gameplay effect.

17:18.580 --> 17:23.950
That's what we have here to subclass of gameplay effect called gameplay effect class.

17:23.950 --> 17:28.870
We're going to pass that in to satisfy that argument requirement.

17:28.900 --> 17:31.600
Now next is a float called level.

17:31.690 --> 17:38.800
You see, gameplay effects can have their own levels and as our game project gets bigger and more serious,

17:38.800 --> 17:41.320
we'll have different levels for everything.

17:41.320 --> 17:49.780
But for now we'll just use one point F, 1.0, f, one point f, same thing and f gameplay effect context

17:49.780 --> 17:51.790
handle called context.

17:51.790 --> 17:54.240
That's the third input parameter that we need.

17:54.250 --> 17:56.110
So what exactly is that?

17:56.110 --> 18:03.190
Well, a gameplay effect is closely related to something called an effect context.

18:03.190 --> 18:06.670
Context meaning what's the context of the effect?

18:06.760 --> 18:09.130
What is the context of the situation?

18:09.130 --> 18:10.780
Who's causing the effect?

18:10.810 --> 18:12.880
Who's the target of the effect?

18:12.910 --> 18:15.940
Is the effect a fire effect?

18:15.940 --> 18:17.020
Lightning effect?

18:17.050 --> 18:24.430
There's really no end to how you can describe a gameplay effect and the context surrounding it, but

18:24.430 --> 18:31.180
the gameplay effect context is something that we associate with the gameplay effect, specifically its

18:31.180 --> 18:40.210
effect spec by passing in an effect context actually an effect context handle a handle is a lightweight

18:40.210 --> 18:43.390
thing that contains the pointer to the context itself.

18:43.390 --> 18:46.270
Now how do we make that context handle?

18:46.270 --> 18:49.330
Well, the ability system component has a function for that.

18:49.330 --> 18:51.430
It has a function for everything really.

18:51.430 --> 18:57.250
So we're going to comment that line out until we're ready to continue with it because we need an effect

18:57.250 --> 18:58.600
context, right?

18:58.600 --> 19:04.360
So we're going to say Target ASC make effect context.

19:04.390 --> 19:06.100
This doesn't take any inputs.

19:06.100 --> 19:11.530
It's just a function that makes an effect context and returns a handle to that.

19:11.530 --> 19:15.760
You see, it returns an F gameplay effect context handle.

19:15.760 --> 19:20.410
Now at this point, we're going to slow down and start taking a look at these types so we don't get

19:20.410 --> 19:21.460
confused.

19:21.460 --> 19:30.250
We know that this is an F game play effect context handle and we're going to call this effect context

19:30.280 --> 19:32.830
handle just so we're not confused.

19:32.830 --> 19:36.190
And now it's time to start looking at these types.

19:36.190 --> 19:44.170
So I'm going to right click on F gameplay effect context handle, go to declaration or usages and we

19:44.170 --> 19:50.690
see that it's defined here in gameplay effect types dot h and we see that it's a handle that wraps f

19:50.740 --> 19:57.760
gameplay effect context or a subclass allowing it to be polymorphic and replicate properly so we can

19:57.760 --> 20:04.510
subclass the effect context if we want to add things for fire or lightning or poison or really anything

20:04.510 --> 20:08.830
we want, It doesn't have to be related to damage or anything like that.

20:09.010 --> 20:16.180
The handle is a lightweight wrapper that stores the actual effect context as a pointer.

20:16.180 --> 20:17.530
It's called data.

20:17.680 --> 20:22.780
See data is a shared pointer of type gameplay effect context.

20:22.780 --> 20:26.470
So data here is the true context.

20:26.540 --> 20:31.940
The handle itself is just a wrapper that has a couple of utilities.

20:31.970 --> 20:34.910
It has the ability to clear that pointer.

20:34.940 --> 20:38.330
We have an is valid function to check if it's valid.

20:38.360 --> 20:46.610
We have a way to get any gameplay tags that that affect context may have and we'll learn more about

20:46.610 --> 20:47.430
those later.

20:47.450 --> 20:50.930
We can add things like instigators, set abilities.

20:50.930 --> 20:57.750
It has a bunch of utilities, but really at the heart of this handle is the context itself called data.

20:57.800 --> 20:58.820
So make effect.

20:58.820 --> 21:06.470
Context is just a way to create that wrapper that contains an internal gameplay effect context, and

21:06.470 --> 21:08.720
we can set things on that context.

21:08.840 --> 21:15.980
For example, we can take effect context handle and we can call add source object.

21:15.980 --> 21:25.670
So if we want to know what caused this effect, we can store a source object and just peeking this definition

21:25.670 --> 21:32.130
add source object that we see that it takes the data inside and calls, add source object.

21:32.130 --> 21:40.440
And if we check out the definition of that, we see that now we're inside the effect context struct.

21:40.680 --> 21:41.460
Gameplay effect.

21:41.460 --> 21:42.240
Context.

21:42.240 --> 21:43.710
And what does this do?

21:43.710 --> 21:51.060
Well, it takes that you object and it sets an internal member variable called source object uses a

21:51.060 --> 21:57.330
weak pointer and that basically means it won't affect garbage collection, it won't affect reference

21:57.330 --> 21:59.070
counting for garbage collection.

21:59.070 --> 22:07.380
So the gameplay effect context has the ability to store things related to the context of the gameplay

22:07.380 --> 22:08.060
effect.

22:08.070 --> 22:14.880
So we'll go ahead and add the source object so that say some time down the line we need to know what

22:14.910 --> 22:17.210
object caused this effect.

22:17.220 --> 22:21.510
Well, we can know by checking the source object on the effect context, for instance.

22:21.690 --> 22:27.630
So now that we have an effect context, we're going to uncomment the next line where we're calling make

22:27.660 --> 22:31.530
outgoing spec, which needs that effect context.

22:31.530 --> 22:38.340
We're going to pass it in for the third parameter, and this function requires an gameplay effect context

22:38.370 --> 22:43.110
handle specifically so we can just pass in the handle like so.

22:43.740 --> 22:50.160
Now make outgoing spec returns an gameplay effect spec handle.

22:50.400 --> 22:57.270
So let's store that in a local for gameplay effect spec handle.

22:59.580 --> 23:03.060
And we'll call this effect spec handle.

23:03.600 --> 23:05.670
No need for that equal sign there.

23:05.670 --> 23:06.450
There we go.

23:06.540 --> 23:09.000
So you'll see a lot in gas code.

23:09.030 --> 23:12.690
These words like handle will be omitted.

23:12.690 --> 23:18.210
For example, we know that make outgoing spec returns a spec handle, right?

23:18.240 --> 23:26.310
You'll see oftentimes in gas code that a spec handle will have the name effect spec without the handle

23:26.310 --> 23:27.090
on it.

23:27.090 --> 23:28.260
So be aware of that.

23:28.260 --> 23:34.440
If you're looking at other gas code in other projects you'll see effect spec and you'll hover over it

23:34.440 --> 23:40.380
and you'll see, well it's actually an effect spec handle that's pretty common to leave off that handle

23:40.380 --> 23:44.850
part because well, it makes the variables longer.

23:44.970 --> 23:50.730
But in this case we're going to try to keep it descriptive of what it is so as to avoid confusion.

23:50.730 --> 23:58.960
But just, just know that you might see a variable called effect spec or just spec that really is an

23:58.960 --> 24:00.130
effect spec handle.

24:00.130 --> 24:03.070
So look at the type to be sure.

24:03.070 --> 24:06.730
Now these handles are wrappers, right?

24:06.730 --> 24:13.330
We've seen that the effect context handle is a wrapper that holds a gameplay effect context.

24:13.360 --> 24:19.240
Well, similarly an effect spec handle is a wrapper that holds an effect spec.

24:19.240 --> 24:22.480
We can go to the definition of this.

24:23.020 --> 24:25.060
And see that it's an effect.

24:25.060 --> 24:26.060
Spec handle.

24:26.080 --> 24:32.080
The comment says allows blueprints to generate a gameplay effect spec once and reference it by handle

24:32.110 --> 24:36.070
to apply it multiple times to multiple targets etcetera.

24:36.070 --> 24:40.000
And notice it has its own data of type gameplay effect spec.

24:40.030 --> 24:43.630
It's wrapped in a shared pointer, but you get the gist.

24:43.630 --> 24:45.730
It has a data member variable.

24:45.730 --> 24:53.110
So these wrappers, these handles have an internal data member that stores the actual struct, in this

24:53.110 --> 24:55.180
case a gameplay effect spec.

24:55.180 --> 25:03.250
So we went through all that just to get this effect spec handle which now has the effect class a level

25:03.250 --> 25:06.520
and the effect context handle all set for it.

25:06.550 --> 25:15.310
Now we can take our target ASC and call apply gameplay effect spec to self, which takes the gameplay

25:15.310 --> 25:20.980
effect spec, but we have an effect spec handle not an effect spec.

25:21.010 --> 25:24.230
This function needs the effect spec, not the handle.

25:24.230 --> 25:32.120
So we need to get that data from inside the effect spec handle and notice that it takes an gameplay

25:32.120 --> 25:37.760
effect spec by const reference, not by pointer but by const reference.

25:37.760 --> 25:42.410
And we know that that data is a pointer inside of our handle.

25:42.410 --> 25:49.640
So to get that data we take our effect spec handle and we access data.

25:50.060 --> 25:53.600
Data as we saw was a smart pointer.

25:53.600 --> 25:59.000
So data itself is also yet another wrapper to get that raw pointer inside of it.

25:59.030 --> 26:05.930
We got to call get right, so right clicking and going to the declaration of data, we see that it's

26:05.930 --> 26:13.790
a shared pointer at least in gameplay effect spec handle and to get that raw pointer inside of the shared

26:13.790 --> 26:16.220
pointer wrapper we have to use get.

26:16.250 --> 26:19.130
Now that just returns us the raw pointer.

26:19.130 --> 26:26.050
But as I said, this function doesn't take a pointer to an gameplay effect spec, it takes a const reference

26:26.050 --> 26:27.370
so it can't be a pointer.

26:27.370 --> 26:33.640
We have to dereference the pointer, so using the asterisk that's going to get rid of those squiggles.

26:33.670 --> 26:41.650
Now we've drilled down to the gameplay effect spec buried down deep inside this gameplay effect spec

26:41.650 --> 26:42.040
handle.

26:42.040 --> 26:48.130
So it's a little bit of kind of syntax nightmare, but you take the effect spec handle, you get the

26:48.130 --> 26:54.820
data, which is a shared pointer, storing a gameplay effect spec pointer in its raw form.

26:54.820 --> 27:02.830
You call get to get that raw pointer and then all of this gets dereferenced into the gameplay effect

27:02.830 --> 27:07.420
spec that apply gameplay effect spec to self craves and desires.

27:07.420 --> 27:13.720
And with our semicolon there we now have a successful call to this function.

27:13.720 --> 27:21.430
So as long as our subclassof is set to some gameplay effect, apply a gameplay effect to target should

27:21.430 --> 27:29.390
work when we pass that in and we pass in a target that has an ability system component now to kind of

27:29.390 --> 27:30.680
safeguard us.

27:30.680 --> 27:38.450
You know, we could check the pointer target ASC and do nothing if it doesn't have an ability system

27:38.450 --> 27:40.370
component, we could do it that way.

27:40.370 --> 27:42.110
And think about this.

27:42.140 --> 27:48.140
If something overlaps with the volume, it may not have an ability system component.

27:48.140 --> 27:52.700
And in that case, well, we don't really want to crash the program or anything.

27:52.700 --> 27:56.120
We kind of just want the pickup to do nothing, right?

27:56.120 --> 27:58.940
So what I'm going to do is simply check the pointer.

27:58.940 --> 28:09.230
We're going to say if Target ASC is a null pointer, we'll just return and do nothing and otherwise

28:09.230 --> 28:11.630
we'll apply the effect that we have.

28:11.630 --> 28:15.380
But the effect itself should not be unset.

28:15.410 --> 28:17.390
That's something we want to check.

28:17.390 --> 28:20.420
We're going to say check gameplay effect class.

28:20.420 --> 28:23.210
If that's a null pointer, we got problems right.

28:23.210 --> 28:29.510
We should definitely set this because this aura effect actor is designed to apply an effect.

28:29.510 --> 28:33.170
If it doesn't have an effect, we're going to crash intentionally here.

28:33.560 --> 28:35.750
Okay, so this is looking pretty good.

28:35.750 --> 28:40.310
We have apply effect to Target and we can call this from Blueprint.

28:40.310 --> 28:47.210
So since we have our sphere set up in Blueprint, we're going to call this when overlapping, but we

28:47.210 --> 28:53.540
also need to create a gameplay effect and that is something we're going to get into in the next video

28:53.540 --> 28:57.920
and we'll tie this all together and see our effect actor in action.

28:57.920 --> 29:00.680
So in the meantime, go ahead and compile your code.

29:00.680 --> 29:04.340
Make sure there are no typos or anything like that.

29:04.340 --> 29:09.020
If you want, you can go up here and remove any of these unused includes.

29:09.260 --> 29:10.910
They're not needed either.

29:10.910 --> 29:14.540
And in the next video, we'll get this all working.

29:14.540 --> 29:19.340
So great job, well done for sitting through a bit of a lengthy discussion.

29:19.340 --> 29:22.460
But, you know, these things are kind of important.

29:22.640 --> 29:24.350
To understand in depth.

29:24.350 --> 29:32.150
And the better you understand the working parts here, the more capable you'll be when you start implementing

29:32.150 --> 29:33.830
these type of effects on your own.

29:33.830 --> 29:35.540
So great job.

29:35.690 --> 29:42.710
And I'm just noticing the green squiggles writer says that this can be a const variable.

29:42.710 --> 29:43.520
Why not?

29:43.940 --> 29:47.900
We'll go ahead and do that and I'll see you in the next video.
