WEBVTT

00:06.920 --> 00:08.120
Welcome back.

00:08.360 --> 00:16.070
Now we've just overridden a function called pre attribute change, and we've used it to perform some

00:16.070 --> 00:19.670
clamping here in the attribute set.

00:19.940 --> 00:24.710
Now pre attribute change is really only good for clamping.

00:24.710 --> 00:29.990
It's not really good for kicking off any logic in response to attribute changes.

00:30.470 --> 00:32.600
But that's not to say that we can't do that.

00:32.630 --> 00:34.760
This is just not the place for it.

00:34.880 --> 00:42.260
Now there is another function that's extremely useful for the attribute set, and we're going to override

00:42.260 --> 00:43.460
that now.

00:43.610 --> 00:52.250
So let's say virtual void and the function is called post gameplay effect execute.

00:52.490 --> 00:55.430
Let's go ahead and get that declared.

00:55.430 --> 01:03.860
And we see that it takes a const reference called data of type gameplay effect mod callback data.

01:04.160 --> 01:12.240
Now I'm going to generate the definition for this function and let that super call exist and now we

01:12.240 --> 01:15.090
have post gameplay effect execute.

01:15.330 --> 01:20.250
Now post gameplay effect execute is pretty self descriptive.

01:20.280 --> 01:29.490
This is executed after a gameplay effect changes an attribute and we have access to a lot of information

01:29.490 --> 01:32.970
via this data input parameter.

01:33.000 --> 01:40.950
We can access a whole lot of info based on the effect that was just applied and we're going to harvest

01:40.950 --> 01:44.070
some information from this data parameter.

01:44.250 --> 01:50.990
And for starters, we're going to take our data and see what attribute has been changed.

01:51.000 --> 01:56.580
We can do that by taking data and accessing evaluated data.

01:56.670 --> 02:00.210
Now you probably see in the pop up effect spec and target.

02:00.210 --> 02:06.330
So already we're seeing some really useful information, but we're going to get that evaluated data

02:06.330 --> 02:13.260
and from evaluated data, if we type the Dot, you'll see that we have some information here, including

02:13.260 --> 02:16.380
attribute the gameplay attribute.

02:16.380 --> 02:21.320
So we know from the data which attribute is being changed here.

02:21.330 --> 02:24.540
For example, we can wrap this in an If statement.

02:25.630 --> 02:32.140
And use comparison and see if the attribute is equal to, for instance, get health attribute.

02:32.530 --> 02:39.820
We'll compare to that attribute, and if it is the health attribute, we can just place a UI log here.

02:40.330 --> 02:47.260
I'll use log temp warning and spit out the value of health.

02:49.670 --> 02:54.470
And we can really just get the current value of health with git health.

02:55.070 --> 03:03.980
Now we can also get the magnitude or the amount changed in the health from that gameplay effect.

03:04.370 --> 03:05.990
I'm going to print that out as well.

03:05.990 --> 03:13.430
So I'm going to copy and paste this line and we're going to say magnitude.

03:15.050 --> 03:21.770
And we can get that from the data as well with data dot evaluated data.

03:21.800 --> 03:23.540
Dot magnitude.

03:24.440 --> 03:27.830
So this will be how much we're changing the health.

03:28.010 --> 03:29.330
Let's just test this out.

03:29.330 --> 03:32.340
I'm going to hit debug and we'll run in debug mode.

03:32.360 --> 03:39.500
I'm running a debug so that I can place breakpoints and inspect some of the data that we have here.

03:39.500 --> 03:43.460
But first, let's just see what we get printed to the output log.

03:44.140 --> 03:51.670
So I'm going to go ahead and press play and walk into the fire volume and we see 49, 48, 47 and magnitude

03:51.670 --> 03:52.930
is negative one.

03:52.940 --> 03:58.180
If we pick up the health potion, we see that we go from 44 to 69.

03:58.180 --> 04:01.840
Magnitude of that gameplay effect was 25.

04:01.870 --> 04:08.680
Here we got our mana increased, which we have nothing printed to the screen because we're only printing

04:08.680 --> 04:10.930
if that attribute is health.

04:10.930 --> 04:12.850
So let's get the health crystal.

04:12.850 --> 04:20.200
And there we see it going up by one Each time you get the gist, we can get information right now.

04:20.200 --> 04:23.410
Let's go ahead and place a break point.

04:23.440 --> 04:31.180
We'll place it right here on the log and let's run the game and trigger that break point.

04:31.360 --> 04:31.900
Okay.

04:31.900 --> 04:33.790
So we've triggered the break point.

04:33.790 --> 04:35.770
We have some information now.

04:35.920 --> 04:39.610
And what I'm mostly interested in right now is data.

04:39.610 --> 04:44.870
And right here at the bottom right, we can expand the data dropdown.

04:44.930 --> 04:50.870
Now data has effects back, evaluated data and target.

04:51.200 --> 04:56.810
Now in just these three variables, data has quite a lot of information.

04:56.960 --> 05:06.020
If we expand effect spec, the effect spec of course has the definition or def we can see the object

05:06.020 --> 05:15.440
in def has the name default G fire area C, so that's the gameplay effect default object.

05:15.470 --> 05:18.590
We have the duration magnitude and all of its information.

05:18.590 --> 05:21.350
We have the period and all of its information.

05:21.350 --> 05:25.580
We can really get any information that we need from this.

05:25.610 --> 05:30.350
Aside from that, we have evaluated data that tells us the attribute.

05:30.350 --> 05:33.710
The modifier operation is additive.

05:33.710 --> 05:35.390
We have that information.

05:35.390 --> 05:38.750
We have the magnitude of negative one.

05:38.780 --> 05:43.430
Here's the actual handle, the active gameplay effect handle.

05:43.430 --> 05:47.930
We have access to that and then we have our target.

05:47.960 --> 05:54.650
The ability system component here is the ability system component of this gameplay ability so we can

05:54.650 --> 05:55.610
access that.

05:55.610 --> 06:02.690
And if we can access the ability system component of the target, that means we can access the ability

06:02.690 --> 06:08.780
actor info, both the owner, actor and the avatar actor.

06:08.780 --> 06:10.550
We can get all that stuff.

06:11.150 --> 06:17.210
So not only can we get information about the target, we also can get information about the source because

06:17.210 --> 06:26.900
the effect spec here is a gameplay effect spec which can get the context and the context has information

06:26.900 --> 06:29.120
about the source if we set that.

06:29.690 --> 06:33.430
Here's the effect context and its data.

06:33.440 --> 06:35.270
We have instigator.

06:35.270 --> 06:37.940
In this case, it's the Or player state.

06:37.970 --> 06:42.290
We have the effect causer BP or a character.

06:42.290 --> 06:50.000
These are just set in the effect context because the effect context was created using the ability system

06:50.000 --> 06:53.390
component of the overlapped actor in this case.

06:53.390 --> 07:00.470
So when you call make effect context from an ability system component, a lot of these are set automatically

07:00.470 --> 07:06.950
and we just happen to be using the ASC of whatever actor is overlapping with our effect.

07:06.950 --> 07:14.240
Actor So in that case, the source is going to be really the ability system component of that actor

07:14.240 --> 07:16.370
because they made the effect context.

07:16.370 --> 07:24.380
But in combat, for example, when Aura launches a fireball at an enemy, she's going to be the source.

07:24.380 --> 07:27.230
And then the enemy that gets hit will be the target.

07:27.230 --> 07:36.720
So ultimately, in post gameplay effect, execute, we have access to just about every entity involved

07:36.720 --> 07:40.830
in this gameplay effect being executed, which is huge.

07:40.830 --> 07:49.950
It's a very powerful thing, so it can be useful for us to collect a bunch of data about the gameplay

07:49.950 --> 07:52.440
effect and store it.

07:52.530 --> 07:54.990
We can create a bunch of local variables here.

07:54.990 --> 08:00.630
We can even store them all in a data structure for this particular effect execution.

08:00.750 --> 08:07.590
And so what we're going to do in this video is collect all the data that we may end up using, and it'll

08:07.620 --> 08:13.170
be a nice learning exercise that will show us just how much data we can get in post gameplay effect,

08:13.170 --> 08:14.160
execute.

08:14.280 --> 08:20.730
And then later in the course, as we're implementing our combat mechanics, we can use this function

08:20.730 --> 08:25.950
as a really handy way to respond to gameplay effects being executed.

08:25.950 --> 08:27.870
So I'm going to go ahead and hit stop.

08:27.870 --> 08:33.290
That's going to close out of the editor and we're going to start collecting some data here.

08:33.290 --> 08:37.790
So I'm going to go ahead and remove the breakpoint and remove this code here.

08:37.790 --> 08:42.710
And we're going to start by getting our effect context.

08:42.710 --> 08:50.540
So if we take data and we get our effect spec from the effect spec, we can call the function get context.

08:50.540 --> 08:55.160
And this returns an gameplay effect context handle.

08:55.190 --> 08:57.350
We're going to store that in a local variable.

08:57.350 --> 09:05.120
So we're going to say gameplay effect context handle and we're going to call this effect context handle.

09:07.430 --> 09:09.890
So that's a piece of information, number one.

09:10.220 --> 09:16.970
Now, how do we get the ability system component from the source of this gameplay effect?

09:16.970 --> 09:21.980
And by the way, when I say source and target, just so we don't get confused, I'm just going to put

09:21.980 --> 09:32.600
a quick comment here that says source equals causer of the effect and then target equals well target

09:32.630 --> 09:33.620
of the effect.

09:35.720 --> 09:46.190
But in parentheses, owner of this attribute set right, the target is the thing being affected.

09:46.190 --> 09:50.510
In other words, this attribute sets owner right.

09:50.690 --> 09:59.120
The source is something else that applied in effect to us and then target is us right in this context.

09:59.240 --> 10:03.590
So we want the ability system component of the source.

10:03.590 --> 10:12.030
Well, we can take this effect context handle and there are many ways to get the ability system component.

10:12.060 --> 10:21.180
One of them is the function get original instigator ability system component and that returns a you

10:21.180 --> 10:24.060
ability system component to be lazy.

10:24.060 --> 10:30.720
I'm going to say auto ASC equals and then hover over auto and then copy the type.

10:34.550 --> 10:38.240
And replace auto with that type.

10:38.510 --> 10:41.000
But ASC isn't good enough.

10:41.000 --> 10:42.740
I'm going to call it source ASC.

10:43.610 --> 10:46.130
So we have the source ability system component.

10:46.400 --> 10:52.640
Now, if we have the source ability system component, we can get lots of things such as the source

10:52.670 --> 10:55.640
actor that owns that ability system component.

10:55.670 --> 10:58.150
Perhaps it's the avatar.

10:58.160 --> 11:08.210
So we can make an A actor called Source Avatar actor, for example, and we can get the source ability

11:08.210 --> 11:16.820
system component and we can always access from the ability system component, the ability actor info

11:17.510 --> 11:26.660
and that has the avatar actor And of course this is a pointer wrapper we have to call, get on that

11:26.660 --> 11:27.470
pointer.

11:27.890 --> 11:34.880
Okay, So we're doing a lot of accessing of pointers here and not all sources may have a valid ability

11:34.880 --> 11:37.760
system component or avatar actor.

11:37.760 --> 11:40.280
So what we're going to do is put some checks in place.

11:40.520 --> 11:46.650
We'll say if source ASC will use is valid here.

11:49.860 --> 11:58.800
And we'll say source ASC ability actor info dot is valid and then we'll also check the avatar actor.

11:58.800 --> 12:03.720
We'll say and source ASC ability actor info.

12:05.290 --> 12:08.380
Avatar actor is valid.

12:08.380 --> 12:15.400
So if you're confused that we're using ability actor info with the dot operator here and then with the

12:15.400 --> 12:20.110
arrow operator here, just remember these are wrapped in pointer wrappers.

12:20.140 --> 12:26.950
T Shared pointer is a smart pointer which has its own utilities, right?

12:26.950 --> 12:32.770
These wrappers are structs that have their own functions and it's the wrappers is valid function we're

12:32.770 --> 12:33.790
calling here.

12:33.790 --> 12:39.400
And after checking to make sure that the pointer is stored in the wrapper is valid, then we can use

12:39.400 --> 12:43.870
the arrow operator on it and check if that avatar actor is valid.

12:43.870 --> 12:50.080
If all this stuff is valid, then we'll store the source avatar actor.

12:50.170 --> 12:52.000
So we'll stick it right in there.

12:52.270 --> 12:54.310
Now we can get other stuff.

12:54.310 --> 12:58.030
For example, the player controller of the source.

12:58.060 --> 13:01.030
If the source has a player controller, right.

13:01.030 --> 13:04.700
That's something we can get from the ability actor info as well.

13:04.700 --> 13:16.460
We can say source, AC ability, actor info, we know that's valid and from that we can get player controller

13:16.730 --> 13:18.980
that's in the ability actor info.

13:18.980 --> 13:23.390
And of course this is in a wrapper, it's in a weak object pointer.

13:23.390 --> 13:28.250
So we'd have to call, get to get that pointer and we can store this.

13:28.280 --> 13:35.750
It's a player controller of type a player controller, so we can make a pointer called source player

13:35.750 --> 13:38.960
controller and we can get that.

13:39.440 --> 13:47.000
Now here's the thing, just in case our ability actor info has a null pointer for the player controller,

13:47.000 --> 13:54.650
we can always fall back on getting the player controller from the actor itself by casting it to a pawn.

13:54.800 --> 13:57.620
So what we'll do here is we'll just check.

13:57.620 --> 14:09.350
We'll say if source player controller is a null pointer in that case and our source avatar actor is

14:09.350 --> 14:10.760
not a null pointer.

14:12.610 --> 14:16.630
Then we'll attempt to get the player controller from the pawn directly.

14:16.630 --> 14:18.760
So we'll perform a cast here.

14:18.760 --> 14:24.820
We'll say if a pawn pawn equals cast to a pawn.

14:25.640 --> 14:28.120
Source, Actor, Source, Avatar, actor.

14:28.130 --> 14:36.050
If that cast is successful, then we now have the pawn We can call get controller using pawn.

14:36.950 --> 14:41.090
Get controller and get controller returns an A controller.

14:41.090 --> 14:45.200
So we could just cast a player controller like this.

14:45.200 --> 14:51.110
Or if we want the controller and don't care if it's a player controller or not, we could just call

14:51.110 --> 14:56.210
this source controller and make it an A controller instead.

14:56.210 --> 15:01.880
We can always cast later if we need it to be a player controller, I'll just call it source controller.

15:02.500 --> 15:09.700
And if we cast source Avatar actor to a pawn, then we don't need to cast.

15:09.730 --> 15:16.900
We'll just say source controller equals pawn get controller.

15:17.560 --> 15:19.030
So you have options here.

15:19.150 --> 15:23.140
Now we're casting because the source may not be a pawn.

15:23.170 --> 15:25.450
The source may not have a controller.

15:25.450 --> 15:32.680
So we're just, you know, setting it if we can, setting it, if it is upon that has a controller and

15:32.680 --> 15:39.190
we can make the pawn const here, we can make the A controller const here, the source ask can be made

15:39.190 --> 15:42.850
const and if we need to change it later, we can change it later.

15:42.880 --> 15:46.270
This can be made const the effect context handle as well.

15:46.540 --> 15:49.690
But either way we know that we can access the controller.

15:49.690 --> 15:55.780
So what we're doing is we're first getting it from the ability actor info, but if ability actor info

15:55.780 --> 16:01.840
contains a null pointer for the source controller, well then we'll just try to get it from the actor

16:01.840 --> 16:05.480
by casting to a pawn and getting the controller then.

16:05.480 --> 16:08.780
So it's kind of a optional second step there.

16:09.050 --> 16:12.020
Now we know that we have the source Avatar actor.

16:12.020 --> 16:13.640
We know that we have the pawn.

16:13.670 --> 16:17.900
We can also access the source character if it is a character.

16:17.900 --> 16:22.850
So, you know, at this point we have a source controller that may or may not be null.

16:22.850 --> 16:28.700
If it's not null, we can get its pawn and store its character as well.

16:28.700 --> 16:39.530
So we can say if source controller is not null or just if source controller, then we can get the source

16:39.530 --> 16:49.520
character, we can say a character source character and we can cast the pawn possessed by the controller

16:49.520 --> 16:50.390
to a character.

16:50.390 --> 16:53.660
We can say cast a character.

16:53.660 --> 16:58.640
And by the way, as I'm doing this, you're going to be thinking in your mind, Can't we do this in

16:58.640 --> 16:59.470
other way?

16:59.480 --> 17:03.430
I can think of three different ways to do it, and the answer is yes.

17:03.430 --> 17:06.460
There are lots of ways you can do all of this stuff.

17:06.460 --> 17:08.830
You can get the possessed pawn.

17:08.860 --> 17:12.880
You can cast the Avatar actor to a character.

17:12.910 --> 17:14.110
There's lots of ways.

17:14.500 --> 17:20.950
So I'm casting to an A character our source controller possessed pawn.

17:20.950 --> 17:22.690
We can get that with get pawn.

17:23.050 --> 17:25.780
Now it says a character is incomplete.

17:25.780 --> 17:30.070
We can always include a character up at the top.

17:30.070 --> 17:31.660
We'll go ahead and include it.

17:31.660 --> 17:33.310
It's in game framework, right?

17:33.310 --> 17:36.970
Game framework, Character dot H.

17:37.570 --> 17:38.470
All right.

17:38.470 --> 17:43.000
So as you can see, we have lots of info here that we got from the source.

17:43.030 --> 17:46.240
Now we can get stuff from the target as well.

17:46.240 --> 17:53.050
We can get the target ability system component, much like we got the source ability system component.

17:53.050 --> 17:56.950
So how are we going to get the target ability system component?

17:56.950 --> 17:59.470
Well, let's go down here to the bottom.

17:59.470 --> 18:06.170
If we take our data notice, we have target here, which is an ability system component.

18:06.290 --> 18:10.580
So there it is and we can easily store that.

18:10.790 --> 18:13.760
We also have the target ability actor info.

18:13.760 --> 18:23.840
So if we want that target actor, we can say a actor target actor and that's going to be data dot,

18:23.840 --> 18:29.360
target, dot, ability, actor info, avatar, actor.

18:29.810 --> 18:36.860
And of course we have to call get on that avatar actor to weak object pointer wrapper.

18:36.950 --> 18:39.710
Now we'll check if these things are valid as well.

18:39.710 --> 18:50.810
We'll say if data dot target dot ability actor info dot is valid and we'll also check data dot target

18:51.170 --> 18:54.950
dot ability actor info Avatar actor.

18:54.950 --> 18:56.810
We'll check if that's valid as well.

18:57.650 --> 19:03.110
Again, we're checking using those pointer wrapper utilities.

19:03.110 --> 19:09.980
If all that stuff's valid, then we'll set a target actor and we can also get the target controller.

19:09.980 --> 19:20.210
We can say a controller target controller equals data, dot target, dot ability, actor info player

19:20.210 --> 19:21.050
controller.

19:21.110 --> 19:23.360
And that's going to be dot get.

19:23.390 --> 19:34.490
Of course we can get the character, a character target character, and we could simply cast to a character

19:35.330 --> 19:36.440
what can we cast?

19:36.470 --> 19:38.870
We can simply cast that target.

19:38.870 --> 19:40.430
Actor Why not?

19:43.070 --> 19:47.720
Now I know that we could access the ability system component directly.

19:47.750 --> 19:50.510
We can also get it through the interface.

19:50.540 --> 19:52.370
We could also get it with you.

19:52.370 --> 19:59.660
Ability system blueprint library, get ability system component.

19:59.660 --> 20:02.690
Right passing in target actor.

20:03.050 --> 20:05.210
And of course I made a typo here.

20:05.210 --> 20:16.040
Let's fix that and we can say you ability system component target ask and we can get it that way.

20:16.070 --> 20:17.630
There are many options here.

20:17.660 --> 20:25.730
The point is that here in post gameplay effect execute from data, we have the ability to get all sorts

20:25.730 --> 20:30.200
of information and we're going to be using this all throughout the course.

20:30.200 --> 20:36.980
So rather than cluttering up post gameplay effect, execute with all of these lines of code, it'd be

20:36.980 --> 20:44.250
handy to refactor a handy little function that can collect all of these into perhaps a struct.

20:44.280 --> 20:44.700
Right.

20:44.700 --> 20:51.210
Maybe we can have some kind of struct called effect properties or something like that and it can store

20:51.240 --> 20:54.120
the source and target ability system components.

20:54.120 --> 20:56.730
It can store the source Avatar.

20:56.730 --> 20:58.950
Actor The Target Avatar actor.

20:58.950 --> 21:00.720
By the way, this should be called Target.

21:00.720 --> 21:01.410
Avatar.

21:01.410 --> 21:02.160
Actor Right.

21:02.160 --> 21:06.330
There's the difference between Avatar and owner actor.

21:06.330 --> 21:09.120
We should specify so we don't confuse ourselves.

21:09.120 --> 21:13.740
So Target, Avatar, actor, we have controller character.

21:13.770 --> 21:20.610
All of these could be stored in some kind of struct and then in post gameplay effect execute we can

21:20.610 --> 21:27.690
fill in that struct with some kind of function for setting the properties based on the effect and that

21:27.690 --> 21:31.230
way we can just retrieve them anytime we want.

21:31.230 --> 21:34.770
And that's kind of the approach that I'd like to take.

21:34.770 --> 21:37.380
So I'd like us to do that here.

21:37.680 --> 21:40.470
So here's your quest for this video.

21:40.500 --> 21:44.190
I'd like you to create the effect properties struct.

21:44.220 --> 21:52.470
You can define this right there in the attribute set header file, call it F effect properties and just

21:52.470 --> 21:59.040
give it some variables, the ability system component for the source and target and the avatar actor,

21:59.070 --> 22:05.130
the controller, the character and go ahead and store the effect context handle in it as well.

22:05.220 --> 22:12.840
And that way we'll create a function together that will fill this in with all the data that we've harvested.

22:12.840 --> 22:16.410
So pause the video and create this struct now.

22:19.240 --> 22:23.680
All right, let's create our effect properties struct.

22:23.920 --> 22:26.970
I'm going to create this in or attribute set.

22:26.980 --> 22:31.570
I'm going to go ahead and just close all other tabs for now.

22:31.660 --> 22:35.980
And right here at the top we'll define our struct.

22:35.990 --> 22:38.980
I'll put it below the attribute accessors.

22:38.980 --> 22:40.510
Macro definition.

22:40.780 --> 22:48.580
I'm going to say struct and this will be called F effect properties and I'd like it to be a use struct.

22:48.580 --> 22:51.700
So I'm going to add the use struct macro for now.

22:51.700 --> 22:57.670
I'm not going to make it blueprint type or anything like that, but I do need the generated body macro

22:58.150 --> 23:06.160
and I'll give it a default constructor that takes no arguments and does nothing.

23:06.640 --> 23:10.540
And first I'm going to have the effect context handle.

23:10.540 --> 23:16.750
So I'm going to make a game play effect context handle called effect context handle.

23:17.200 --> 23:20.360
And after that we'll have a bunch of pointers, right?

23:20.360 --> 23:23.510
And I'm going to make sure to initialize them all to null.

23:23.630 --> 23:30.590
So I'm going to have a new ability system component pointer and I'm going to call it source ask and

23:30.590 --> 23:36.890
initialize it to null pointer and give it a new property and it's just going to be an empty property

23:37.610 --> 23:41.900
and we'll deal with all the source variables first.

23:41.900 --> 23:54.020
So we'll have the source Avatar actor So a actor source Avatar actor equals null pointer Give it a new

23:54.020 --> 23:54.830
property.

23:55.580 --> 24:00.320
We'll have the A controller that's going to be the source controller.

24:02.060 --> 24:05.600
We'll set that equal to null with a new property.

24:07.370 --> 24:12.740
And an a character called source character.

24:13.220 --> 24:16.640
Make that a null pointer as well with you property.

24:18.140 --> 24:20.780
And then we just need these for the target.

24:20.780 --> 24:28.760
So I'm going to copy all of them and paste them just beneath and highlight these four and control.

24:28.760 --> 24:31.430
H And I'm going to change source.

24:31.430 --> 24:36.830
I'm going to search for source and replace it with target and click replace all.

24:36.830 --> 24:39.830
And now we have the target versions.

24:39.830 --> 24:41.960
So quick little shortcut there.

24:42.650 --> 24:43.580
Okay, great.

24:43.580 --> 24:45.410
So that was the challenge.

24:45.410 --> 24:53.750
Now I'd like to make a function for filling in this data, so I'd like it to simply take in an effect

24:53.750 --> 25:04.070
property struct as a non-const reference and we can make this function right here in the attribute set.

25:04.100 --> 25:10.220
I'm going to put it way down in a private section because this is just internal to the attribute set

25:10.220 --> 25:12.590
and I'll make it a void function.

25:12.590 --> 25:19.380
It's going to be called set effect properties and it's going to take a couple of things.

25:19.380 --> 25:27.930
If I alt O or ctrl k o into the CPP file, I'll see that post gameplay effect.

25:27.930 --> 25:33.060
Execute takes a const reference to data and that's where we're getting all this stuff.

25:33.060 --> 25:38.220
So we're going to need to pass that in to our function set effect property.

25:38.220 --> 25:40.080
So I'm going to paste that right there.

25:40.680 --> 25:45.510
And of course we're going to want to pass in an effect properties.

25:45.540 --> 25:51.090
Now this will be non const because we're going to change this struct, we're going to fill it in with

25:51.090 --> 25:51.960
all the data.

25:51.960 --> 25:57.810
So this will be an F effect properties reference called we'll just call it props.

25:58.140 --> 26:04.080
Very important that it's a non const reference and we'll generate the definition and I'm going to cut

26:04.080 --> 26:12.120
this and paste it way up here just above post gameplay effect, execute that way it's right next to

26:12.120 --> 26:13.530
where it's going to be used.

26:13.530 --> 26:16.890
And I'd like to just use all the code we've already done.

26:17.310 --> 26:23.880
I'm going to highlight all of it and cut it out of post gameplay effect, execute and paste it in to

26:23.880 --> 26:25.170
set effect properties.

26:25.170 --> 26:30.750
And now we just need to use all of this work we've done to fill in our props struct.

26:30.750 --> 26:34.320
So let's take a look at those variables in our struct.

26:34.560 --> 26:37.950
Let's first store the effect context handle.

26:37.950 --> 26:42.210
Let's get that stored in our props struct.

26:42.240 --> 26:45.390
We have it right here in a local variable.

26:45.390 --> 26:52.650
Now all we should really have to do is set props dot effect context handle.

26:52.650 --> 26:55.290
So that takes care of the first thing.

26:55.530 --> 27:00.870
Now next we have the source ability system component source as well.

27:00.870 --> 27:06.030
We can set that on props so we can just replace this with props.

27:06.030 --> 27:07.770
Dot source ASC.

27:08.160 --> 27:15.120
Of course we have effect context handle here, but that's now stored on props, so we're going to want

27:15.120 --> 27:18.120
props, dot effect, context handle there.

27:18.330 --> 27:21.360
So we've got our source ability system component.

27:21.540 --> 27:28.560
Now next we're checking if source ASC is valid, but now it's in our struct props source ASC.

27:28.560 --> 27:35.760
So we're going to replace source ASC with props dot source, ASC here, here and here.

27:36.150 --> 27:40.830
Next we're getting the source Avatar actor from Source ASC.

27:40.860 --> 27:48.180
We're going to replace that with props, dot source, ASC and source Avatar Actor is also on props,

27:48.180 --> 27:55.620
so we're going to replace our local variable with props, dot source, Avatar Actor.

27:55.620 --> 27:58.140
We're going to set that on our struct.

27:58.170 --> 28:00.090
We're going to do the same thing for our controller.

28:00.090 --> 28:06.690
We're going to replace this with props, dot source controller and source ASC is going to be props dot

28:06.690 --> 28:14.820
source ASC and we're going to check props dot source controller here and props dot source, Avatar actor.

28:14.820 --> 28:19.950
And then we're going to cast to upon our source Avatar actor on props.

28:19.950 --> 28:23.910
So we're just pasting props dot all over the place.

28:23.910 --> 28:25.680
Same with the source controller here.

28:25.680 --> 28:27.000
We're going to set that there.

28:27.000 --> 28:32.880
And then here we're checking that pointer and then we're replacing source controller with the one on

28:32.880 --> 28:34.440
the props struct.

28:34.770 --> 28:35.340
Okay.

28:35.340 --> 28:40.680
So next we're going to get our variables set for the target.

28:40.680 --> 28:47.610
And first we have Target Avatar actor and that's of course a variable on props.

28:47.610 --> 28:56.430
So we're going to set props, dot target, Avatar actor here and also target controller is going to

28:56.430 --> 29:03.720
be set on props and Target character is going to be set on props and it's casting Target Avatar actor.

29:03.720 --> 29:07.860
We're going to use the one on props and then we have the target.

29:07.890 --> 29:15.960
ASC We're going to set that on props using Target, Avatar, Actor passing that in to get ability system

29:15.960 --> 29:16.500
component.

29:16.880 --> 29:20.450
And now we've set those variables for the target.

29:20.450 --> 29:23.960
So now we have this nice function set effect properties.

29:23.960 --> 29:30.290
And as always, writer is reminding me that this could be a const function and why not?

29:30.290 --> 29:36.050
I'm going to make it a const function because I can real quick just add const to it.

29:36.050 --> 29:42.650
Like just add water, just add const and now we can call set effect properties here in post gameplay

29:42.650 --> 29:43.970
effect execute.

29:43.970 --> 29:48.710
And we have all of our data just packaged up into our props struct.

29:48.710 --> 29:56.360
So what I'd like to do is make an f effect properties struct called props and then pass it into set

29:56.390 --> 30:03.350
effect properties, which takes two things the data which we can pass in and the props which we can

30:03.350 --> 30:04.100
pass in.

30:04.460 --> 30:07.850
And now from within post gameplay effect execute.

30:07.880 --> 30:11.240
We have easy access to all of these properties.

30:11.240 --> 30:16.670
We can get props, dot source, character, source, controller, target, all of these things.

30:16.670 --> 30:22.910
And we just have to keep in mind that depending on what caused the effect, it might not be a character

30:22.910 --> 30:29.060
that caused it, it might not have a controller, it might have some of these properties and not all.

30:29.060 --> 30:32.750
So it's important to check if those are valid before using them.

30:32.750 --> 30:34.190
So we'll be careful.

30:34.310 --> 30:40.820
But now that we have props, we have access to all sorts of things in post gameplay effect, execute

30:40.820 --> 30:47.330
and we'll be using them all throughout this course as we implement more complex mechanics and combat.

30:47.630 --> 30:49.400
So excellent job.

30:49.400 --> 30:52.280
We now have our post gameplay effect execute.

30:52.310 --> 30:56.780
It's going to be very useful for us and I'll see you in the next video.
