WEBVTT

00:06.930 --> 00:07.950
Welcome back.

00:07.950 --> 00:12.990
So we've just learned how we can initialize attributes with a data table.

00:13.110 --> 00:16.140
And I mentioned that that's not my favorite way.

00:16.170 --> 00:19.800
My preferred way is to use a gameplay effect.

00:20.070 --> 00:28.140
Now I'd like to add the ability to initialize our attribute values with a function that will apply this

00:28.140 --> 00:29.250
gameplay effect.

00:29.250 --> 00:32.910
And before we go and start doing that, I'm going to open the editor.

00:34.050 --> 00:42.390
And just remove that data table from our ability system component on the player state.

00:42.420 --> 00:42.750
Why?

00:42.780 --> 00:44.710
Because we're not going to use it anymore.

00:44.730 --> 00:47.010
It was just for educational purposes.

00:47.010 --> 00:49.590
But now that we're educated, we're not going to use it.

00:49.590 --> 00:52.690
So I'm going to select the ability system component on the player state.

00:52.710 --> 00:54.930
I'm going to remove this.

00:55.080 --> 00:58.940
I'm going to delete that index from default starting data.

00:58.950 --> 01:00.900
So we're now no longer using it.

01:00.900 --> 01:09.840
And if I press play and show debug, all of my attributes have values of zero and in fact we don't see

01:09.840 --> 01:11.160
them twice anymore.

01:11.870 --> 01:19.010
Now I'm going to close the editor, and now we're going to work on applying a gameplay effect to initialize

01:19.010 --> 01:21.980
these primary attributes instead.

01:22.160 --> 01:26.240
So let's create the ability to do that.

01:26.240 --> 01:32.870
And I'm first going to add a function for doing this on the character.

01:33.260 --> 01:41.330
Our base character class can have some sort of default primary attributes, gameplay effect.

01:41.450 --> 01:48.590
So I'm going to go into my public folder, into character and open aura character base, and I'm going

01:48.590 --> 01:51.470
to add a variable to the protected section.

01:51.500 --> 01:53.810
This is going to be a subclass of.

01:55.400 --> 02:04.730
It's going to be of you gameplay effect and I'm going to call this default primary attributes.

02:05.030 --> 02:11.600
Now I want to be able to set this from the blueprint so it gets a new property and we'll make this blueprint

02:11.600 --> 02:19.460
read only edit anywhere and I'll put it in the category of attributes.

02:20.360 --> 02:22.940
So we have a default primary attributes.

02:22.940 --> 02:29.480
I'm going to want a way to apply these attributes, so I'm just going to make a function that can do

02:29.480 --> 02:32.480
it and I'll put it right here in the protected section.

02:32.630 --> 02:38.570
It'll be void, and I'm going to call this initialize primary attributes.

02:39.340 --> 02:44.680
So let's generate the definition for this and how are we going to do this?

02:44.710 --> 02:50.680
Well, first, if we're going to call something like apply gameplay effect spec to self or to target

02:50.680 --> 02:57.160
or something like that, we're going to need a gameplay effect spec to apply which we can create because

02:57.160 --> 03:01.060
we have a class for our default primary attributes.

03:01.060 --> 03:09.100
So we can work backwards by first trying to call the function to apply the effect so we can always get

03:09.100 --> 03:16.510
our ability system component, assuming that it's valid at the time we call this function and from this

03:16.510 --> 03:19.300
ability system component, we can call apply.

03:19.330 --> 03:26.200
And I'm not getting the auto complete because ability system component is an incomplete type here,

03:26.200 --> 03:28.900
which means I'll have to include its header file.

03:29.740 --> 03:35.620
I like autocomplete, so I'm going to go ahead and include that first ability system component.

03:35.800 --> 03:40.600
H And now I should be able to get autocomplete.

03:40.690 --> 03:48.190
Now we know about apply gameplay effect spec to self this function, but what about to target?

03:48.190 --> 03:51.250
Let's get some practice using that one this time.

03:51.490 --> 04:00.340
So this one, much like the two self version requires an effect spec an ability system component that

04:00.340 --> 04:03.280
is the target and an optional prediction key.

04:03.280 --> 04:05.680
And we're not talking about prediction keys yet.

04:05.680 --> 04:08.530
For now we just need that effect spec.

04:08.560 --> 04:09.760
So how did we do it?

04:09.760 --> 04:15.850
See if you can remember, try to remember without me telling you and without looking over at other classes

04:15.850 --> 04:17.260
because we've done this before.

04:17.260 --> 04:20.200
How do you make an effect spec now?

04:20.200 --> 04:21.730
It's okay if you don't remember.

04:21.730 --> 04:28.120
It's good enough to know that there's a way to make it and you can always go and look at old code that

04:28.120 --> 04:33.350
you've done before, but, but it's good to give it a try to try remembering.

04:33.440 --> 04:36.590
So the way to do it is through the ability system component.

04:36.590 --> 04:42.680
So I'm going to say get ability system component and the function is make outgoing spec.

04:42.800 --> 04:49.520
And of course this requires a gameplay effect class and we created one here on the base class.

04:49.520 --> 04:52.160
It's called default primary attributes.

04:52.160 --> 04:54.020
So that's what we pass in.

04:54.320 --> 05:00.530
It also needs a level and we're just going to use level one for this effect and then it needs a context

05:00.530 --> 05:01.220
handle.

05:01.400 --> 05:03.710
So we need to make that context handle.

05:03.710 --> 05:09.920
I like to work backwards like this and just comment these things out until I'm ready to fill them in.

05:10.160 --> 05:12.350
So I need a context handle, right?

05:12.350 --> 05:20.060
And so for that I get the ability system component and I call, see if you can remember make effect

05:20.060 --> 05:21.110
context.

05:21.560 --> 05:27.980
And this if we hover over we see it returns an gameplay effect context handle.

05:28.190 --> 05:34.450
So let's make that F gameplay effect context handle.

05:34.750 --> 05:43.210
I'll call this context handle and I'm going to uncomment the next line and pass in that context handle.

05:44.380 --> 05:51.070
Now this one make outgoing spec returns an F gameplay effect spec handle.

05:51.220 --> 05:58.930
Let's make that f gameplay effect spec handle and we'll call this spec handle.

05:59.290 --> 06:07.270
And then finally we get to pass this in to apply gameplay effect spec to target, we pass in the spec

06:07.270 --> 06:11.290
handle and we pass in the ability system component.

06:11.320 --> 06:14.440
We'll just use get ability system component.

06:14.800 --> 06:21.250
Now remember, we can't just pass in spec handle can we, because this requires the actual gameplay

06:21.250 --> 06:22.540
effect spec.

06:22.540 --> 06:27.010
So remember the words syntax nightmare should come to mind.

06:27.040 --> 06:31.160
We have some things buried deep down inside the spec handle.

06:31.160 --> 06:31.760
Right?

06:31.790 --> 06:40.460
We know that the spec handle has the actual spec and see if you can remember just from memory what is

06:40.460 --> 06:45.530
that internal variable called that stores the actual spec?

06:45.560 --> 06:50.300
That would be data, but data is also a wrapper of its own.

06:50.300 --> 06:55.220
It's a shared pointer, which means to get the actual pointer we have to use.

06:55.910 --> 06:56.540
That's right.

06:56.540 --> 06:57.800
We have to use get.

06:57.800 --> 07:04.070
And if we get the pointer, well we're now passing a pointer in, but it doesn't take a pointer.

07:04.070 --> 07:11.150
This function takes a const reference so we have to dereference the pointer and then this will work.

07:11.620 --> 07:13.270
So kind of a lot to do.

07:13.270 --> 07:20.770
And of course these can both be made const, so to be const correct and make this nice and squiggle

07:20.770 --> 07:26.860
free, we can put the const on both of those and there we go.

07:27.040 --> 07:33.400
This is the version that applies a gameplay effect spec to a target ability system component and we

07:33.400 --> 07:37.510
have to specify the ability system component when we use this one.

07:37.960 --> 07:41.950
And if we hover over this, we see that this function can be const as well.

07:41.950 --> 07:49.000
So we don't need to change the values of any variables, we're just calling functions on them.

07:49.000 --> 07:55.690
So I'm going to make this a const function, which means I have to come back to the header file and

07:55.690 --> 07:56.920
make it const there.

07:57.070 --> 08:06.370
So now we have initialized primary attributes and as long as we have a valid gameplay effect class default

08:06.370 --> 08:10.150
primary attributes, then calling this function should be fine.

08:10.150 --> 08:16.940
We shouldn't have any issues as as long as that is the case and our ability system component is valid

08:16.940 --> 08:24.890
as well and we can check those things, we can say check and we can use is valid get ability system

08:24.890 --> 08:32.810
component, and we can also check default primary attributes just to make sure that that's not a null

08:32.810 --> 08:34.550
pointer that's unset.

08:34.550 --> 08:38.780
So now that we have this function, the question is where do we call it?

08:39.220 --> 08:46.150
Now we can call it in different circumstances depending on if we're the aura, character or the enemy.

08:46.480 --> 08:50.350
In this video, I'm just concerned with setting our attributes for Aura.

08:50.350 --> 08:54.940
So I'd like to open up our Aura character CPP file.

08:54.940 --> 08:57.820
So I'm going to go to character and open Aura character.

08:58.370 --> 09:00.290
And an aura character.

09:00.290 --> 09:03.070
I'd like to apply this effect.

09:03.080 --> 09:08.180
In other words, I'd like to call the function we just created in the base character class.

09:08.210 --> 09:11.540
We called that initialize primary attributes.

09:11.540 --> 09:19.400
But unlike init ability actor info which we're calling on both server and client, applying this gameplay

09:19.400 --> 09:21.970
effect only really needs to be done on the server.

09:21.980 --> 09:22.700
Why?

09:22.730 --> 09:26.780
Because all of those attributes are marked to be replicated.

09:26.780 --> 09:31.970
So if we change them on the server then they'll change on the client as well.

09:32.000 --> 09:36.950
However, if we wanted to do this on both client and server, that'd be okay too.

09:36.980 --> 09:42.920
We'd be setting these attributes to the same values on client and server, and that way the client won't

09:42.920 --> 09:45.770
have to wait for the server to replicate it back down.

09:45.770 --> 09:47.840
Either way is fine.

09:47.990 --> 09:54.410
Now if we do it in init ability actor info, we know that our ability system component should be valid

09:54.410 --> 09:58.080
by this point and it's clear by looking in this function.

09:58.080 --> 10:04.770
So we can just do it here after ability system component is set since we know that it should be safe

10:04.770 --> 10:05.490
to call it there.

10:05.490 --> 10:06.810
So I'm going to call it here.

10:06.840 --> 10:08.640
And what did we call it?

10:08.640 --> 10:10.800
Initialize primary attributes.

10:10.800 --> 10:15.300
So we'll call it right here in init ability actor info.

10:15.300 --> 10:22.470
So now all that's left is to make sure that we have that effect and that we configure some default values.

10:22.470 --> 10:27.270
So I'm going to go ahead and run and debug mode so that we can create that effect.

10:27.270 --> 10:32.130
That sets our initial primary attribute values.

10:32.460 --> 10:34.560
Now get some compilation errors.

10:34.560 --> 10:41.040
So the first one says an aura character based gameplay effect is an undeclared identifier.

10:41.040 --> 10:43.770
We didn't forward declare gameplay effect.

10:43.770 --> 10:46.200
I'm going to go ahead and do that up here at the top.

10:49.140 --> 10:51.000
Then I'll go ahead and compile again.

10:52.440 --> 10:55.080
And that solves all of our problems.

10:55.110 --> 11:00.690
So when I have multiple compiler errors, if I know how to fix one, usually I'll fix it and compile

11:00.690 --> 11:01.470
again.

11:01.490 --> 11:07.080
And then if there are more compiler errors, I'll find another one that I can fix.

11:07.080 --> 11:12.010
Fix it, compile again, and usually that list goes down pretty quickly.

11:12.030 --> 11:15.980
It's usually only a couple of errors that can propagate many more.

11:15.990 --> 11:17.790
So that's kind of my workflow.

11:18.120 --> 11:20.400
Okay, let's run in debug mode.

11:21.400 --> 11:29.140
And here in the editor, what we need is a gameplay effect that we can use to initialize our primary

11:29.140 --> 11:30.670
attribute values.

11:30.760 --> 11:37.390
And this is going to be specific to really the aura character, right?

11:37.390 --> 11:43.930
And eventually we're going to have different types of characters that may start off with different values

11:43.930 --> 11:48.760
and we'll be implementing a clever solution.

11:48.760 --> 11:56.310
But for now, just to get it working, we're going to just create one for Aura and apply it for aura.

11:56.320 --> 12:02.530
So I'm going to go into ability system and we're going to make a new folder here in ability system called

12:02.530 --> 12:10.780
Gameplay Effects and here in gameplay effects, we're going to make a new folder called Primary Attributes.

12:11.170 --> 12:14.980
And in primary attributes we're going to make a new gameplay effect.

12:15.850 --> 12:24.910
So let's make this gameplay effect and we're going to call it G Aura primary attributes.

12:25.560 --> 12:29.880
We're going to open it up and this will be an instant gameplay effect.

12:29.910 --> 12:32.220
We're going to apply it once.

12:32.370 --> 12:39.360
We're already calling the function to apply it and we're going to have four modifiers, one for each

12:39.360 --> 12:41.100
of the primary attributes.

12:41.100 --> 12:48.720
So I'm going to click plus one, two, three, four times and expand the first one and pick from among

12:48.750 --> 12:49.560
our attributes.

12:49.560 --> 12:54.780
I'm going to choose attribute set dot strength modifier.

12:54.810 --> 12:56.700
OP though, is not going to be Add.

12:56.700 --> 12:58.650
It's going to be override.

12:58.890 --> 13:01.830
Yes, they will have values of zero.

13:01.830 --> 13:10.560
So adding this initial value to it will give us the same result, but we're going to override just because

13:10.560 --> 13:18.030
this is the value that it should start off at for the modifier magnitude, we're going to set the scalable

13:18.030 --> 13:21.810
float magnitude and for auras initial strength.

13:21.840 --> 13:23.340
Let's give her ten.

13:23.520 --> 13:26.170
And there's our strength.

13:26.170 --> 13:28.090
Let's go to the next one.

13:28.480 --> 13:32.470
For the next one, we're going to choose intelligence.

13:32.470 --> 13:36.880
We're going to set, modifier op to override modifier magnitude.

13:36.880 --> 13:39.220
We'll give her, let's say, 17.

13:39.490 --> 13:41.410
And there's our intelligence.

13:41.440 --> 13:45.340
Next, we'll choose our resilience modifier.

13:45.340 --> 13:48.340
OP will be override modifier magnitude.

13:48.580 --> 13:53.050
These might not be the same values I chose earlier, but I'm going to choose 12.

13:53.050 --> 13:56.290
And then for the next one, finally we have vigor.

13:56.320 --> 14:00.610
It's going to be override and the magnitude can be nine.

14:00.610 --> 14:05.130
So we should see ten, 17, 12 and nine.

14:05.140 --> 14:06.700
I'm going to compile that.

14:06.700 --> 14:08.890
And now we have our gameplay effect.

14:08.920 --> 14:13.450
We just need to set that and that's going to be on the Aura character itself.

14:13.450 --> 14:18.190
So into character, Aura, BP or a character blueprint.

14:18.190 --> 14:26.430
And I'm going to search for primary attribute and here's my default primary attributes.

14:26.430 --> 14:33.570
I'm going to choose Aura, primary attributes, compile and save, and I'm going to save all.

14:34.930 --> 14:40.600
So now all we need to do is press play and show debug.

14:40.690 --> 14:41.780
And there we have it.

14:41.800 --> 14:42.430
We have strength.

14:42.430 --> 14:44.590
Ten Intelligence 17.

14:44.590 --> 14:47.430
Resilience 12 and Vigor nine.

14:47.440 --> 14:49.480
So pretty simple.

14:49.480 --> 14:53.370
We kind of already knew how to apply gameplay effects, didn't we?

14:53.380 --> 14:58.030
But this is my preferred way and this is the most common way I've seen it done.

14:58.030 --> 15:04.750
I think it's a good way and it works as long as we apply the gameplay effect at the beginning of the

15:04.750 --> 15:12.850
game, then we get our default attributes and later when we decide that we need to load in some attributes

15:12.850 --> 15:17.110
from saved data, it's pretty simple to do that as well.

15:17.140 --> 15:24.580
Once you know how to apply an effect and specify the magnitude at runtime and we'll learn how to do

15:24.580 --> 15:25.300
that too.

15:25.510 --> 15:30.130
So now we know two different ways to initialize our attributes.

15:30.130 --> 15:31.540
Actually three ways.

15:31.540 --> 15:35.060
One is through the attribute accessors in code.

15:35.060 --> 15:39.110
That's currently how we're doing our health, Max Health Mana and Max Mana.

15:39.110 --> 15:40.730
We'll fix that later.

15:40.760 --> 15:47.060
We're going to handle these in time, but now we're using a gameplay effect for our primary attributes,

15:47.060 --> 15:48.080
which is great.

15:48.080 --> 15:51.410
So excellent job and I'll see you in the next video.
