Welcome back.
In the last video, we learned a little bit more about gameplay cues, and we have our gameplay cues
now all in the same folder, and we've designated the gameplay cue notify paths to that folder and Blueprint's
ability system gameplay cue notifies they're all here.
Now that's great, but so far we've only created the gameplay cue notify static type of gameplay cue,
and we've seen that there are others now.
Gameplay cue notifies static is limited.
It's not actually instanced, so this is treated as if it were, say, a static function call on a static
function library.
For example, a gameplay cue notifies static is a gameplay cue notify that operates on the class default
object, so there are no instances spawned when we execute the gameplay cue.
Now there's another kind of gameplay cue notify.
There's the gameplay cue notify actor, and for the gameplay cue, notify actor, we actually do spawn
an instance of that class when we execute it.
I'd like to create one of those now.
So I'm going to go to create new blueprint class and search for gameplay cue notify and choose Gameplay
Cue Notify Actor and select it.
And I'm going to call this GC underscore shock loop.
Shock loop seems to indicate that this is going to be something that loops.
And that's what gameplay cue notify actors are pretty good for.
If you need some kind of looping sound, or perhaps a Niagara system that needs to stick around until
you remove this gameplay cue.
Gameplay cue notify actors are great for that.
Now if we open it.
Notice that it's a lot different looking than our GC Shock Burst.
Shock burst has an event graph and this on execute that we overrode.
But shock loop actually has a viewport.
This is an actual actor.
It has a default scene route like all actors have.
It has a construction script an event graph.
It even has begun play event.
Tick.
All of that stuff, all the stuff an actor has.
But it's a special kind of actor.
It's a gameplay cue.
Notify actor and the gameplay cue.
Notify actor has some functions we can override to determine what happens when we execute this gameplay
cue.
Now, in the class settings, notice that we can even implement interfaces and things like that.
And in the class defaults.
This is where we set the gameplay cue tag.
And of course we'll need one if we want this shock loop to be executable as a gameplay cue.
So I'm going to go to Project Settings Gameplay Tags and add a new gameplay cue tag.
And this will be gameplay cue shock loop.
And I can close project settings and our new shock loop.
I'm going to set its gameplay queue tag to Shock loop.
Now one important setting is auto destroy on remove.
You're going to want to check that.
Otherwise, subsequent calls to execute this gameplay queue won't work if it's not destroyed when the
gameplay queue has been removed.
Now, a gameplay queue can be added to an actor, and it can stay active until you remove it from that
actor.
And in order to determine what happens when active, we can override a function.
Now on active is, as we can see by the pop up called, when a gameplay cue with duration is first activated
and will only be called if the client witnessed the activation.
So in other words, if we activate this and we have some looping sound and a looping beam particle effect
or something like that, if another player spawns in, they won't see it.
They missed it.
Whereas if we spawn that effect in while active, while active is good for things that a newly spawning
in player should see.
So while active will be triggered for a player that spawns in, whereas on active is a one off that
that player missed.
Here's a good way to think about when to use on active versus while active.
Let's say you have an explosion, and as soon as this gameplay cue is added to an actor, you want that
explosion to trigger.
And if a new player spawns in and this gameplay queue is still active, well, you don't need it to
see that explosion.
That explosion happened in the past.
It's done.
But let's say now that you're spawning a beam effect like a shock electric beam.
And while this gameplay effect is active, you want that beam to be active.
And if a new player spawns in, they should see that beam.
So while active, should trigger for them because it's still happening.
So in our case, for a shock loop for our electric beam we're going to want to override while active.
Now while active takes in the my target.
But it can also take in parameters.
And if we break the gameplay cue parameters.
Notice that there are quite a few of them that can be passed into this gameplay queue, and this can
be really useful.
We can use any number of these.
So we're going to be using this to spawn our electric beam and play a sound.
Now an important question is how do we actually trigger this gameplay cue?
How do we make it happen?
Well, to do that, we add this gameplay cue to an actor.
So let's go into our gameplay ability.
Aura abilities lightning to electrocute.
And let's actually add this gameplay cue to an actor.
So after we've received the gameplay event, this is when I want to start spawning that electric beam.
So what I can do is I can right click and type Add Gameplay cue on actor, and notice there's a looping
in parentheses here.
So if we add a gameplay cue on an actor, it's going to remain active until we remove it.
We need to specify the actor to add this to.
For now, I'm just going to pass in the avatar.
So I'm going to get avatar actor from actor info and pass that in for now.
And we're going to set the gameplay tag to Shock Loop.
We can even make some gameplay queue parameters to pass in.
And if I compile you'll see that that's required.
So we're going to make gameplay queue parameters and pass them in.
Now as soon as this node is reached, shock loop is going to be active.
We can get that my target and we can get object name.
And we can print it in a string.
So we can see what happens when we add the gameplay cue.
Let's press play and right click.
And we get that print string.
Now if we try to execute multiple times.
Well, let's try it a second time.
We don't see the printed string every subsequent time.
We're going to have to remove this gameplay cue because it's already active.
So what we can do is remove it.
Here in prepared to end ability.
And how do we remove it?
We can call remove gameplay cue from owner.
Now this will remove the gameplay cue.
And this is a function actually on the gameplay ability itself.
So it can take in self as the reference.
And it just is smart enough to find the avatar associated with this gameplay ability.
And we specify the gameplay tag, we're going to choose Shock Loop.
So we can go ahead and activate it.
We got the string we can activate again.
We got the string again.
And we'll keep getting that string if we keep activating it because we keep removing it.
Now if we want to see exactly when it's removed, we can do that here in our shock loop gameplay queue,
we can override the function.
Override on remove.
And here in on remove we can also print a string.
And I'll make this string red.
And we'll say remove GCC shock loop.
And now we can see when it gets removed.
I'm still holding the mouse button down, and if I unclick, we see that it's removed.
So the gameplay cue is added as soon as we get that gameplay event.
It's removed when we unclick, but notice we didn't see the string the second time we release the mouse
button.
Let's see that again.
So we get it.
We get on remove, we activate again, and then we don't get on remove.
So what's going on here?
Well, if we click on class defaults we need to make sure auto destroy on remove is checked.
If we have that checked.
Then we should see the remove message.
Every single time.
So we'll make sure that each time GC shock loop is added and removed, the actual instance of this gameplay
queue notify actor is going to be destroyed on remove.
Okay, so that's great.
But we want to see a electric beam, right.
How are we going to do that?
Well, first of all we need to go to while active and spawn a Niagara system.
I'm going to remove the print string.
I actually don't need the print string.
And on remove either.
And I'm going to use spawn system attached.
I'd like to use spawn system attached because I want to attach this system to a specific socket, the
socket on or staff in the case of aura.
So back to the electrocute in the event graph up here where we're passing in gameplay queue parameters,
I'd like to pass something in to my queue parameters.
And here in the shock loop we can get something to pass into the component we want to attach to.
Now, the gameplay queue parameters has a number of things that we can set.
One of them is called target attach component.
I'd like to set that.
Now for electrocute.
I'd like to get the weapon, and it'd be handy to get the weapon from an interface function call.
So if I could just take my avatar and pass it into an interface function call that retrieves the weapon,
well, then we could use that weapon, as the weapon is a skeletal mesh component, and we could pass
that in as target attached component as that's a scene component.
And we can just pass it right in there.
That would make things easy.
So I'm going to go ahead and close the editor.
Saving all.
I'm going to open my combat interface, and I'm going to add a function to get the weapon.
I don't think we have a get weapon function.
So this function will return a skeletal mesh component.
So it's going to return a new skeletal mesh component pointer.
And this will be called get weapon.
And I'd like it to be a blueprint native event.
Blueprint callable.
So we'll go ahead and put that here and we'll override it in the base character class or a character
base.
So here in combat interface we'll say virtual you skeletal mesh component get weapon implementation.
We'll implement it.
And we're going to simply return the weapon.
So now we have this easy to use function to get the weapon.
Let's go ahead and compile and launch back up.
And we can go right back into electrocute, back to where we're making gameplay parameters, and we
can set the target attach component.
So I'm going to right click and type Get Weapon.
We're going to use that interface function call.
We can use get avatar actor from actor info and pass that in.
And take the return value and hook it up to target attach component.
So right before we add the gameplay cue, we're going to call this function get weapon.
Okay, I just made some spaghetti knots here, so I'm going to make sure to tidy up.
My nodes here.
And of course, this is something that will be refactoring into a collapsed function to make things
easier to see and to read.
But for now, this is okay.
There we go.
Trying to keep the spaghetti to a minimum here.
And now we're passing in target attach component.
And here in shock loop I don't need shock burst.
I'm going to close that.
But here in shock loop in while active.
Now that we have a target attached component we can hook that in to spawn system attached.
And we can get that tip socket.
So we can pass in tip socket and we can double check that.
That's what it's called.
If we go to characters or staff SQM staff and it's actually called yes tip socket.
So we're spawning a system and we're attaching it to the TCP socket.
Now the system template.
We're going to search for beam and get electric beam.
Now I'd like to check auto destroy because as soon as this is deactivated, I'd just like it to be destroyed.
Okay, so we've spawned a system, but what about the end of that beam?
Because we're going to attach it to the tip socket.
But the beam itself has an endpoint, and we can see that by browsing and opening the electric beam.
If we go into this first emitter and you'll see that there are other emitters that are not active and
there's two that are.
If we go into blue electric beam and select beam Emitter setup, notice there's this beam start and
beam end.
And you can see that these say user.
And it says a read only value which can be initialized per system and modified externally by the level
by blueprint or by C plus plus.
So we have a beam start and beam end.
These are parameters we can set on this Niagara system.
So if we go back to shock loop when we spawn this system, we can then promote this.
So we can take the return value.
We can promote to a variable local or just a variable.
I'm going to promote to a regular variable and call this beam system and we'll save that.
That way we can remove it later.
And now that we have this beam system, we can set that beam end for it.
We can take the beam system.
And we can call set Niagara variable and we can set it as a vector.
There's vector two, three and four.
I'm going to choose vector three.
And we're going to hook this up and make sure it goes to the return node.
And the variable name is going to be the beam end.
We want to set the beam end.
So beam.
And and we need a value.
Well, for now, I'd just like to see what this looks like when we pass a value in.
So in GA electrocute we're going to pass a value in through the queue parameters.
We'll just use the location and we have the mouse hit location.
Why don't we pass that in as location and in shock loop.
We'll take that location.
I'll go ahead and just promote that to a variable as well.
So take location.
Promote to variable.
And we'll call this mouse hit location.
We'll set that and we'll use it to update that beam parameter.
We'll pass in mouse hit location.
Okay, now this is going to spawn the system.
But what about removing it?
Right.
We need to remove it too.
So we're going to go into on remove.
And since we made beam system a variable we can get it.
It would be safe if we convert it to a validated Get.
And if it's valid then what I'd like to do is destroy it.
So I'm going to take it.
Call destroy component.
It's going to auto deactivate itself.
And then we can go to the return node.
So with that, let's see what happens when we add and remove this gameplay cue.
I'm going to save all.
I'm going to press play.
And there's our lovely beam.
And it stays there.
It sticks around until we release the mouse button.
Isn't that lovely?
Look at that.
It looks great.
Now it looks like it's not going up to the correct location here on the wall.
But remember, the wall is not responding to the visibility channel, so it's going through the wall
there.
Same thing with this.
It's not responding to the visibility channel.
Right.
So if we want to perform a trace that will hit that, we'd have to go and do that separately.
But look at that.
We have a very, very nice looking.
Electric beam.
It doesn't have sound, but we're going to take care of that very soon.
But for now we have the beam and it's looking great.
Excellent.
Awesome job and I'll see you in the next video.