Welcome back.
So our widget controller is broadcasting a delegate and we need to bind to that delegate in our widgets
so that we can receive ability info.
Our whole goal here is to show which abilities we have in our HUD.
So I'm going to run in debug mode and we're going to bind to our ability info Delegate.
So we're back in the editor.
Here's our ability info.
This is the stuff that we have exposed to the data asset itself.
Now there's another field we don't see here, and that's the input tag, but that is blueprint read
only so we can access that from within our widgets.
Event Graphs.
Now let's go into one of our widgets that we'd like to receive ability info in.
We're going to go to Blueprints UI and what I'm interested in is in overlay sub widget.
Actually, nope.
It's in spell globes and it's called spell globe.
Our spell globe is going to receive an ability info delegate.
So I'm going to go to graph and as soon as our spell globe has had its widget controller set, we can
bind to some delegates on that widget controller.
So what I want to do is delete those nodes and right click and type event widget controller set.
As soon as the widget controller has been set, then I know that I have a valid widget controller variable
and then I can cast it to the overlay widget controller.
So cast to and I'm going to cast to the blueprint version, BP overlay widget controller.
And I can simply promote that to a variable and I'm going to call it BP overlay widget controller.
Now that's the first thing I'm going to do in widget controller set, and that's not the only thing.
So for that reason, I'm going to make a sequence node.
So dragging off of this, I'm going to type sequence and that will be the first thing we do.
The second thing we do will be to take that BP overlay widget controller and get that ability info delegate.
So I'm going to assign ability info delegate.
Now I have an event that will respond to it and that is going to receive a ability info struct.
And if I drag off and I break the ability info struct I see the four fields, the ability tag, the
input tag, the icon and the material.
So now I can set my globe properties based on these, but I don't want to set it just for any ability
info.
I want to check the input tag.
Why?
Because our widget, if we press play, each one of these globes has its own input tag.
The passive ability globes don't really have an input tag, but we can assign them input tags anyway
to identify them.
We can just call them passive one and two, but LNB, R and B and one through four have input tags,
or at least they should.
So for that reason, our spell globe should have a gameplay tag variable called input tag.
So let's add that to it.
We're going to add a variable called input tag and we're going to change this to a gameplay tag.
And each of these spell globes needs to know what its input tag is and then it can check its input tag
against the info it's receiving.
So how is it going to know what its input tag is?
Well, really the overlay is the only thing that knows that if we go into UI overlay and open up overlay,
we know here what the input tag is.
In fact, actually not even the overlay, but the health mana spells widget is what knows that.
So we can go to sub widget and open health mana spells and the health man spells knows which one is
which.
Right.
So we need to assign those input tags here.
I need to take the first one and just to know which one is which.
I'm going to rename this to spell globe underscore LMB and I'm going to take the next one and rename
this one to spell Globe R&B and take the next one.
This is one.
So I'm going to rename this to spell globe underscore one.
And we'll do two through four.
So there now they have names that we can easily identify them by, and I'm also going to name the passive
ones as well.
I'm going to call this one spell globe underscore passive, underscore one, and then the next one will
be spell globe passive two.
And we'll worry about creating gameplay tags for those later.
But for now I'm going to select each of these and make them variables.
I'm going to hold, shift and just click on each of them.
Make sure it's only those spell globes selected check is variable and go back to the graph.
And now I have variables for each of them.
They're easily identifiable and I'm going to set their input tags so they know which ones they are.
So I'm going to add a function to do that called set spell globe input tags, and I'm going to take
each of them and set their input tags one through four and LMB and R&B.
I'm going to get LMB and R&B first and then get one through.
For.
And I can simply set each of their tags.
So if I drag off and type input tag, I can call set input tag.
And I can use a sequence to set these.
So first we'll get Spell Globe Lab and set its input tag to lab.
So it's going to be input tag dot lab.
Next is R&B.
And, you know, I'm just going to take this setter and duplicate it one, two, three, four, five
more times.
And for R&B, I'm going to set it to R&B.
That'll be the next thing we do.
And next we have spell globe one and that one gets the input tag one.
We'll hook that up.
Next we have spell globe two through four and I'm going to time lapse the rest of this.
Okay.
And just double checking the name of the spell globe with the name of the input tag.
And they all match.
So now we have this function for setting all the input tags.
This can be set right away.
In fact, it can be set before widget controller set.
It can be set in event pre construct.
So I'm going to set spell globe input tags as early as possible.
And now those spell globes should all have their input tags set.
So back to spell globe.
Now that we know by the time this happens, the widget controller has been set, we can check the input
tag against our spell globes input tag.
We can say matches tag, we can do an exact match and check the input tag and we'll have a branch here.
Now, what happens if we do get a match?
Well, we have info.
We have the icon in the background material that we can set here in our globe because we have the background
and the spell icon.
We want to set those.
So we're going to call a function we specifically made for this set icon in background.
These take brushes, so we have to make brushes based on the icon and the material.
If we type make slate brush.
Then we can make one from the image and drag it in.
That's for the icon.
And we can also get a background material and make slate brush.
And use that as the image to.
And so now we have a way to set the abilities, icon and background image based on the ability info
that we receive.
And this can all be collapsed to a function.
And we can call it receive ability info.
So now we have a nice struct that receives that info from our widget controller and we should now fingers
crossed, see the ability.
And we don't.
And I think I know why.
Because our firebolt ability doesn't have an ability tag.
So in blueprints ability system or a abilities fire firebolt Firebolt.
Our ability tags have nothing there because we never actually gave it the abilities.
Fire firebolt ability.
Now that that's set, now we know when we perform the lookup, we can identify it because we're looking
for abilities that have that tag if we press play now.
Still nothing.
Let's go to ability info.
We do have the abilities fire Firebolt.
We don't know if our widget controller is being set for the spell globe.
In fact I believe it is not.
So that's something we have to do as well.
Now that's something we have to do after the widget controller has been set here as our health mana
spells is going to set the widget controller for its spell globes and those globes are going to share
the same widget controller.
So we actually need to create a function here and we're going to call this set globe widget controllers.
And this has to actually call set widget controller on all of our Globes.
So we're going to get that LMB first and call set widget controller.
And hook this up and pass in widget controller.
So we're going to set it to.
This widgets widget controller.
And the cool thing here is we can actually pass in all of our spell globes into this function call.
So using that trick with one node, we can call it multiple times by passing in multiple targets.
So we'll get the LMB, we'll get the R&B, pass that in and one through four.
And pass each of those in.
So now they'll all have their widget controllers set.
Now, it's very, very important that all of these have their input tags set before their widget controllers
because in the spell globe, we're checking our own input tag.
The input tag for the spell globe is checked, so that needs to be set first.
Luckily, we're setting it really early on.
We're setting it up here in event pre construct.
So it might even be worth having a comment here that says input tags must be set before widget controllers
are set on the spell globes and then widget controllers can be set set globe widget controllers, we
can call that here.
And then once that happens, the spell globes will have their widget controller set events.
Then they can bind to the ability info delegate.
So now we should be able to press play and sure enough, our left mouse button globe has our firebolt
spell and none of the others do because they don't match any input tags that are broadcast.
Okay, so that is great.
But there's one last thing to take care of, and that's multiplayer.
Let's go ahead and change the number of players to two and press play.
And I'm going to take my client here and notice the client does not have that icon, so why not?
Well, that all comes back to I'm going to close the editor.
Our ability system component broadcasting that delegate when it gives abilities, it's broadcasting
our abilities given delegate in add character abilities.
But this is only done on the server.
So we need a way to broadcast it on clients as well.
And there's a nice, easy way to do that.
You see, once our abilities have been given, then the ability system components, activatable abilities,
container replicates.
It's a replicated variable.
In fact, if we search for Activatable all.
Abilities.
And here's what I find.
Git activatable abilities if I go to its definition, here's.
Activatable abilities.
And if I go to its declaration or usages, we see here that it's replicated using en rep.
Activatable abilities or en rep activate abilities.
Now if we search for this, we see that it's a virtual rep notify.
So this gets called in response to our activatable abilities replicating.
So after we've called give abilities, this is going to replicate.
And not only that, it's going to contain the ability specs of our newly given abilities so we can override
en rep, activate abilities in our ability system component.
And this is a protected function.
So let's override it and are protected section in our ability system component virtual void en rep activate
abilities.
Let's go ahead and generate the definition.
We'll let it call super and we'll also do what we want to make a broadcast.
What do we want to broadcast?
Well, that's going to be the abilities given delegate.
We have to broadcast it and we have to pass in this.
And not only are we going to do that, but we don't want to broadcast it every time this replicates.
We want to do this only the first time we've given abilities.
So what we'll do is check, if not be startup abilities given.
Now we only set this on the server and it's not replicated.
So down here on the client it will be false the first time and if it's false, we'll set it to true
be startup abilities given equals true.
And that way every time this activatable abilities replicates, we won't be broadcasting the delegate
every time, just the first time.
So now that we're broadcasting it on the client, we can actually test this in multiplayer and see if
we can see that fireball icon on the client.
Okay.
So back in the editor.
Moment of truth.
I have two players.
Let's press play.
And on the client, sure enough, we see our ability icon.
And it's assigned to our left mouse button.
Now, the really magical thing about this, this is really cool because we have a dynamic system here
that is extremely well coded.
Why?
Well, let's go to our GA firebolt and take a look at its input tag.
Start up input tag.
This is something we created and change it to right mouse button, R&B and press play.
Check it out.
Our system is so robust, it already handles it and we can't fire our ability with the left mouse button
anymore.
We have to use the right mouse button.
How cool is that?
So when you code things well from the start, then expanding the system becomes relatively easy.
As everything is in place, everything just works out of the box because you took the extra effort to
code it well.
I mean, this is so nice.
We can go into our firebolt and change this to input tag dot one and if we press play, it's now in
one and we have to press the one key in order to launch.
The one key actually works to launch a firebolt.
So pretty cool.
I'm going to set it back to left mouse button.
But the great thing about this is it's so robust that we can change a given abilities input tag at runtime
as this variable is not what we would change, we would actually change its dynamic ability tags on
the ability spec and our activatable abilities.
And if we change that and removed the old input tag from it, then we could reassign abilities at runtime.
That's exactly what we're going to do.
But we need to make a HUD with buttons that can allow us to do that and all of that in time.
We'll get to that.
But for now, we have a great milestone under our belts.
We now have the ability to show our start up abilities in our HUD, which is really nice.
And when we start creating more abilities, we'll be able to see those here and we'll get to all that.
But in the meantime we have this exp bar to take care of.
So exp is one of the next things that we're going to implement so our character can start to level up.
So really exciting stuff.
Excellent.
Excellent job.
And I'll see you in the next video.