Welcome back.
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
creating a gameplay ability that can listen for gameplay events.
Now we know that we can send gameplay events.
We're doing so from our montages and that gameplay abilities can listen to them.
Well, let's go ahead and run the Unreal Engine editor and create an ability that can do this.
Okay, so I'm back in the editor.
I don't need to open anything.
I just want to create a new ability.
So I'm going to go to blueprints, ability system, aura abilities.
Now this is going to be a special kind of ability.
It's going to be a passive gameplay ability.
I'd like it to always be running, but there are some things that it doesn't need to do.
It does not need to replicate and it really only needs to run on the server.
So as soon as we give this ability, we can activate it, We can use, give ability and activate once
and then it can always be running.
So we'll have some optimizations in place such as not replicating.
Now that's what my passive abilities are going to do.
They're going to run all the time.
So I'm going to make a new folder called Passive.
In fact, this is going to be a startup ability, so we'll call it passive startup.
And here in passive startup we'll make our new gameplay ability.
So we're going to search for gameplay ability and choose gameplay ability and make this new class and
it's going to be called gar underscore listen for events.
That's what this gameplay abilities job is.
Let's open it up and the first thing I'm going to do is optimize this by changing some of the settings
so that it doesn't do things that we don't need it to do.
We're going to set its instancing policy to instance per actor, so we only have one and it sticks around.
Now its execution policy is not going to be predicted.
It's not even going to run locally.
It's going to run on the server only.
So not only server initiated, but server only means it won't replicate at all.
It'll only be running on the server.
That's all we care about.
So that's what we want.
We can leave replication policy at do not replicate.
We've already mentioned that.
We don't even touch that.
Now we have a gameplay ability.
We want a way to listen to gameplay events.
So as soon as we activate the ability we're going to use wait gameplay event.
And we're going to listen for a gameplay event and we can listen for a non exact match.
For example, if I uncheck only exact match, then I could listen to a general category of gameplay
tags.
For example, let's say I want to listen for when any of my attributes are sent in a gameplay event
so we can send a gameplay event with attributes dot anything and we can listen for events for that.
That's what I'd like.
I'd like to listen for attributes and then we can have this nice generic wait for event that will respond
when we send any gameplay event that has an attribute tag that includes incoming XP.
Now.
Yes, we still need to create a tag for incoming XP.
That's going to be one of our next things to do.
But for now we know that we're going to listen for any attribute tag events.
Now we don't want to only trigger once either, so leave that unchecked because this gameplay ability
will be running throughout the course of the game as long as the game is running and continually firing
off.
Wait gameplay event we've seen in the past how this can fire off multiple times and get us into trouble.
If you only want it to fire once, then you check that checkbox.
In this case we don't.
We want this to fire off multiple times.
Now, as we've seen before, gameplay events can pass along data in a payload.
If we take this payload and we break this gameplay event data struct, we can see all the things we
can send in a gameplay event.
The ones I'm interested in are tags and magnitude a float value because if we have a tag that's being
sent and it's an attribute tag, then we can know which attribute we're supposed to change and then
we can create some kind of gameplay effect and set a set by color magnitude on it and apply it.
So we need some kind of effect and we can make one and set it as a variable on our gameplay ability.
Let's go ahead and make one.
I'm going to right click New Blueprint class, search for gameplay effect.
Choose that and we'll call this G underscore.
And this is going to be in effect specifically for this gameplay ability that's listening for events.
So we can call it something like event based effect.
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
duration policy and then we can add a modifier that can modify incoming XP.
And then if we want this effect to be able to modify anything else, we can add other modifiers, but
we're just going to add incoming XP to this.
There it is at the bottom and this will add to incoming XP and the modifier magnitude is going to be
set by caller and the set by caller magnitude.
Will that needs to be a specific tag, right?
Well, we can use attribute tags now we don't have an attribute tag for incoming XP, so we should have
one.
In fact, we should probably have attributes dot meta because it's not a primary, it's not a resistance
or a secondary or a vital attribute for that matter.
It's kind of its own thing.
Meta attributes are their own thing, So I'm going to close the editor and create a native gameplay
tag, making sure to save everything.
We're going to go into our gameplay tags and make a meta gameplay tag for our incoming XP.
So we'll go up to our attributes where our other attributes exist and we'll make a new attribute tag
and we'll call it attributes Underscore meta underscore incoming XP.
And we'll go ahead and create that in the CPP file as well.
So let's go up to our other attributes.
We'll copy a multi-line comment, paste one here.
We'll call it meta attributes and we'll just create the meta attribute for incoming XP.
So we have to change this to attributes underscore meta incoming XP.
We're going to say the name is attributes dot meta dot incoming XP and the F string comment is going
to say incoming XP meta attribute.
So that's our first meta attribute gameplay tag.
We haven't really had a need for the damage meta attribute, incoming damage, but now we see that we
have a need for incoming XP.
All right.
So now that we have that attribute, we can go ahead and run back in the editor again.
And we can open up our assets that we had open.
And in our event based effect, we need to go back down to our modifier because it's set by caller magnitude
needs to listen for a specific tag.
It's going to listen for attributes meta incoming exp.
So if we ever send an event with this specific tag as its event tag, then in GA listen for event we
can receive that event and remember we can listen to events if they have attributes as their first tag
in the hierarchy.
So sending attributes dot meta dot incoming exp will indeed trigger this event.
I promise you it'll work.
We'll see.
Now the event tag is going to be the tag that we were listening for.
Except the cool thing is when we send an event with this full tag attributes dot meta dot incoming exp.
Then this event tag will have that full tag in it.
It's not just going to be attributes and that's the cool thing because now we can apply this gameplay
effect and set it set by caller magnitude.
So how are we going to apply this gameplay effect?
Well, let's add a variable for this gameplay effect class I'm going to click plus and this can be called
event based effect class and we'll change its type.
It's going to be gameplay effect and let's see if we can find gameplay effect in here.
Gameplay effect, here it is, but it's not an object reference, it's going to be a class reference
and if we compile we can set it to a default value and it's going to be g event based effect.
Now how are we going to apply this effect?
Well, we're going to have to make an effect context and that is something we have to do with an ability
system component.
But gameplay abilities can get their owning ability system component.
We can use get ability system component from actor info and from that ability system component, we
can make an effect spec.
So we can say make effect spec, we can even make an effect context as well.
We can drag off of it and make make effect context.
And plug that in because make outgoing spec needs a context, we can plug that in and we have an outgoing
spec.
Now we want this spec to be specific to event based effect class.
So we're going to use that as the gameplay effect class and we'll just use one for the level.
Nothing will change based on the level of this effect spec.
And once we have this effect we can apply it.
But we do want to use a set by color magnitude because this effect modifies incoming XP according to
a set by color magnitude.
So we'll take the return value.
And we're going to use a sign tag set by color magnitude.
So let's hook that up.
And this has to be when event is received, right?
Not directly after calling wait gameplay event, but we're using event received here.
So we'll hook that in.
Now, what is the tag?
That's going to be our event tag, so we'll hook that up.
And the magnitude.
Well, we can send a magnitude through in our gameplay event.
We'll hook that up.
So we haven't sent the event yet, but when we do, we can send it using the event tag of the attribute
that we wish to change like incoming XP.
And we can set the event magnitude on the gameplay event data.
Once we've assigned the set by caller magnitude, we can then apply the gameplay effect.
So I want to apply it to the owner of this gameplay ability.
We can just use this ability system component that we get from actor info, right?
So we can get that and from that we can apply the gameplay effect spec we're going to call apply gameplay
effect spec to self.
And pass in the gameplay effect spec.
And with that, we'll be applying our event based effect after setting it set by caller magnitude to
whatever was passed through in the gameplay event data.
Now we just need to send that event and we'll get to that.
But before we start thinking about actually sending that event, we need to remember that our Aura character
doesn't have this gameplay ability.
In fact, it doesn't have any passive gameplay abilities, abilities that should be activated as soon
as they are given.
So what we should do is we should have an array of passive gameplay abilities that should be applied
by our ability system component and they're passive, so they should be activated once as they're given.
So to wrap this up, let's just make sure that we get that ability and we activate it on aura.
So we're going to have to get our Aura character open.
I'm going to go ahead and close all tabs and open my public folder, open character and get aura character.
And in fact, her abilities are inherited from Aura character base.
They just so happen to not be used on the enemy class.
So really these could be moved.
But all I'm going to do is just add a new array of gameplay abilities, just like start up abilities,
but they're going to be start up passive abilities and we'll make sure that aura gets those applied.
So I'm going to just copy the array of subclass of gameplay abilities called start up abilities and
paste it and rename this to start up passive abilities.
So now that we have this array, we can go through and make sure that this gets looped through and these
abilities get given to Aura at the beginning of the game, just like start up abilities.
So let's see how that happens by going to private character or a character and see where we're calling
a function to get those start up abilities given we see in possessed by we're calling Add character
abilities.
So let's see how add character abilities works.
We'll go to its declaration or usages, and here it is.
It gets the ability system component and calls add character abilities.
Passing in startup abilities.
Well, we could just have an Add character passive abilities also on the ability system component that
would make things quite easy.
Let's do that.
So we'll go to public ability system or ability system component and find add character abilities.
Here it is.
We can copy and paste a copy of it and call this startup passive abilities and call the function, add
character passive abilities.
And it's going to be just like add character abilities with one key difference.
It's going to loop through the passive abilities and call give ability and activate once.
It's also not going to bother with anything related to input either.
We don't care about the input tags or anything like that, but I'm going to copy from Add character
abilities the for loop here and I'm going to change what we're looping through to start up passive abilities
and we can create an ability spec with level one.
That's fine.
We don't need to cast it to aura ability.
So this if statement is unnecessary, all we need to do is call, give ability and activate once passing
in that ability spec.
So it's actually quite simple.
We just loop through it and give it and activate it.
So now a character can call that function in its Add character abilities, which is actually in or a
character base here.
So as we call add character abilities on or ask, we're also going to call Aura, ask add character,
passive abilities, and we're going to pass in start up.
Passive abilities.
Now, as long as that new passive ability we created is in start up passive abilities for aura, Aura
will have this granted and activated.
Now this we can test.
So I'm going to run in debug mode.
We're back.
Let's open those editors and let's also get Aura open.
So we're going to go to Blueprints, character Aura, Open aura, search for passive.
And here's our start up passive abilities.
We're going to click Plus and we want our new to listen for event.
Let's get that.
And now we should have Aura getting this guy listen for event ability activated at the beginning of
the game only on the server and we can prove that by going to listen for event and we can print a string
in activate ability and we can just say listening for events.
Plural and we can start the game.
Let's press play and we see listening for events.
And if we set this to two players, we see listening for events and on the client listening for events.
And if we change this to play as client.
Only the server is saying listening for events.
So when it's a listen server we see it first for the server on both.
That's kind of how it works for listen server in the Pi and then when the client prints it, it shows
that it's the server.
But trust me, it's only being activated on the server.
We'll set that back to one player.
So now that we know we're listening for events and we know that if that event we're listening for contains
the correct tag, then we'll assign a set by color magnitude with that tag and apply that gameplay effect
event based effect class, which is only equipped to apply a modifier for incoming XP.
So we're almost to the point of being able to test this out.
We just need to send that gameplay event and we're going to do that next.
How exciting.
We've almost got working XP.
Excellent job.
I'll see you in the next video.