WEBVTT

00:06.780 --> 00:07.800
Welcome back.

00:07.800 --> 00:15.360
Now that we have incoming XP, we're not setting it yet, but we're going to set up a way to do so by

00:15.360 --> 00:18.960
creating a gameplay ability that can listen for gameplay events.

00:19.170 --> 00:21.540
Now we know that we can send gameplay events.

00:21.540 --> 00:26.230
We're doing so from our montages and that gameplay abilities can listen to them.

00:26.250 --> 00:33.060
Well, let's go ahead and run the Unreal Engine editor and create an ability that can do this.

00:34.010 --> 00:35.600
Okay, so I'm back in the editor.

00:35.600 --> 00:37.310
I don't need to open anything.

00:37.310 --> 00:39.560
I just want to create a new ability.

00:39.560 --> 00:44.500
So I'm going to go to blueprints, ability system, aura abilities.

00:44.510 --> 00:48.470
Now this is going to be a special kind of ability.

00:48.470 --> 00:51.110
It's going to be a passive gameplay ability.

00:51.110 --> 00:56.870
I'd like it to always be running, but there are some things that it doesn't need to do.

00:56.900 --> 01:01.940
It does not need to replicate and it really only needs to run on the server.

01:01.940 --> 01:10.520
So as soon as we give this ability, we can activate it, We can use, give ability and activate once

01:10.520 --> 01:12.470
and then it can always be running.

01:12.560 --> 01:17.440
So we'll have some optimizations in place such as not replicating.

01:17.450 --> 01:20.780
Now that's what my passive abilities are going to do.

01:20.780 --> 01:23.120
They're going to run all the time.

01:23.120 --> 01:26.450
So I'm going to make a new folder called Passive.

01:26.630 --> 01:32.240
In fact, this is going to be a startup ability, so we'll call it passive startup.

01:32.480 --> 01:36.960
And here in passive startup we'll make our new gameplay ability.

01:36.960 --> 01:45.810
So we're going to search for gameplay ability and choose gameplay ability and make this new class and

01:45.810 --> 01:50.490
it's going to be called gar underscore listen for events.

01:50.490 --> 01:53.580
That's what this gameplay abilities job is.

01:53.580 --> 02:01.080
Let's open it up and the first thing I'm going to do is optimize this by changing some of the settings

02:01.080 --> 02:04.320
so that it doesn't do things that we don't need it to do.

02:04.350 --> 02:12.270
We're going to set its instancing policy to instance per actor, so we only have one and it sticks around.

02:12.420 --> 02:16.620
Now its execution policy is not going to be predicted.

02:16.620 --> 02:18.690
It's not even going to run locally.

02:18.690 --> 02:20.970
It's going to run on the server only.

02:20.970 --> 02:26.460
So not only server initiated, but server only means it won't replicate at all.

02:26.460 --> 02:28.590
It'll only be running on the server.

02:28.620 --> 02:29.970
That's all we care about.

02:29.970 --> 02:31.170
So that's what we want.

02:31.200 --> 02:33.840
We can leave replication policy at do not replicate.

02:33.870 --> 02:34.860
We've already mentioned that.

02:34.860 --> 02:36.150
We don't even touch that.

02:36.180 --> 02:38.310
Now we have a gameplay ability.

02:38.310 --> 02:41.700
We want a way to listen to gameplay events.

02:41.700 --> 02:47.520
So as soon as we activate the ability we're going to use wait gameplay event.

02:50.110 --> 02:57.290
And we're going to listen for a gameplay event and we can listen for a non exact match.

02:57.310 --> 03:06.070
For example, if I uncheck only exact match, then I could listen to a general category of gameplay

03:06.100 --> 03:06.930
tags.

03:06.940 --> 03:14.490
For example, let's say I want to listen for when any of my attributes are sent in a gameplay event

03:14.500 --> 03:21.610
so we can send a gameplay event with attributes dot anything and we can listen for events for that.

03:21.610 --> 03:22.500
That's what I'd like.

03:22.510 --> 03:29.740
I'd like to listen for attributes and then we can have this nice generic wait for event that will respond

03:29.740 --> 03:35.350
when we send any gameplay event that has an attribute tag that includes incoming XP.

03:35.680 --> 03:36.070
Now.

03:36.070 --> 03:39.700
Yes, we still need to create a tag for incoming XP.

03:40.090 --> 03:43.180
That's going to be one of our next things to do.

03:43.180 --> 03:50.030
But for now we know that we're going to listen for any attribute tag events.

03:50.030 --> 03:55.760
Now we don't want to only trigger once either, so leave that unchecked because this gameplay ability

03:55.760 --> 04:02.300
will be running throughout the course of the game as long as the game is running and continually firing

04:02.300 --> 04:02.570
off.

04:02.600 --> 04:08.870
Wait gameplay event we've seen in the past how this can fire off multiple times and get us into trouble.

04:09.110 --> 04:12.230
If you only want it to fire once, then you check that checkbox.

04:12.250 --> 04:13.760
In this case we don't.

04:13.790 --> 04:16.770
We want this to fire off multiple times.

04:16.790 --> 04:24.020
Now, as we've seen before, gameplay events can pass along data in a payload.

04:24.020 --> 04:30.140
If we take this payload and we break this gameplay event data struct, we can see all the things we

04:30.140 --> 04:32.210
can send in a gameplay event.

04:32.240 --> 04:41.450
The ones I'm interested in are tags and magnitude a float value because if we have a tag that's being

04:41.450 --> 04:49.130
sent and it's an attribute tag, then we can know which attribute we're supposed to change and then

04:49.130 --> 04:56.390
we can create some kind of gameplay effect and set a set by color magnitude on it and apply it.

04:56.660 --> 05:03.650
So we need some kind of effect and we can make one and set it as a variable on our gameplay ability.

05:03.650 --> 05:05.180
Let's go ahead and make one.

05:05.180 --> 05:11.000
I'm going to right click New Blueprint class, search for gameplay effect.

05:11.360 --> 05:15.920
Choose that and we'll call this G underscore.

05:16.160 --> 05:22.790
And this is going to be in effect specifically for this gameplay ability that's listening for events.

05:22.790 --> 05:27.080
So we can call it something like event based effect.

05:27.440 --> 05:36.140
So we have our event based effect and the first thing we'll do is we'll make sure that it's set to instant

05:36.140 --> 05:41.840
duration policy and then we can add a modifier that can modify incoming XP.

05:42.290 --> 05:47.270
And then if we want this effect to be able to modify anything else, we can add other modifiers, but

05:47.270 --> 05:50.360
we're just going to add incoming XP to this.

05:50.390 --> 05:58.120
There it is at the bottom and this will add to incoming XP and the modifier magnitude is going to be

05:58.120 --> 06:01.240
set by caller and the set by caller magnitude.

06:01.240 --> 06:04.450
Will that needs to be a specific tag, right?

06:04.450 --> 06:12.790
Well, we can use attribute tags now we don't have an attribute tag for incoming XP, so we should have

06:12.790 --> 06:13.410
one.

06:13.420 --> 06:19.300
In fact, we should probably have attributes dot meta because it's not a primary, it's not a resistance

06:19.300 --> 06:23.230
or a secondary or a vital attribute for that matter.

06:23.230 --> 06:25.000
It's kind of its own thing.

06:25.000 --> 06:31.240
Meta attributes are their own thing, So I'm going to close the editor and create a native gameplay

06:31.240 --> 06:33.460
tag, making sure to save everything.

06:33.460 --> 06:40.180
We're going to go into our gameplay tags and make a meta gameplay tag for our incoming XP.

06:40.600 --> 06:47.020
So we'll go up to our attributes where our other attributes exist and we'll make a new attribute tag

06:48.130 --> 06:55.030
and we'll call it attributes Underscore meta underscore incoming XP.

06:55.960 --> 07:00.200
And we'll go ahead and create that in the CPP file as well.

07:00.220 --> 07:04.570
So let's go up to our other attributes.

07:04.750 --> 07:10.120
We'll copy a multi-line comment, paste one here.

07:10.390 --> 07:18.040
We'll call it meta attributes and we'll just create the meta attribute for incoming XP.

07:18.430 --> 07:23.770
So we have to change this to attributes underscore meta incoming XP.

07:24.340 --> 07:34.750
We're going to say the name is attributes dot meta dot incoming XP and the F string comment is going

07:34.750 --> 07:40.360
to say incoming XP meta attribute.

07:40.630 --> 07:43.210
So that's our first meta attribute gameplay tag.

07:43.210 --> 07:49.330
We haven't really had a need for the damage meta attribute, incoming damage, but now we see that we

07:49.330 --> 07:51.280
have a need for incoming XP.

07:51.970 --> 07:52.600
All right.

07:52.600 --> 07:58.250
So now that we have that attribute, we can go ahead and run back in the editor again.

07:59.030 --> 08:02.600
And we can open up our assets that we had open.

08:02.600 --> 08:09.320
And in our event based effect, we need to go back down to our modifier because it's set by caller magnitude

08:09.320 --> 08:11.480
needs to listen for a specific tag.

08:11.480 --> 08:16.430
It's going to listen for attributes meta incoming exp.

08:16.790 --> 08:26.930
So if we ever send an event with this specific tag as its event tag, then in GA listen for event we

08:26.930 --> 08:34.100
can receive that event and remember we can listen to events if they have attributes as their first tag

08:34.100 --> 08:35.000
in the hierarchy.

08:35.000 --> 08:41.090
So sending attributes dot meta dot incoming exp will indeed trigger this event.

08:41.090 --> 08:42.770
I promise you it'll work.

08:42.770 --> 08:43.760
We'll see.

08:43.850 --> 08:49.010
Now the event tag is going to be the tag that we were listening for.

08:49.010 --> 08:56.210
Except the cool thing is when we send an event with this full tag attributes dot meta dot incoming exp.

08:56.450 --> 08:59.670
Then this event tag will have that full tag in it.

08:59.700 --> 09:05.580
It's not just going to be attributes and that's the cool thing because now we can apply this gameplay

09:05.580 --> 09:08.400
effect and set it set by caller magnitude.

09:08.400 --> 09:11.130
So how are we going to apply this gameplay effect?

09:11.160 --> 09:18.360
Well, let's add a variable for this gameplay effect class I'm going to click plus and this can be called

09:18.360 --> 09:23.820
event based effect class and we'll change its type.

09:23.820 --> 09:30.030
It's going to be gameplay effect and let's see if we can find gameplay effect in here.

09:30.420 --> 09:36.150
Gameplay effect, here it is, but it's not an object reference, it's going to be a class reference

09:36.150 --> 09:42.900
and if we compile we can set it to a default value and it's going to be g event based effect.

09:43.020 --> 09:46.350
Now how are we going to apply this effect?

09:46.350 --> 09:52.890
Well, we're going to have to make an effect context and that is something we have to do with an ability

09:52.920 --> 09:54.060
system component.

09:54.060 --> 09:58.290
But gameplay abilities can get their owning ability system component.

09:58.290 --> 10:04.980
We can use get ability system component from actor info and from that ability system component, we

10:04.980 --> 10:06.780
can make an effect spec.

10:06.780 --> 10:11.820
So we can say make effect spec, we can even make an effect context as well.

10:11.820 --> 10:17.280
We can drag off of it and make make effect context.

10:17.780 --> 10:25.640
And plug that in because make outgoing spec needs a context, we can plug that in and we have an outgoing

10:25.670 --> 10:26.390
spec.

10:26.420 --> 10:31.520
Now we want this spec to be specific to event based effect class.

10:31.520 --> 10:38.270
So we're going to use that as the gameplay effect class and we'll just use one for the level.

10:38.270 --> 10:41.600
Nothing will change based on the level of this effect spec.

10:41.600 --> 10:44.660
And once we have this effect we can apply it.

10:44.660 --> 10:53.690
But we do want to use a set by color magnitude because this effect modifies incoming XP according to

10:53.690 --> 10:55.670
a set by color magnitude.

10:55.670 --> 10:58.490
So we'll take the return value.

10:59.070 --> 11:03.270
And we're going to use a sign tag set by color magnitude.

11:03.360 --> 11:05.040
So let's hook that up.

11:05.040 --> 11:09.030
And this has to be when event is received, right?

11:09.060 --> 11:15.420
Not directly after calling wait gameplay event, but we're using event received here.

11:16.100 --> 11:17.570
So we'll hook that in.

11:18.410 --> 11:19.820
Now, what is the tag?

11:19.820 --> 11:22.790
That's going to be our event tag, so we'll hook that up.

11:23.930 --> 11:25.400
And the magnitude.

11:25.400 --> 11:28.970
Well, we can send a magnitude through in our gameplay event.

11:29.000 --> 11:30.440
We'll hook that up.

11:30.650 --> 11:38.330
So we haven't sent the event yet, but when we do, we can send it using the event tag of the attribute

11:38.330 --> 11:41.330
that we wish to change like incoming XP.

11:41.540 --> 11:45.530
And we can set the event magnitude on the gameplay event data.

11:45.560 --> 11:50.510
Once we've assigned the set by caller magnitude, we can then apply the gameplay effect.

11:50.540 --> 11:56.900
So I want to apply it to the owner of this gameplay ability.

11:56.930 --> 12:01.880
We can just use this ability system component that we get from actor info, right?

12:01.880 --> 12:08.570
So we can get that and from that we can apply the gameplay effect spec we're going to call apply gameplay

12:08.570 --> 12:10.460
effect spec to self.

12:11.190 --> 12:14.310
And pass in the gameplay effect spec.

12:15.130 --> 12:22.540
And with that, we'll be applying our event based effect after setting it set by caller magnitude to

12:22.540 --> 12:25.810
whatever was passed through in the gameplay event data.

12:25.840 --> 12:30.040
Now we just need to send that event and we'll get to that.

12:30.040 --> 12:37.330
But before we start thinking about actually sending that event, we need to remember that our Aura character

12:37.330 --> 12:39.430
doesn't have this gameplay ability.

12:39.460 --> 12:45.730
In fact, it doesn't have any passive gameplay abilities, abilities that should be activated as soon

12:45.730 --> 12:47.740
as they are given.

12:47.770 --> 12:55.180
So what we should do is we should have an array of passive gameplay abilities that should be applied

12:55.180 --> 13:01.240
by our ability system component and they're passive, so they should be activated once as they're given.

13:01.360 --> 13:09.580
So to wrap this up, let's just make sure that we get that ability and we activate it on aura.

13:09.970 --> 13:13.690
So we're going to have to get our Aura character open.

13:13.690 --> 13:21.460
I'm going to go ahead and close all tabs and open my public folder, open character and get aura character.

13:21.470 --> 13:26.380
And in fact, her abilities are inherited from Aura character base.

13:26.390 --> 13:29.840
They just so happen to not be used on the enemy class.

13:29.840 --> 13:32.630
So really these could be moved.

13:32.630 --> 13:38.150
But all I'm going to do is just add a new array of gameplay abilities, just like start up abilities,

13:38.150 --> 13:44.100
but they're going to be start up passive abilities and we'll make sure that aura gets those applied.

13:44.120 --> 13:50.960
So I'm going to just copy the array of subclass of gameplay abilities called start up abilities and

13:50.960 --> 13:54.890
paste it and rename this to start up passive abilities.

13:55.160 --> 14:02.270
So now that we have this array, we can go through and make sure that this gets looped through and these

14:02.270 --> 14:08.090
abilities get given to Aura at the beginning of the game, just like start up abilities.

14:08.270 --> 14:16.730
So let's see how that happens by going to private character or a character and see where we're calling

14:16.730 --> 14:22.910
a function to get those start up abilities given we see in possessed by we're calling Add character

14:22.910 --> 14:23.660
abilities.

14:23.660 --> 14:27.680
So let's see how add character abilities works.

14:28.330 --> 14:31.600
We'll go to its declaration or usages, and here it is.

14:31.630 --> 14:35.900
It gets the ability system component and calls add character abilities.

14:35.920 --> 14:37.840
Passing in startup abilities.

14:37.840 --> 14:45.520
Well, we could just have an Add character passive abilities also on the ability system component that

14:45.520 --> 14:46.970
would make things quite easy.

14:46.990 --> 14:48.040
Let's do that.

14:48.160 --> 14:56.650
So we'll go to public ability system or ability system component and find add character abilities.

14:56.650 --> 14:57.550
Here it is.

14:57.580 --> 15:06.010
We can copy and paste a copy of it and call this startup passive abilities and call the function, add

15:06.010 --> 15:08.230
character passive abilities.

15:08.230 --> 15:13.270
And it's going to be just like add character abilities with one key difference.

15:13.300 --> 15:19.100
It's going to loop through the passive abilities and call give ability and activate once.

15:19.120 --> 15:23.680
It's also not going to bother with anything related to input either.

15:23.680 --> 15:28.880
We don't care about the input tags or anything like that, but I'm going to copy from Add character

15:28.880 --> 15:37.640
abilities the for loop here and I'm going to change what we're looping through to start up passive abilities

15:37.640 --> 15:41.030
and we can create an ability spec with level one.

15:41.030 --> 15:42.070
That's fine.

15:42.080 --> 15:44.900
We don't need to cast it to aura ability.

15:44.900 --> 15:53.540
So this if statement is unnecessary, all we need to do is call, give ability and activate once passing

15:53.540 --> 15:54.980
in that ability spec.

15:56.360 --> 15:58.160
So it's actually quite simple.

15:58.160 --> 16:01.490
We just loop through it and give it and activate it.

16:01.580 --> 16:10.100
So now a character can call that function in its Add character abilities, which is actually in or a

16:10.100 --> 16:11.400
character base here.

16:11.420 --> 16:20.720
So as we call add character abilities on or ask, we're also going to call Aura, ask add character,

16:20.720 --> 16:24.320
passive abilities, and we're going to pass in start up.

16:25.400 --> 16:26.810
Passive abilities.

16:26.840 --> 16:33.950
Now, as long as that new passive ability we created is in start up passive abilities for aura, Aura

16:33.950 --> 16:36.830
will have this granted and activated.

16:36.860 --> 16:38.180
Now this we can test.

16:38.180 --> 16:40.160
So I'm going to run in debug mode.

16:41.230 --> 16:42.160
We're back.

16:42.160 --> 16:45.550
Let's open those editors and let's also get Aura open.

16:45.550 --> 16:51.790
So we're going to go to Blueprints, character Aura, Open aura, search for passive.

16:51.790 --> 16:54.040
And here's our start up passive abilities.

16:54.040 --> 16:59.770
We're going to click Plus and we want our new to listen for event.

16:59.800 --> 17:01.240
Let's get that.

17:01.240 --> 17:08.770
And now we should have Aura getting this guy listen for event ability activated at the beginning of

17:08.770 --> 17:15.640
the game only on the server and we can prove that by going to listen for event and we can print a string

17:15.640 --> 17:22.120
in activate ability and we can just say listening for events.

17:23.150 --> 17:25.910
Plural and we can start the game.

17:25.910 --> 17:29.240
Let's press play and we see listening for events.

17:29.240 --> 17:36.290
And if we set this to two players, we see listening for events and on the client listening for events.

17:37.510 --> 17:40.330
And if we change this to play as client.

17:42.100 --> 17:45.430
Only the server is saying listening for events.

17:45.430 --> 17:50.660
So when it's a listen server we see it first for the server on both.

17:50.680 --> 17:56.230
That's kind of how it works for listen server in the Pi and then when the client prints it, it shows

17:56.230 --> 17:57.190
that it's the server.

17:57.190 --> 18:00.850
But trust me, it's only being activated on the server.

18:01.000 --> 18:03.010
We'll set that back to one player.

18:03.010 --> 18:10.420
So now that we know we're listening for events and we know that if that event we're listening for contains

18:10.420 --> 18:17.170
the correct tag, then we'll assign a set by color magnitude with that tag and apply that gameplay effect

18:17.200 --> 18:22.870
event based effect class, which is only equipped to apply a modifier for incoming XP.

18:23.680 --> 18:27.520
So we're almost to the point of being able to test this out.

18:27.550 --> 18:32.200
We just need to send that gameplay event and we're going to do that next.

18:32.230 --> 18:33.360
How exciting.

18:33.370 --> 18:35.230
We've almost got working XP.

18:36.160 --> 18:36.910
Excellent job.

18:36.910 --> 18:38.650
I'll see you in the next video.
