Welcome back.
Now our fireballs for the fire blast ability are using on hit, aren't they?
Now, if we go to actor and open fireball, the aura fireball, we don't have anything here for on hit.
We're just using the inherited on hit function.
And if we go to aura projectile, we can see what that function does on hit right here.
It results in playing a sound, spawning a Niagara system, and stopping the looping sound and setting
a boolean.
Now this is great, but this is sort of the vanilla way to do it.
This is just using gameplay statics and you Niagara function library to play sounds and spawn particles.
What if we want to take advantage of gameplay cues?
Well, gameplay cues are replicated by default, as we know there are PCs, and even though we've upped
our projects RPC limit per net update to ten, well, we still know that our fire blast ability is spawning
12 of these, so 12 is verging on a bit much for all at once, which is why we've erred on the side
of not using gameplay cues, or at least using them sparingly.
And we're not using them here.
But what if you wanted to anyway?
What if you wanted to use a gameplay cue locally without sending an RPC?
Well, we could do that too, so I'd like to show how to do that with on hit and in fact, ability system
components should all have a set of functions that make it easy to handle gameplay cues locally.
So we'll visit that.
But for now, let's talk about how we can execute a local gameplay cue in or a fireball.
Well, we're already calling on hit, we're calling it on the server, and then in destroyed we're calling
it if B hit is false.
Right?
So really we could take our A fireball and override on hit if we make it virtual.
So that's the way I'd like to do this.
Because if we do that we won't have to change anything else.
We just have to execute a gameplay cue, which means we'll have to make one.
But we'll get to that.
For now.
I'm going to make on hit an aura projectile, a virtual function, and then we can override this virtual
function in Aura Fireball.
So I'm going to go to Aura Fireball dot h in the protected section as this is a protected function.
And I'm going to override on hit and now or a fireball can implement its own definition for this.
And whatever we do by the end of it I'm going to set be hit to true, just like we did in aura projectile
right here.
The only difference is the way we're going to handle these things right now.
We want to stop the looping sound component.
Yes.
So I'm going to copy that part and put that in the aura of fireball version.
And of course looping sound component is private.
So if we're going to use looping sound component in a child class that has to be protected as well,
no problem.
We can take looping sound component, we can cut it from the private section and paste it into the protected
section.
And now our fireball should be able to access it, provided that it includes the correct header file.
Well, we can steal that from our projectile that CPP its audio component.
So we can paste that up here and we should be good to go.
All right.
So on head is overridden and we're stopping the looping sound.
But how do we execute a gameplay cue.
Well, first of all we need to know what the gameplay cue tag is because gameplay cues are executed
by tag.
So for this particular gameplay cue that we're going to create for Fire Blast, we can make a gameplay
cue tag by going to our gameplay tags.
I'm going to do that.
We have most of our gameplay cue tags made inside the engine.
In fact, all of them are made that way, but this one we want to use in C Plus plus.
So I'm going to make a native gameplay tag, and I'm going to call this gameplay cue underscore fire
blast.
And we'll go ahead and define Fireblast in our gameplay tags.
I'm just going to copy one of these and go all the way down to the bottom.
Make a comment that says gameplay queue and paste this and we'll use gameplay queue Fireblast.
And it's going to be gameplay.
Q dot.
Fire blast.
And we'll say fire blast gameplay cue tag.
Now that we have that, we can close our gameplay tags.
We're done with it.
And here in on hit, we'd like to execute a gameplay cue locally.
So how are we going to execute a local gameplay cue?
Well, if we search for gameplay cue manager and we and we go to gameplay cue manager dot H, we can
scroll down and see that there are a number of functions that are very useful.
Here are three static functions right here.
We can add, remove or execute gameplay cues locally.
Non replicated.
Now remember adding is for adding a instance gameplay cue, something that you add to an actor, whereas
executing is just executing something that's either static, a gameplay cue, notify, burst, etc..
Now I'd like to make a burst notify, so I'm going to use execute gameplay cue non replicated, which
requires a target, a gameplay cue tag and some parameters.
Now our fireball needs to know the target.
And that target has to have an ability system component.
Either it's the avatar actor or the owner actor and so on.
Now our fireball could have an owner.
If we set it, we could get the ability system component from damage effect params, but we're not really
setting that on clients.
We're setting that on the server when we spawn this thing.
Now, how do we set something that the clients will know about?
Well, the owner of all actors is replicated.
So if we go back to our gameplay ability where we're spawning these fireballs, we can set the owner
there or make sure that we're doing so.
Let's go to Aura Fire Blast and go to where we're spawning these fireballs.
We're setting the damage effect params.
We're even setting the return to actor.
We could also set the owner as well.
We can take fireball and call set owner.
And we can simply use the avatar actor from the actor info if we want that to be the owner.
And if we have this set, the owner on all actors is replicated.
So the fireball is going to know on the client who its owner is.
However, we need to make sure that's a valid pointer just in case on hit gets called before that replication
happens, which is unlikely but possible.
So we're going to check if get owner if that's a valid pointer.
And then we can call that static function on gameplay queue manager execute gameplay queue non replicated.
So we're going to get you gameplay queue manager.
Make sure that we have the header file included for that.
So there it is, gameplay queue manager and we can call execute gameplay queue non replicated passing
in the actor.
We're going to use Get owner the gameplay tag we can use for gameplay tags.
Gameplay queue Fireblast.
Now the third parameter is gameplay cue parameters.
We've seen gameplay cue parameters in the editor and blueprint.
This is just an f gameplay cue parameter struct, so we can make one.
We can make an f gameplay cue parameters called cue params, and I mentioned that I'd like this to be
a burst notify, and the burst notify will spawn particles at the location in the cue parameters, so
we can set cue params dot location and we're inside the fireball.
I'm just going to call get actor location.
And we can pass in those Q params.
Now it looks like I made a typo here.
This is for a gameplay tags.
It should be get dot gameplay q fireblast.
So typing a little too hastily there.
But with that we have our gameplay Q params.
We've set the location on it and we're executing gameplay Q non replicated.
With this we can just compile and make our gameplay Q.
Okay, so we're back.
Now the next thing to do is create a gameplay queue.
So I'm going to go to the ability system.
Gameplay cue notifies folder and create a new one.
So we'll go to blueprint gameplay cue.
Notify.
GCN burst and this will be called GC underscore fireblast.
Let's open up GC Fireblast now because I called it Fireblast.
Look at this gameplay queue tag.
Gameplay queue Fireblast.
How amazing!
Now let's go to our burst effects and click plus for burst particles and let's select one.
Now remember we have an explosion and we have nice fire explosion and fire explosion one I'm going to
use fire explosion.
It's this one here.
So that's going to do.
And now for the burst sounds.
We can add one of these and we have an impact sound.
It's called Firebolt Impact.
And that's what this sounds like.
That's the sound our firebolts have been making.
So now that we have burst particles and we have burst sounds, we can go ahead and test out executing
these gameplay queues locally.
So we'll try on the server in a single player game, I'm going to press two.
There's our gameplay cue executing.
Looks good.
Looks like we leveled up to.
Now I'm going to change the number of players to two and press play.
Boom!
We even knocked aura away.
Pretty exciting.
So that worked on the client.
We can even play as client with a dedicated server, and it doesn't matter which of these we use.
And we get our cues, so we're executing gameplay cues locally.
And this is great because this does not result in any rpcs, as gameplay cues by default are multicast
rpcs.
And that can be really expensive bandwidth wise.
If we're doing this a lot and this particular ability has 12.
12 gameplay cues being executed, but they're executed locally, so no information is sent across the
server.
This is actually really useful, and we now know that the gameplay queue manager has static functions
to execute these to make things easy for us, so use these when you can.
If something's already replicated, use local gameplay cues.
If something is already predicted with a gameplay ability, use local gameplay cues only in the situation
where you're not already replicating something and you need that effect replicated.
Do you want to use a replicated queue in all other cases where you can execute them locally?
All right.
That's going to conclude this video.
Excellent job.
You now have another tool in your tool belt to make your games more optimal, more performant and especially
in multiplayer.
Excellent job.
And I'll see you soon.