Welcome back.
Now we're activating and deactivating our passive abilities.
And we didn't test in multiplayer last video.
But we can test that right now.
And in this video I'm concerned with having more than just print strings.
I want to see some Niagara systems.
So let's just really quickly test this.
In multiplayer, I'm going to equip my halo of protection.
We see client one and server both say it was activated.
We can go ahead and try to push it out.
And we see that life siphon was activated both on server and client.
Halo of protection was ended.
And so it looks like in general all of these things are working.
Mana siphon was activated.
We didn't push anything out.
Let's go ahead and replace mana siphon.
Mana siphon ended.
So it looks like things are working.
And we're ready to start making some visual effects.
Now I'm going to want a Niagara component just like our debuff component.
We have a debuff component on our character for each debuff type.
So if we go to aura BP Aura character, we have a stun debuff component and a burn debuff component.
And they're not set to be activated automatically, but we can check Auto Activate to see them there.
I'd like something similar, but for my passive abilities.
And this is a good design pattern because if our debuff components themselves have their own unique
tag to identify themselves, they can listen to a generic broadcast save from the ability system component,
and whenever one of our passive abilities is activated, we could broadcast, say, the ability tag,
and we could have a passive Niagara component that can activate and deactivate itself based on some
delegate broadcast.
So that's the approach I'd like to take.
We already have a stun debuff component, which is basically a debuff component with a tag, and it
listens for a delegate broadcast, but it listens for a change in a gameplay tag.
So we're going to need something a little different and that merits a new class.
So I'm going to make a new type of Niagara component.
So let's go into Aura Public Ability system.
And we'll put this in a new folder called passive.
So I'm going to search for all classes and use Niagara component.
We'll choose Niagara component as the parent class, and we'll put this in ability system slash passive.
And we'll call this passive Niagara component.
We can call it passive spell Niagara component, but I don't want it to get too long, so we'll call
it this.
We'll create the class and close the editor.
So I'm going to go ahead and keep these tabs open for now and go to my public ability system passive
and get that passive Niagara component open.
I'll pull it all the way to the left and control Co to get the CP.
I always like to move my CP files to the left.
I don't know why, it just feels more comfortable that way for me, but I digress.
We have passive Niagara component and what does our passive Niagara component need?
It needs a couple things.
It needs a gameplay tag and also needs a constructor.
Those are things we can put in the public section.
So we'll start with a constructor.
And a gameplay tag.
So f gameplay tag.
We'll call this passive spell tag and it gets a U property and we're going to make it edit defaults
only.
We do need to include the header file in order to use gameplay tags.
That header is gameplay tag container dot h, and now we can use that gameplay tag and we can generate
a definition for our constructor.
And all I want is to set be auto activate to false.
Okay, so a couple things.
I want this Niagara component to activate itself in response to a delegate broadcast.
And that means we'll need a delegate to broadcast something to broadcast from the ability system component.
So I'm going to make a new delegate on the ability system component that we can broadcast.
So what's this delegate going to do.
How many params does it need.
Well I'd like to broadcast the ability tag so we know which ability is being activated and deactivated.
And I'd also like to broadcast a boolean along with it for whether or not to activate or deactivate
that Niagara component.
So we're going to make a two params delegate.
We're going to declare multicast delegate two params.
And I'm going to call this delegate f.
Activate passive effect and it'll take a const f gameplay tag reference.
And I'll go ahead and give it an inline comment that says ability tag.
And it's going to take a boolean, and I'll give this an inline comment as well.
And this will say B activate.
Just so at a glance, we can know what these are for, and we'll add this delegate right here to our
delegates.
And I'm going to call this simply activate passive effect.
So now that this delegate exists, our passive Niagara component can now listen for it and have a callback
to respond with.
Now where are we going to bind this function?
I'd like to do it early on, preferably in begin play.
So I'm going to make a protected section and override Virtualvoid.
Begin.
Play, not begin.
Destroy.
Begin.
Play.
Override here.
In addition to begin play, I'd like the callback for this, and I'm going to call it on Passive Activate
for lack of a better name, and it will be const f gameplay tag, reference ability tag for the first
input, and a bool called be activate for the second, and we can generate definitions for both of these.
So we have begin play.
We have on passive activate.
Now begin play is where we want to bind the callback to that delegate.
And I'm going to do something similar to what we did in our Debuff Niagara system.
In other words, I'm going to check to see if the ability system component is valid first.
If it's not, then I'm going to register to a delegate on the owner that will be broadcast when that
ability system component becomes valid.
So we're kind of making sure to cover ourselves in both cases.
So first thing I'm going to do is I'm going to say if you aura ability system component I'll get that
auto include I'll call this our ASC equals I'll cast to aura ability system component.
And we're going to use the you ability system blueprint library function.
Again there's another auto include get ability system component.
What are we going to get the ability system component of.
Well here in the Niagara component we can call get owner.
So see how that works.
We can always get the ability system component and get ability system component on.
The blueprint library just requires an actor and that's pretty easy to access.
So once we have this aura ask, we can bind our callback.
But the thing is, you know, at this point the aura ask could possibly not be registered yet.
So we're going to have an else in this case as well.
Now first things first.
If it is valid then we're going to take aura ask and get that activate passive effect and bind to it
with Add you object.
We'll bind this user object and we'll bind our callback on passive activate.
We're going to go ahead and put that right there.
And we've bound to it.
But if the aura ask isn't valid yet then how did we get it from within the Debuff Niagara system?
Well we did so by accessing a delegate that gets broadcast from our character, and that delegate is
accessed through the combat interface.
So I'm actually going to say else if and I'm going to see if the owner implements the combat interface.
So I'm going to say I combat interface again another auto include there.
We'll call it combat interface.
And set that equal to the result of a cast to I combat interface.
And we'll cast get owner.
So in this case now we have the combat interface.
And from the combat interface, if that's valid, which inside the if statement it is we can use that
get on ASC register delegate.
By the way, you can always go back to the combat interface to remind yourself what its signature is.
Get on ASC register delegate is this function that returns an F on ASC registered.
We can even check that out.
It's defined up here F on ASC registered simply returns a pointer to the ability system component that
just became valid.
And what are we going to bind?
Well, we could add a lambda to this.
I'm going to go ahead and use Add lambda.
And let's make a lambda.
And the lambda can take in a you ability system component.
I'll call it AC.
And all I want to do is what I did here.
I want to take these lines where we're binding our callback to activate passive effect.
I'm just going to paste those into my lambda here.
Now of course we need to capture this if we're going to be using it.
So I have to pass this into my square brackets there.
And with that I now have my callback bound.
Now what does our callback need to do?
It just needs to activate or deactivate itself based on two conditions.
Is the ability to broadcast this component's ability tag, because remember it has a passive spell tag.
If that's the case, then we should see if the boolean be activate is true or false.
So let's do it.
Let's first take that ability tag and call matches tag exact with our passive spell tag.
Otherwise we do nothing.
Then we can check if B activate.
And we'll have an if and an else.
Now if be activate could also get a little buddy here I'm going to add another condition.
I'm going to say not is active because I don't want to activate if it's already active.
But if we pass that then we can call activate the function all Niagara components have.
And in the else case we'll call deactivate another function all Niagara components are blessed with.
So now on passive activate is going to handle activating and deactivating in response to the delegate
broadcast.
Now the only thing left is to actually broadcast that delegate.
Now here's the thing a delegate broadcast happens locally.
It doesn't happen across the network.
It's not like an RPC.
And if we're broadcasting this from the ability system component in our function server equip ability
implementation, we're on the server.
It's called server equip ability implementation.
So this would only be broadcast on the server.
For that reason I'd like to make the broadcast in a.
Net multicast RPC because all characters need to see these particles.
Everyone deserves to see particles once in a while.
So I'm going to go ahead and go into our ability system components H and add myself a nice RPC.
I'll put it right here.
I'll call it multicast.
Activate passive effect.
It's going to take a const f gameplay tag for the ability tag.
And a bool called B activate.
And because this is going to be an RPC, it gets net multicast.
And I'm going to make this we can make it unreliable.
It's a visual effect.
As important as those beautiful effects are, as much joy they add to people's lives.
They're unreliable.
Now multicast.
Activate passive effect.
What's it going to do?
Who's it going to call?
Not Ghostbusters.
It's going to call activate.
Passive effect.
Broadcast.
And it's going to pass through that ability tag and that bull be activate.
So the last last step is to get multicast activate passive effect.
Call that where do we call it.
Well all things lead back to server equip ability implementation.
So when and where do we broadcast this.
Well we're going to broadcast it in conjunction with activating and deactivating abilities.
Really we're going to go down here to first of all where we're checking if it's a passive ability and
if it's a passive ability here, remember, this first check is checking that pesky slot that's already
occupying the slot we're trying to push an ability into.
And if we deactivate that, we should call our multicast delegate.
I'm going to call it first here multicast activate passive effect.
And we're going to pass in the ability tag for this slot.
Now this slot that's sitting here we only have its spec.
We don't have its ability tag.
But we have nice functions like get ability tag from spec.
We can call that passing in this spec with slot.
Very important that we don't pass in the wrong ability spec for these.
And we're going to pass in false in this case because we're deactivating that ability.
We're going to want that Niagara component deactivated as well.
And if we scroll down just a little bit, we'll see that we're activating an ability here.
And if we activate it we want to see that effect get activated as well.
So we're going to call multicast activate passive effect here.
And in this case we're going to pass in the ability tag.
Ability tag.
And we're going to pass in true there and that's going to activate those effects.
Okay, so now we have all the parts in place.
But what we need to do is add three of these passive Niagara components to our character.
Now we can put this on base character, but then we'd have to go and activate abilities separately if
we want our enemies to have passive abilities.
But that's fine.
We can put it on our base character or a character base.
We can have those three Niagara systems here.
So let's go into our protected section.
We could even put these in the private section.
Doesn't really matter.
We'll put them in the private and we'll make these T object pointers of type U passive Niagara component.
We'll add a forward declaration and we'll call this halo of protection Niagara system actually Niagara
component right.
And I'm going to have two more.
I'll paste them both and I'll call this life siphon Niagara component and mana siphon Niagara component.
And these can be you properties with visible anywhere.
So all three get the U property.
Now what are we going to attach them to?
We can attach them simply to the root component.
But what I'd like to do is I'd like to create a scene component to attach them to, because I'd like
that scene component to have its rotation controlled so that I can make sure my Niagara system looks
good.
So I'm going to make a t object pointer to a u scene component.
And I'm going to call this effect attach component.
And I'll make this one visible anywhere as well.
And this will be what I attach my effects to.
Now I can construct these in the character constructor.
So we'll go into the cpp file, and we'll do this at the end of the constructor.
I'm going to first construct my effect attach component.
We'll use create default Subobject.
Using a you seen component I'm going to call this effect attach point.
And I'm going to attach this to the root.
So effect attach component.
We can call setup attachment with git root component.
That's not what I meant to call git root component.
There we go.
And with that we can create the halo of protection Niagara component.
We'll use Createdefaultsubobject.
This though is going to be a U passive Niagara component.
Notice writer gave me an auto include there.
I'll call this Halo of Protection comp.
And I'm going to take Halo of Protection component and call setup attachment and pass in effect attach
component.
And I'm just going to copy these lines and paste them and change this to life siphon component and change
the name to Life Siphon Niagara component.
I'll just call these component and this will be life Siphon Niagara component.
Set up attachment and we'll set it to the attach component.
And last but not least we have mana siphon.
So I'm going to use the mana siphon Niagara component.
Change its name here call Setup attachment.
And we're attaching it.
Now, I mentioned I want to manipulate the effect attach component.
I want to keep it still.
I don't want it to rotate along with my character.
And an easy way to do that is to just go to our character base.
And we can override the tick function.
I can do it right up here.
Virtualvoid tick takes a float called Delta time.
It's an override.
I'm going to override it.
We'll call super and I'm going to take my effect.
Attach component and call set world rotation.
Passing in F rotator.
Zero rotator.
And if I want tick, I need to go into my constructor and set primary actor tick be can ever tick equal
to true.
And with that, I can compile and I can launch.
Okay.
So we've made a lot of changes and we need to go into blueprints character aura and open BP Aura Character
Blueprint and take a look at our components.
We have the effect attach component along with mana, siphon, life, siphon, and halo of protection.
We need to set their Niagara systems now for the Niagara system asset for Halo of protection.
We can just search for Halo and select that.
And if you want to take a look at it, we can open it up and we can see what halo of protection looks
like.
It looks like this.
And by the way, you have these Niagara assets.
You can come in here and mess with them if you like.
So I'm okay with NS Halo for that.
For life.
Siphon.
We can search for life.
And there's an s life siphon.
If you want to take a look at that, it looks like this.
So that's a little bit, uh, more wild and sporadic and smaller.
So kind of cool.
And then from Anti-siphon, if we search for mana, we have mana drain and mana siphon.
I'm going to choose Mana Siphon.
And here's what that looks like.
It's a little bit too light blue for me.
So I'm going to go to initialize particle and under selection take the color and just move it more towards
the deeper blue here.
I think I like those colors, those deeper blue colors a little bit better.
And if you really want to drive this color, you could take that blue and make it bigger, like 100.
Make it nice and glowy.
Nice.
Okay, so I have mana siphon.
Now that we have these Niagara components, I'm going to save all.
I'm going to set it to one player just at first.
And I'm going to go ahead.
And first of all I need to level up.
And then I can go ahead and spin some spell points on all three and start equipping.
So I'm going to full screen this and let's see what happens if I take my halo of protection and equip
it.
Do I get my Niagara system?
No.
So we need to find out why.
Let's place a breakpoint in Onpassive activate in our Niagara component.
All right.
It is being called with halo of protection be activate O.
However, our passive spell tag hasn't been set, so I did forget a step.
Of course, these need their spell tags set so Halo of Protection has a passive spell tag.
It needs to be set to abilities.
Passive halo of protection.
Easy to forget when you have a lot of moving parts.
Life siphon gets life siphon and mana siphon gets mana siphon.
Let's try this again.
Saving all pressing play and leveling up.
Let's full screen and let's activate Halo of Protection.
All right, there we go.
Looking nice.
I'm really enjoying this, especially in the dark.
I like to go into the dark with these really pretty Niagara effects.
And it's cool because now you can totally see that its halo of protection that's active and whatever
that means, whatever mechanics that you programmed for it, that's up to you.
But at least you know that it's active.
Let's activate our life siphon.
There's the red one.
I think I might tweak the red one and make it glow a little brighter, but now we have both.
Let's try pushing out one of our abilities.
I'm going to spend a point on Mana siphon.
I'm going to equip it in place of Halo of protection.
There it goes.
Halo of protection.
It's gone away.
And here is my mana siphon.
So we have blue and red, and of course we can push out the blue with the red, even though we already
have the red.
Hopefully that means the blue goes away.
Yes.
And we just have red.
And if we take the yellow and push out the red, the red should go away.
And we just have yellow.
Perfect.
Things are working.
That is so satisfying after doing so much work now we do need to test multiplayer.
And I'm going to test three players because.
I just want to see if, first of all, if my server change is propagated to clients, and then if one
client changes, do we see it on the server and the other client.
So if you really want to test your multiplayer mechanics, a really good way to do so is with three
players.
So I'm going to go ahead and just try to fill the screen as much as I can here and see if we can really
test this out.
Now.
I'm going to first try on the server, so I'm going to level up on the server.
And I'm going to see if I can get that spell menu open.
I'm going to have to sort of push this off a little bit off the screen.
Okay.
I'm going to first equip.
Halo of protection.
I see the yellow.
And I see it on both clients.
So far so good.
Let's equip our life siphon.
I see both red and yellow on both clients looking good.
And let's just try equipping our mana siphon in place of halo of protection.
We should see the yellow go away.
It does.
Red and blue.
Stay there and we'll test one more.
We'll go to, uh.
Let's take our red and equip it on the blue.
We should no longer see blue, just red.
And we do.
And it's looking good.
Okay, cool.
So server works.
Clients see it.
Let's try now on a client.
We'll make some changes and see if we can see that on the server and on the other client.
So we'll start with this client.
We'll level up here.
And we'll go ahead and spend a point on each of the three abilities.
I know it's kind of hard to see, but I'm going to equip the halo of protection, and I see the gold
on all three machines.
It's looking great.
And I'm going to equip my mana or my life siphon rather.
And I see red and yellow on all machines looking great.
And I'm going to take my blue and equip it to the yellow, pushing out the yellow, out with the yellow
and with the blue we have red and blue.
Looking good.
And let's just try taking the blue and pushing out the red.
We should only have blue now, and we only have blue.
And we see it on the other client and on the server.
So it works perfectly in multiplayer.
All right.
So now we have passive abilities and the framework is there the main framework.
All I really cared about was getting three abilities that we could equip.
And activate as we equip them.
And that just gives us a new kind of dynamic here.
We now have the ability to equip something in the menu, and as we do so, that means it becomes active.
We have a passive ability going on in the background.
It can be doing things, it can be responding to things.
And we also have a visual component to that that we can see.
And we know that we can activate and deactivate based on what's going on in the menu.
And.
It's a really nice system that we have in place here.
Okay, so the last thing I'm going to do is go to effects.
And these effects are actually in the stun folder.
And I'm going to go to Life siphon and I'm going to go to initialize particle and take this color.
It looks like it's already ramped up pretty high.
So I don't think I should mess with the color much.
I can make it 500, but we can mess with these in other ways like curl noise force.
This makes it more sporadic.
I can take the noise frequency and put it up to 50, and it's really going to swirl off into the distance.
Noise strength I can increase to 2000.
And now our life syphon particles are swimming around in a lot more of a sporadic manner and kind of
like that.
So I'm going to avoid trying to do too many tweaks.
In this video, I think that.
That's something you can just do.
You can always tweak things for hours, and you know it'll never look perfect until it does.
But with that, we have passive abilities.
They're active.
We have Niagara systems.
It's looking great.
Excellent job.
And I'll see you in the next video.