Welcome back.
So now that we have a pretty nice HUD, it's time that we start actually sending information up to it
from the C plus plus side of things.
And I'd like to start with initializing our spell globes with the spells we have equipped.
Now, so far, we just have one offensive spell equipped.
We don't have any passive spells, so we need to start thinking about a way to send data to this widget.
Now, an example of something like this that we can look at is our attribute menu, because our attribute
menu has widgets, each of which are identified with gameplay tags, and we're sending data up to widgets
via the attribute menu widget controller, and we're sending it in a nicely packaged little struct that
contains information about that given attribute.
We're able to do this because we have a data asset.
If we go to blueprints ability system data, we'll see that we have this attribute info and attribute
info has an array and each element in the array is identified by an attribute tag and it contains information,
the attribute name, the attribute description, and so on.
Now we can follow this same pattern for our abilities.
Our abilities can be identified by their ability tag.
They can also have other information that we can send to widgets which can then fill in what they need
to fill in.
In the case of our spell globes, we're going to need an icon and a background that we can fill in here
based on ability information.
So what we're going to need is our own data asset for ability info and just like attribute info, we
can create a struct to store that info for each element in our array that we'll put in there.
Now we can go into our ability system folder into data and take a look at attribute info.
Notice here we have a struct for the data to send up to our widgets and we have a array of those structs.
Now we could use a t array, we could use a map mapping F gameplay tags to structs.
Either one is okay, but we definitely need a data asset.
So that's what we're going to create.
So we can create a new C plus plus class.
And I'm going to put this in ability system data along with our other data assets.
So I'm going to right click Choose New C Plus plus class, click on all classes and search for data
asset Choose Data Asset, click next and we're going to call this ability info.
So it's like attribute info only.
It's for abilities.
We're going to create the class.
And somehow I got Visual Studio opened.
So Visual Studio has opened with my new class.
Interesting.
I'm going to close that and I'm going to go to edit and editor preferences.
And just see if my source code editor has changed.
Looks like it's set to Visual Studio.
I like writer new projects, so I'm going to have to restart.
Not quite sure how that changed.
And now that that's fixed, I'm going to check and I see that my data folder doesn't have my new class
in it.
So what I'm going to do is go ahead and close the editor.
I do see the class here in Writer, so I'm going to force writer to regenerate my temporary files.
Mostly my intermediate folder is what I'm interested in, so I'm going to delete my intermediate folder
and my binaries and right click my new project, open it back up with Jetbrains writer.
And with that change, I'm going to go ahead and launch the editor.
Okay, so we're back here in the editor and sure enough, there's my new ability info.
So now that we have that, I'm going to go ahead and close again and this time start looking at my ability
info class.
Now the first thing I need is a struct and that struct is going to hold some information about my abilities.
It doesn't have to be complete yet.
I'm only going to add things to it that I want to use right now.
So first let's create the struct.
We're going to say struct and I'm going to call it aura ability info.
It's going to be marked with use struct and blueprint type and it gets a generated body and we can give
it a couple of fields here.
Now the first thing I want to give it is an gameplay tag and I'm going to call this ability tag and
this will be how we identify each of these abilities.
That means I'm going to need to include gameplay tag container.
So I'm going to go ahead and get that in here.
And I'm going to assign a default value of an empty gameplay tag like so and just like attribute info.
In fact, attribute info has the gameplay tag for the attribute set to edit defaults only.
Blueprint read only.
That's something I'd like to take, so I'm going to use that same exact property.
Now, in addition to the ability tag, I'm going to want a texture 2D for the icon and a material for
the background.
Right?
And that's basically all I need for now.
So first our icon.
It's going to be a T object pointer.
It's going to be of type U texture 2D.
I'm going to call it icon and set it equal to null pointer by default.
And this could be a const you texture 2D if we like, we would put that right there in the angle brackets
and I'm going to give it the same new property.
Now in addition to a new texture 2D, I'd like a material so I can use a T object pointer and a new
material interface is what I can use for this.
That will allow us to set it to a material.
And I'm going to call this background material and set this to a null pointer.
This can also be marked as const, and I'll give this a new property here.
So remember, const means we can't change it at runtime.
That doesn't mean we can't set it in the blueprint.
Now we can identify abilities by their ability tag, but we're also going to want to be able to assign
abilities to input tags.
In fact, we're already doing that with our Firebolt is assigned to the left mouse button input tag.
I think this should be something that we have in here as well.
So when this struct makes it to the widget, the widget can identify itself with the input tag and then
match those up and set its own properties based on that tag.
So I'm going to copy the ability tag and paste it and call this one input tag so an ability can be assigned
an input tag, right?
And now that we have the aura ability info, we can create a public section in the class and make a
array of these.
So t array of aura ability info structs.
And this will be called ability information and this will get also a new property and basically going
to give it the same exact property.
The only difference is we can put a category here.
Ability information.
Now, in addition to this array, I'd like a function that can retrieve the ability information based
on the ability tag.
So I'm going to have a function that returns an array ability info struct called find ability info for
tag and this can take in a const f gameplay tag by reference and I'm going to call it ability tag and
we can use b log not found a boolean.
But I'm going to set it to false by default.
So if we want to be warned, if we can't find one, we'll have that.
Now Findability info for tag can get a definition.
And here in the definition, we're going to simply find the ability info, right?
We can do that by looping through our ability information.
So I'm going to use a const F or ability info reference called info for each of these in ability information.
We're going to see if the info dot ability tag matches the ability tag passed in and if so, we'll return
info now.
Otherwise we'll return an empty f ora ability info struct.
And if we do reach beneath this for loop, if we never return from it we can log if our boolean b log
not found is true.
So if b log not found we're going to use a log and we can log an error.
Now, so far we've been using log temp an awful lot and I think that by this point what I'd like to
have my own log category.
So rather than using log temp, it'd be nice if we had a log ora.
So our project is now serious enough, I think, to have one of those.
So what I can do is I can right click on Ora go to add and choose file and I'm going to have a Ora log
channels dot H, I'm going to click okay and I'm going to go ahead and create another file.
Called aura log channels Dhcp.
So I'm just creating them right here at the project level where Aurora exists and in Aurora Log channels.
H.
I'd like to define or declare a log category.
Now, in order to do that, we have to include a couple headers.
We need core minimal.
So I'm going to include that and we need to include logging slash log macros because I'm going to use
a log macro.
I'm going to use declare log category extern and I can choose what my category name will be.
I'm going to call it log ora.
The default verbosity can be log and compile time.
Verbosity is going to be all.
So with this we're declaring a log.
We need to define it in our log channels.
CP And the first thing we can do is include the header file or a log channels, and then we can use
define log category and we have to define it log ora.
So with this, we now have our own log category that we can use and here in ability info dot CP when
we use log now we can use log ora if we include Ora log channels.
So as soon as I press comma space there's ora log channels.
Thank you writer and I can log an error here and the error is going to say we're going to use text here.
We're going to say, can't find info for ability tag.
We're going to go ahead and say what that tag is.
So we'll use percent s for a string on ability info.
And we'll say the name of the ability info this class that we're in.
So first we need that ability tag string.
So we're going to use star ability tag dot to string.
And then we want the name of the class we're in.
I'm going to use get name safe passing in this.
Like.
So there's my semi colon and we're now using our own log, so this is kind of cool.
We can even go into our other data assets here in ability system data.
We can take a look at attribute info where we're using log temp.
Instead of that, we can use log aura.
Now functionally it's basically the same.
The difference is it's not going to have log temp and the log, it's going to be log aura.
Now we're suppressing this log, but it's kind of cool that we have this now.
Okay, so now we have a data asset and this data asset needs to be accessible somewhere and I'd like
to use it in my overlay widget controller as the overlay widget controller is going to be performing
lookups and broadcasting information.
So I'm going to go into UI, into widget controller, but I do want this to be my public folder.
So public UI, widget controller, I'm going to go into overlay widget controller and add a variable
for our new data asset.
So here in overlay widget controller, I'm going to go down into our protected section where we have
our message widget data table.
I'm going to place a new object pointer for my data asset.
So it's going to be you ability info.
We're going to forward declare ability info.
So I'm going to put that up here class you ability info and right back down to it I'm going to call
this ability info.
And we have to set this from the blueprint.
So I'm going to copy the property for the data table.
We can even keep it in the same category widget data.
In fact, both of these could just be in data, but that's fine.
I'm going to leave it as is.
And now we have ability info.
So with that we can create a blueprint based on our ability info, data asset and set this ability info
on our overlay widget controller.
So let's go ahead and compile launch the editor and we'll do that.
Okay, so we can create our new blueprint.
So I'm going to go to Blueprints Ability system data and make our new data asset here by right clicking,
going to miscellaneous and choosing data asset and I can get my new ability info.
There it is all the way up at the top and I'll call this data ability info.
Now we can set this on our widget controller in blueprints, UI, widget controller and BP overlay widget
controller.
There's our new ability info.
I'm going to set it to the ability info.
I'm also going to browse to it and open it up and here's our ability information I can click plus to
add an element to it.
And here are the fields.
Now we can set this, but we don't actually have an ability for our firebolt do we?
So we need to set that and then we can set the input tag, the icon background material and all that
good stuff.
So I'm going to go ahead and close editor preferences.
I'm done with my overlay widget controller, but I'm going to keep ability info open and just go and
make that native gameplay tag for our ability.
It's going to be in aura gameplay tags, dot h and just under attack and summon.
I'm going to make a new ability tag for my Firebolt I'm going to call this abilities underscore fire,
underscore firebolt and I'll have a category of fire spells.
So let's go ahead and create that and it's going to be right here in abilities so I can copy and paste
and change abilities, summon to abilities fire Firebolt and call this abilities dot fire dot Firebolt
And this will just be Firebolt ability tag and that's it.
Now I can compile and launch and I should have my firebolt ability tag and I can use that now.
Okay, so getting my data asset back open now I can set my ability tag to abilities.
Fire Firebolt.
Now input tag.
I could just go in here and set it to the left mouse button.
Right?
But this is actually something that should be set from code.
I actually don't think it needs to be exposed here to the data asset blueprint.
I think it should be set in code.
It should be looked up from the ability itself because this can change.
So just like our current value of an attribute, we did not expose that to our data asset attribute
info.
I'm actually going to UN, expose input tag and get that out of here.
But icon we can set I'm going to set it to firebolt that texture.
And we can browse to it and remind ourselves, here's what it looks like.
And for the background material, I'm going to look up fire skill BG.
That material instance.
So now we have the data for this data asset and the last thing I can do is expose input tag.
So I'm going to save all close the editor, go back to ability info H and for the input tag I'm going
to remove edit defaults only, but we can still access it from the event graph with blueprint read only.
And with that now we have our data asset and our widget controller has that ability info variable that
we've set.
So it now has the ability to look up data based on an ability tag.
So we're one step closer to broadcasting this information, one of these structs up to our overlay widget
and in fact we can just broadcast it not specifically to the overlay widget, but just broadcast it.
And any of our globe's can be listening for that broadcast.
And the left mouse button one is going to update itself with the background and the icon there.
So we need to code all that and that's going to be in the videos to come.
Now, attempting to compile, I see that F log category log ora.
We have a struct type redefinition.
Now this is indicative of including this header file more than once.
And so our log category is being defined more than once.
Now.
We can easily fix that by going back to our ora log channels H and making sure that we have a pragma
once here.
Pragma once is something that we kind of always take for granted, but it makes sure that we never include
a header file more than once if it's already been included, or if something in here is defined, it's
never going to be redefined.
So adding a pragma once will save us there.
Excellent job and I'll see you in the next video.