Welcome back.
It's time for your next quest.
Now we're going to make the Attribute menu widget controller.
We need to actually construct one of these, and that's going to be the task you have and do it in the
Aura HUD.
Look at how we did this for overlay Widget controller to see all the steps involved and you're going
to add a static blueprint, pure function to get this widget controller in our new blueprint function
library.
And now we'll have a nice, easy to use blueprint pure function that we can call inside of our attribute
menu widget and it can set its own widget controller.
Now if you get this far on your own, see if you can try to verify that everything is working.
Print something to the screen, do what you like, but make sure that this works.
And if you get stuck, don't worry, we can just do it all together.
So pause the video and conquer this quest now.
Okay, we're ready to construct an attribute menu widget controller.
And there are a number of steps, which is why it's important to look at how we've done this already
for the overlay widget controller.
So I'd like to go to our Aura HUD and open its header file just to kind of see exactly what we need
here.
Now we see that we had an overlay widget class that's a subclass of we needed that so we could construct
a new widget.
We also have the overlay widget controller variable and the overlay widget controller class.
So two of these are classes, those we set in the blueprint and the overlay widget controller is the
controller that we store.
Now I see up here that we have the overlay widget itself up in the public section.
I don't really see any reason for it to be public unless we're accessing it directly somewhere.
But we can find out really quickly by dragging it down into private and compiling.
We'll get a nice compiler error if we're attempting to access it directly in some other class.
So let's see what our compiler says.
It says we're fine so we can keep that private, no problem.
And we have our overlay widget and overlay widget class as well as our overlay widget controller and
overlay widget controller class.
Now we don't need to construct the attribute menu here in C plus plus we're already doing that from
the overlay blueprint.
All we need is the ability for the aura HUD to construct a widget controller.
For that, we need the widget controller variable that the aura HUD will store and the class that we'll
need to use to construct that widget controller.
So here's how we'll do it.
We'll make a T object pointer of type u attribute menu widget controller.
We'll forward declare that.
So we'll add that forward declaration up there at the top and this pointer will be called attribute
menu widget controller.
And this will store the actual attribute menu widget controller.
We'll make it U property without exposure and then we can have the class.
So it'll be a subclass of with the same type u attribute menu widget controller.
That way we can set this in the blueprint and this will be called attribute menu Widget Controller class.
This one we do want to be able to edit from the blueprint.
We'll make it edit anywhere.
Edit Defaults only would also work here and now we need a function to construct our widget controller.
The attribute menu widget controller and this is going to be a getter for that variable that will require
widget controller params.
So just like git overlay widget controller, we're going to make a getter for our attribute menu widget
controller that returns a pointer to one, so it'll return a u attribute menu widget controller pointer
called get attribute menu widget controller which will take a const reference to some widget controller
params.
We can copy that from the overlay widget controller getter and we can generate the definition and this
will be very similar to get overlay widget controller.
We're first going to check if attribute menu widget controller is null.
So if attribute menu widget controller equals a null pointer, that's when we create the new one.
Otherwise we can return attribute menu widget controller.
So just like get overlay widget controller, we're going to create one using new object and the attribute
menu widget controller class that we're going to set in the Aura HUD blueprint.
So we'll say attribute menu widget controller equals new object of type U attribute menu Widget controller.
We're going to want to include that.
Make sure you don't forget, right or did it for me.
And then this takes in an outer object and a class to construct.
So that's going to be our attribute Menu Widget Controller class.
So after we've created one of these with new object, we'll make some room so we can see.
We then want to set its widget controller params using the WC params.
So we're going to say attribute menu, widget controller, set widget controller params passing in wc
params and then we can have it bind its callbacks to dependencies.
So we'll say attribute menu, widget controller and call bind callbacks to dependencies, just like
we're doing with the overlay widget controller.
And at that point we can return the attribute menu widget controller.
Now as soon as we exit this if statement, we return the attribute menu widget controller anyway, so
we really don't need that return there.
It's redundant.
Same thing with git overlay widget controller.
This return is redundant isn't it?
So we're going to return these widget controllers by the time we reach the end anyway, whether it's
a null pointer or not.
So now our aura HUD has the getter for this.
Now to make things easy, we're going to make a blueprint pure function in our new blueprint function
library or Aura ability system library.
And it will be a getter for our attribute menu widget controller.
So this will be static.
It'll return a new attribute menu widget controller.
We'll forward declare, it'll return a pointer and we'll call this get attribute menu widget controller
and it'll take a world context object.
So that's a const uobject pointer like so and we'll give it the same exact blueprint, pure and category
as our other function there it'll be in category widget controller and we can create this definition.
And what's it going to do?
Well, basically, it's going to do what this other function is doing.
Let's copy the whole thing and paste it there.
There's a key difference though.
This is for the attribute menu, widget controller and not the overlay widget controller.
So the only difference is we're going to change this function call to get attribute menu widget controller.
And it looks like writer didn't quite autocomplete that how I wanted to let's clean that up there.
So just like the other function we get the player controller, we get the aura HUD, we get the player
state, we get the ability system component and the attribute set.
We create widget controller params and call the getter and return it.
So now we have this function and our attribute menu could call this function from its own blueprint
and set its own widget controller.
Why don't we test that out?
Let's go ahead and run.
We'll run it in debug mode.
Okay, I'm going to go ahead and click open and get my attribute menu open.
And I'm going to open the graph here.
And I'd like to do this an event construct.
So I'm going to right click and let's see if we get our get attribute menu widget controller.
There it is.
Now here's part of the challenge that you may not have quite remembered all the details and nuances
on.
If we call this function our aura.
HUD is going to attempt to construct a new attribute menu widget controller, right?
And it's going to try to do that with attribute menu widget controller class.
This is added anywhere.
We should have set that on the HUD.
Now if you forgot that, that's okay, but that is an important step.
So that's something that you may have gotten tripped up on.
So we need to set that on the HUD class on the blueprint.
And before we do that, I'd like to make a blueprint of the Attribute Menu widget Controller class in
our UI folder in UI Widget Controller.
I'm going to make that blueprint here.
So I'm going to make a new blueprint search for Attribute menu widget Controller.
And I don't see it here.
And if you got stuck at this part, here's the solution to that.
Let's go ahead and first close the editor saving all and going to our attribute menu widget controller
in our public folder and UI widget controller.
We'll get that open there.
And let's also open overlay widget controller and take a look at its declaration here.
Why were we able to create a blueprint of overlay widget controller but not attribute menu widget controller
because it's got blueprint able and it's use class.
And we can also use blueprint type to make sure that this type can be used in blueprint in the event
graph.
So I'm going to go ahead and close overlay widget controller and in attribute menu widget controller,
we'll paste in blueprint type and blueprint label here.
So now we should be able to make a blueprint of this type.
So it's little things like this that are easily forgettable.
Sometimes you can get stuck on them and the more times you get stuck, the less likely you are to get
stuck in the future.
So you'll, one by one start to remember all these details with experience.
Okay, I'm going to go ahead and open those asset editors and right next to overlay Widget Controllers
Blueprint, we'll make a new Blueprint class.
I'm going to search for attribute menu and there it is Attribute Menu Widget Controller.
Now we see it.
Now we can make a blueprint based on it and this will be BP underscore attribute menu Widget Controller.
Now we have this blueprint and now we can set it on the HUD by going to UI, HUD, BP Aura, HUD and
there's attribute menu widget controller class.
We're going to set that to the blueprint.
Now, that's what will be constructed when we call the function.
Where is it get attribute menu, widget controller, and we're going to pass in self for the world context
object.
And now we'll have a widget controller.
What are we going to do with it?
We'd like the attribute menu to set its own widget controller.
So set widget controller.
Luckily we made that blueprint callable and we can pass this in as the widget controller like so.
Now, the last part was to prove that this was working.
Right.
We want to see if this works and when any of our Ora user widgets has its widget controller.
Set that setter for set Widget controller calls the blueprint implementable event widget controller
set so we can prove that our widget controller has been set here by implementing this.
And we can even do a print string here and print the name of our widget controller.
So we're going to get our widget controller variable.
Which is just a you object, but we can get the object name.
Get object name.
Now I said it's just a you object.
What I mean is widget controller is a you object pointer.
It points to the object that we set it to here and set widget controller.
So it points to an attribute menu widget controller object.
But the widget controller pointer right on or a user widget is a you object pointer.
But we should see the correct class name if we press play first, I'm going to save.
All right.
Always save all for fear of crashes, press play, click on attributes.
And there's our log message.
It shows up for just a second attribute Menu Widget Controller.
It's being set.
Awesome.
It's working as expected because as soon as Attribute Menu widget controller is created, we get the
menu widget controller using our new aura ability system library function and the HUD is only constructing
a widget controller the first time.
Every subsequent time we call this, we're getting the already constructed widget controller so we don't
construct a new one every time.
Perfect.
All right.
So that was a bigger challenge, wasn't it?
Some of these challenges are getting a little bit more challenging, a little more ambitious, a little
larger, because at this point in time, you're capable.
I believe you are capable of more impressive challenges.
You're capable of more impressive feats because, well, you've gotten this far already and you're now
developing the skills that a game developer needs to have.
You need to do something similar to what you've already done.
Well, you go and look at what you've done before and use that as an example for yourself, right?
We wanted to create an attribute menu widget controller.
We've already created an overlay widget controller.
So we look at the way we did it before and now follow that pattern, making adjustments as we need to,
Right?
That is a valuable skill and I want to get you very good at doing that because that's what's going to
make it easier for you to implement your own ideas and ideas that your team is going to give to you
to implement.
So I really want you to pat yourself on the shoulder for this one.
This was a great challenge to even attempt.
I don't even care if you got through it all on your own.
I just care that you gave it a try.
And then as we went through it together, if you got stumped on anything, I want you to now understand
why you got stumped.
That's the most important part.
The challenges are not win or lose.
There's no winning or losing.
It's just give it a try.
Kind of assess how far you can get and then learn from doing these things together.
Where you got stumped, why you got stumped and why it didn't work and so on.
So excellent job.
This is a great milestone that we've accomplished and we're very, very close to being able to actually
broadcast data to our attribute menu because now our attribute menu has a widget controller, right?
And our widget controller has the ability to bind its callbacks to dependencies.
In fact, we're calling bind callbacks to dependencies.
And when we create the attribute menu widget controller because of that, at this point in time we can
bind our callbacks to our dependencies.
And in fact we have the four key variables.
We have the player state player, controller, ability, system component and attribute set at this
point in time.
And that means we're all set up and ready.
Attribute Menu Widget Controller.
If I can open the CPP file right here in bind callbacks to dependencies has all the info it needs,
it can start binding to any kind of delegates in our ability system anywhere else in our game and it
can start broadcasting things to our attribute menu and we're going to start learning how to do this
in a very nice, modular, sophisticated and robust way in the videos to come.
So I hope you're excited because we're going to create a very nice attribute menu widget system architecture.
So excellent job and I'll see you in the next video.