Welcome back.
It's now time to start working on our electrocute ability.
Now our electrocute gameplay ability is going to be really cool.
It's one of my favorites that I've created for this course.
And I'm going to show you just a couple things before we get started.
For one, let's go to effects.
And look in the shock folder and open in s electric beam.
Now here is an electric beam Niagara system.
And this beam can have its start and end locations changed, and it will be dynamic.
We're going to be using this beam to shoot a beam of electricity from Aura's staff.
So by the end of this, it's going to look really cool.
So that's the goal for now is to be able to activate this ability.
In other words, we're going to need first of all to have that ability.
So I'm just going to level up real quick.
And I'm going to have to reconfigure things so that I can easily test this.
But for now, I'm just going to get rid of these threats.
Just a moment.
Got to slay some enemies real quick.
I'm really going to have to.
Fix this so that I can.
Launch these fireballs a little bit closer.
Okay.
Sorry about that.
Let's level up our electrocute ability.
We'll spend a point on it, and we'll equip it.
Okay, I really should just add this to my abilities that I start off with now.
Activating this requires the right mouse button, and so far it does nothing.
But my goal here is to hold the right mouse button, and I'd like aura to play a start animation like
start casting the spell and then be in a loop as we're holding the mouse button down and stay in that
electrocute loop or shock loop until I release the mouse button, and then she can stop.
So the next thing I'm going to take a look at is in assets.
Characters, aura in animations go into abilities and we can see we have a couple of animations here.
We have Cast Shock and this is a really quick animation.
It just starts the cast and it goes all the way to this part and that's it.
And then we have cast Shock Loop that looks like this.
So I'd like to stay in this shock loop while we're holding that mouse button down or whatever input
we're using.
I'd like aura to stay in this loop during that time.
In other words, there can be a boolean on aura that we can set, and aura can be in this animation
when that boolean is set.
So the first thing we can do is we can go into her animation blueprint.
So in character Aura app aura, we can add another state.
Here I'm going to move to an air down here and get that out of the way.
Because if I'm an idol, I'm going to go into that shock loop.
So cast shock loop here and we need a condition.
So here in the event graph we can get that.
And because we have a character, if a character has that boolean, we can get it here.
So I'm going to give or a character's blueprint a shock loop.
And this can be a boolean.
So we'll call this.
We'll call it in shock loop and I'll check the eye icon, make it instance editable.
And from here in the Animation blueprint I'm going to add one pin to the sequence.
And we're going to get our character.
It's got to be the BP version.
We're going to type in shock loop.
We're going to get that and we'll just use this.
Promote it to a variable in shock loop.
And we'll store that here.
And we can use that in our state machine.
We can have a transition into cast shock loop using in shock loop.
And the transition back out is going to be the opposite.
Not in shock loop.
So get in shock loop.
Not boolean.
And then we can hook that in.
Okay.
So that's the first step is now aura is capable of having that animation played.
Now we also need a way to set in shock loop.
And that means we should have an interface function to do that.
So what I can do is I can go into my public folder, into interaction, into combat interface, and
we can add a function that we can implement right there in the blueprint.
It could be a blueprint implementable event.
And we'll also make it blueprint callable.
So we'll call this void set in shock loop with a bool input be in.
We'll just call it in loop because the boolean in blueprint is called in shock loop.
And we'll make it blueprint implementable event blueprint callable.
So we don't have to implement it here in C plus plus okay.
So we have that.
Next time we compile we'll have it here in the editor.
And that's step one.
And after this we can start looking into our gameplay ability.
So let's go to blueprints ability system aura abilities and lightning.
And we have this gameplay ability electrocute which is right now pretty simple.
I'm going to delete on an ability.
It tends to get in the way.
And in fact we can just delete everything here because things are going to be a little bit different.
And the first thing I want to do is find out how we can know in this gameplay ability when we've released
our input.
So if we're holding the input down and we release it, we want to be able to do something well for that
purpose.
There's a gameplay task and it's called wait input release.
And notice there's a wait input press two.
So we have both.
Now if I use wait input release, if I hook this up, you would expect on release to be executed.
When we release the input right.
We can use a print string for that.
And we can say electrocute input release.
And notice there's a test already released as well.
So if it was already released by the time we hit this, then we can get on release.
But let's see what happens if we activate the ability now.
I don't want to have to level up.
I also don't want to have to run away from the enemies.
So for testing purposes, once again I'm moving my nav mesh bounds volume out of the way.
Up to about there.
In addition, I'm going to just go to a character.
And in startup abilities, I'm going to add a electrocute.
And since we're doing that, we have to give a electrocute a input tag.
We have a start up input tag here.
I'm going to give it R&B for the right mouse button.
And if we press play now, we have that ability and I can right click and activate it.
Now there's no confirmation that we're activating the ability.
So just to show that we're actually activating it, I'm going to print a yellow string that says electrocute
activated.
So now I can press play and right click and electrocute.
Activated works at least once.
We can't do it again unless we end the ability.
So we can call end ability, at least right here.
But notice that we didn't get our electrocute input released.
I'm going to make that red.
We didn't get that.
So how come this doesn't work?
We'd expect it to work.
It doesn't.
Well, there's a step that we have to go through to make sure that wait input release works.
So we have to do that in C plus plus.
So I'm going to save all close out.
And we're going to go into our ability system component in the private folder.
Let's open the cpp file.
So here's Ora ability system component.
And I'm going to search for input tag.
And we have ability input tag held and released right now.
In order for weight input release to work, we have to call a function on the ability system component.
And that function is called Invoke Replicated Event.
And by the way, our ability should be active if we're even doing this.
If we're not, there's really no need to pass the input along to the ability if it's not even active.
So here in the if statement, I'm going to place an and and say and ability spec dot is active.
So if so we're going to pass that input active status along and then call invoke replicated event.
Now this needs an event type.
And it does what it sounds like.
It sends data to the server telling it that we're doing something.
And what does the server interpret that as well.
It depends on what we pass in here.
Now this is an ability generic replicated event.
And there's a bunch of options here.
But we can use input pressed and input released.
So we can tell the server look we're releasing input here.
Now the next input is the ability spec handle.
So we need to take the ability spec and get the handle from it.
That's easy ability spec dot handle.
Now this is a predicted action and it needs the original prediction key.
Remember that's the prediction key for when this ability was first activated.
Or I should say last activated the last time it was activated.
We had that prediction key.
And we can get that from the ability spec.
From activation info.
It contains that.
And in fact here's the function for it.
Get activation prediction key.
So now that we're invoking a replicated event for ability input tag released, we can now use wait input
release.
And if we want to use wait input press we got to do the same thing.
So right here in ability input tag held we're doing a couple of things right.
We're checking if the ability is not active.
And we try activate ability.
If we like we can invoke a replicated event if it is active.
Of course we don't really want to do this every frame.
So instead of having just a held and released, we could also have a pressed simply for invoking replicated
events.
And that way it only happens once when pressed.
So if we go into the player controller or a player controller.
We know when ability input is pressed.
That's right here.
So we can let the server know here that input has been pressed for the first time, and it won't be
spammed, because this is just a one off here.
So we can make an ability input tag pressed.
It'll be just like the held and released versions.
So here it is.
We can create the definition for it, and we'll do the same thing that held is doing pretty much.
Minus a couple things.
We'll make sure the input tag is valid.
We'll get our activatable abilities.
We'll find the one that has this input tag.
By the way, in all of these, we could just break out of the loop when we're done.
Once we find the ability with the tag, we can go ahead and pass along the input press status here and
we can check if the ability spec is active when we press it.
The only point in invoking a replicated event for input pressed is if we're pressing input while the
ability is active.
So if it is, we'll go ahead and invoke the replicated event just like we did here.
So we'll say invoke replicated event E ability generic replicated event.
We're going to choose input pressed.
We need to pass in the ability spec handle.
So get ability spec dot handle.
And we also need that activation prediction key.
So that's on the ability spec activation info.
So here's the spec.
Here's activation info.
And then here's get activation prediction key.
And there we go.
We know that ability input tag pressed is only called once every time we click.
So we can check if git ask.
Then get ASC ability input tag.
Pressed.
And we can pass in the input tag.
So now we're sending replicated events for when we press and release and ability tasks like wait, input,
press and release should work.
Now let's test that.
All right, let's get that ability back open.
And first we'll try the release.
So I'm going to right click.
And as soon as I release boom we get our print string and it's pink and we can see it and it's great.
Now let's try the pressed version.
And for that, as soon as we release I'm going to start a timer.
Let's do a delay, actually.
They're easier.
And we'll wait for 10s.
And then we'll end the ability.
But here's the thing.
Immediately after weight input release, I'm also going to use a weight input press.
And on press, I'm going to print a different string.
And it's going to say input press and this can be a different color.
Let's make it purple.
So we can press the input.
We'll see the yellow.
And then when we release, we should see the pink.
And when we press again, at least until the ability is ended, we should keep getting the purple.
So let's see if that works.
I'm going to right click release and press.
Now I can only do it once.
And let's check test already.
Press.
Notice that I got it right away because it was already pressed.
It was pressed right away.
So if test already pressed is checked.
We get that message immediately.
Same goes for weight input release, but we would just see the same result there as it was not released
yet.
But this is how we can wait for input to be pressed and released.
And we can just prove to ourselves that this ability input tag pressed is not being spammed.
And we're not spamming a replicated event here by placing a couple of breakpoints there.
And we can press play and we'll see that it isn't until I click that we get ability input tag pressed.
So here we are.
No break points.
And then I'll go ahead and click.
And we get it.
So it's a one off.
So no spamming there.
Okay, so now we know how to wait for input, press and release.
This is great because this is going to be pivotal for us in our electrocute ability.
All right.
So before we wrap up and move on, I'd like to do something about those fireballs being a little too
hard to use at close range.
And speaking of those fireballs, there's another thing I noticed.
It's a little hard to reproduce, but if you can manage to get a projectile that does not explode,
which with homing projectiles, it can happen.
They can float around in the air there.
I noticed that when that happens, after their lifespan has elapsed, the sound will keep going and
we can fix that by coming into the on hit and make sure to destroy the looping sound component on hit
so we can call destroy component on it.
But also we need to do that and destroy it as well.
So we'll just go ahead and stop and destroy the sound component here regardless of whether we got a
hit or not.
Because if the projectile dies due to its lifespan expiring, we'll go ahead and just stop that looping
sound then too.
Okay, so that's the first problem.
And the other is of course, being a little bit too difficult to hit those enemies when they're close.
Now that's something we can easily fix if we go into GA Firebolt, because we made homing acceleration
min and max parameters, and we can make these a lot higher, say 6000 507,800.
This means those projectiles will arc onto their target location much faster.
They're much less likely to overshoot.
So if we go close.
Well, I'm getting knocked back like crazy, but we can see that it's a lot easier to hit them when
close.
Oh, I died.
So yeah, that's a lot better.
Yes.
Much better.
And we can test with a little upgrade as well.
And of course these are not responding.
These don't block the visibility channel.
They do block the projectile.
And if we try to fire a projectile out into space, well, that's not actually going to work because
these blocking volumes don't block the visibility channel.
But if they did, we could fire a projectile out into space.
So if we just highlight those blocking volumes and get their collision settings open.
Their presets are set to invisible wall.
If we set it to custom and we block the visibility channel, we're going to ignore the camera as well.
Then we should be able to go ahead and click on them.
We just have to be careful because this one here might block the visibility channel if we're out here.
Yeah.
So it's blocking the visibility channel here.
And this is actually a good opportunity to see when they expire and make sure that sound goes away.
So let's listen.
Excellent.
So we took care of the sound problem.
But the problem now is that when we click, since this is blocking the visibility channel, we're clicking
and getting a hit here, we can prove that by moving this down and out of the way.
And now if I shift, click.
Now it's behaving as expected.
So we have an issue, right?
We want our line trace under the cursor to work.
Right.
We want to be able to do this.
Of course, we're actually making a homing target right there, too.
So maybe that's not what we want.
I suppose a good compromise would be to make these also block the projectile channel, or at least overlap
with them and generate overlap events.
At least then our projectiles would explode.
Right, like an invisible wall.
That's probably the best solution here.
And of course, just not have one here.
I think we're going to have to have a distinction between the blocking volume that's going to be in
front of the camera.
In other words, the one on this side, every time we place one in a dungeon and the others.
This one can just not block the visibility channel.
So we'll take visibility and ignore it.
But it can block the other channels such as -- and world static world dynamic, so it'll prevent these
enemies from flying out of it, including aura herself.
But it will not block visibility, so we won't be able to accidentally launch a fireball up there.
And that's okay, because we're never actually going to be facing the other direction, right?
This is like the side on a movie set that nobody in the audience sees.
So that's okay if this one doesn't block visibility, I think that's the best way to go.
And we'll just keep it so that if we launch something out there, well, then we'll just go ahead and
explode that projectile.
The only alternative would be to have a second blocking volume way, way out.
That would block the visibility and projectile channel.
And that would be only for our hits under the cursor for launching projectiles.
And then these ones closer in would be for the enemies and anything that's flying around that had been
launched.
I'd rather not go through the trouble.
I think I'm okay with projectiles exploding on the invisible walls, and that's how I'm going to handle
it.
I'm also going to take these blocking volumes and just put them in their own folder.
So I'm going to move to and create a new folder and rename the folder.
Two blocking volumes.
That'll make things a little bit easier to organize.
So we have the dungeon meshes, we have the blocking volumes, we have the lighting.
Here's all of our enemies and then a few miscellaneous things.
And that makes the level a little bit more manageable.
All right.
Excellent job.
And I'll see you in the next video.