So now that we have an attribute menu, we want to show the values of our attributes.
And for that matter, we want our attribute names to be shown and any other information associated with
those attributes.
Perhaps we'd like to hover over the name and get a tooltip or something like that.
So we need a way to get the data to the attribute menu.
Now, following our architecture pattern, this means we'll need a widget controller so we can have
a widget controller dedicated to the attribute menu.
We can call this attribute menu widget controller.
And then as changes occur in the model, for example, our Ability system component broadcasts a new
change for one of our attributes.
Our widget controller can subscribe to those ability system delegates and then broadcast those changes
to the widget controller.
Now we have a lot of attributes.
So what's the best approach here?
Do we simply subscribe to delegates for all of the attributes and respond to those and then create a
new delegate for each attribute and broadcast it to widgets which subscribe to those attribute change
delegates and just continue this pattern every time we add new attributes.
This is a sort of brute force approach, but if we do that, we're going to have a lot of different
delegates and broadcasts.
When strength changes, the Ability system broadcasts it.
Our widget controller receives that and broadcasts its own delegate on strength changed, for example,
and then the appropriate widget binds to that and displays the value.
And when resilience changes, that results in a delegate broadcast received by our widget controller,
which broadcasts a delegate of its own and so on.
Now this approach is okay.
It does work and it is actually pretty efficient because only the strength row in our attribute menu
is the widget that binds to the on strength change delegate.
No other widgets bind to that delegate, so when it broadcasts, only one widget will respond to it.
But this is not the most scalable pattern because if we add new attributes to our attribute set, then
we have to actively go into the widget controller and bind some kind of callback or lambda to the delegate
broadcast when that new attribute changes and then declare a new delegate to broadcast from the widget
controller and broadcast that to the widgets.
So in other words, just to add a new attribute results in changing quite a lot of code, not only in
the widget controller, but perhaps on the widget blueprint side as well.
And that makes it very hard to maintain and expand.
Now consider the possibility that even though the ability system makes a broadcast, when any given
attribute changes, our widget controller could have its code designed a little bit more cleverly.
Let's say we receive the broadcast for when an attribute changes and instead of broadcasting one specific
delegate for when the corresponding attribute changes, we broadcast one generic delegate on attribute
changed and on attribute change can broadcast a number of pieces of information.
Let's say each attribute is associated with a gameplay tag, so when the strength attribute changes,
our widget controller will simply broadcast one delegate on attribute changed and pass through the gameplay
tag associated with strength and any other information the widget is going to need, such as the name
of the attribute and its value.
Perhaps a description for a tooltip or whatever.
In other words, we can send multiple pieces of information.
We can even package them up into a nice, neat little struct that gets broadcast up to the widget side
and the widget can check that gameplay tag and do what it needs.
Perhaps each row in the attribute menu can have its own tag assigned to it and they can all receive
this delegate and check to see if it's their particular tag that was broadcast.
And if it is, they can take the data from that struct and update themselves.
So it might be appealing to create this struct, something like an aura attribute info struct that we
can send up to the widgets and each widget will be assigned its own gameplay tag that corresponds to
an attribute for example.
So this is a good way to do it.
And the.
Flow of information will proceed as follows.
We have our widget controller which will bind to delegates broadcast from the ability system.
When an attribute changes, the widget controller will know about it.
Then the widget controller can take that attribute and try to figure out what the gameplay tag is that
is associated with that attribute.
That's something we're going to have to figure out how to do.
But once our widget controller is smart enough to make that connection, we can then perform some kind
of lookup to find the correct struct that has the right attribute, name, attribute, description and
so on.
So we can send that data up to the widgets.
If this is data driven, then we can have some kind of either data table or perhaps a data asset that
can package up all the data associated with any given attribute.
Gameplay tag.
Now we've seen how to use data tables and lookup info from those, but so far we haven't used any data
assets.
Data assets are nice because they can look things up not only by name but by anything we'd like, such
as a gameplay tag so we can make a data asset class, call it you attribute info and we can program
the capability of this attribute info data asset to receive a gameplay tag and return a struct that
contains all the information associated with that tag.
Now, once we have that information, we can then make the broadcast up to the widget side and the widgets
can each receive it and check to see if it contains the correct tag so it can update itself with information.
So this means we need to do a few things.
First, we need a widget controller for the attribute menu set up to receive broadcasts from the ability
system when attributes change.
Next, when we receive that attribute, we need a way to figure out what the correct gameplay tag is
associated with that attribute.
We need to map these two together somehow, and we'd also like a way to reference these gameplay tags
in Cplusplus.
Now we've seen one way to do this.
We can use request gameplay tag which takes in an fname where we specify the tag we'd like.
So we're basically asking the gameplay tag manager for a tag structure, giving it the name to look
up and if the gameplay tag manager has that tag, then request gameplay tag will return that for us.
Now this is error prone and I don't like having to have an F name where we type out the string name
of a given gameplay tag.
I'd like a better approach to this.
Some kind of class that stores a global source of tag variables that we can access.
So that's something we'll need to look into.
Now third, we need a data asset capable of receiving gameplay tags and returning our aura attribute
info struct that we need to make.
So that way, as soon as we know the tag for a given attribute, our data asset can give us all the
data we need to send up to our widgets and that will be our last step once we have that struct, that's
to broadcast it up to widgets and our widgets can check their own gameplay tags against the struct gameplay
tag sent up and then they can update themselves.
So this means we have a few next steps for our attribute menu.
First, we need to create our secondary attribute gameplay tags and we want a way to handle tags better
in cplusplus rather than calling request gameplay tag all over the place.
We want some kind of centralized source of gameplay tag variables on the Cplusplus side.
We also need a attribute info data asset that can store these structs and allow us to perform a lookup
based on gameplay tag to find the attribute info we need so we can broadcast it up to widgets.
We also want to create that struct.
We'll make an aura attribute info struct that contains all the information we want to send up to widgets.
And then we need to fill in that data asset with those attribute info structs for each attribute.
And of course we need to create our widget controller for the attribute menu.
This widget controller will tie everything together as it's going to listen to broadcasts made from
the ability system and it can perform its lookup from the data asset attribute info retrieving the attribute
info struct that it can then broadcast up to the widget side.
So now that we know our next steps, let's get started constructing this robust and elegant system.