Welcome back.
So our attribute menu is looking pretty good so far, but we do need a way to broadcast data to the
menu.
And we know that we have a few steps in the way of that.
One of those steps is we need to have a gameplay tag associated with all of our attributes.
Each one gets its own gameplay tag.
Now we've seen a couple of ways to add gameplay tags to our project.
If we go to project settings and gameplay tags, we've seen that we can add tags directly from within
the project settings.
We can also add them from a source, which is a config file and we can add them from data tables that
use the gameplay tag table row.
We've done that for our primary attributes.
Now the problem with these methods is when we need to use those tags in C plus plus.
The way to do so is by the use of request gameplay tag.
Now we do this in our widget controller class overlay widget controller.
We're using request gameplay tag using message.
So this is for part of a gameplay tag and this is a pretty good use case for request gameplay tag.
But we don't want to have to do this every time we need a gameplay tag.
We want to be able to use variables and have some kind of central source for variables for all the gameplay
tags in our project.
And then we don't have to type out these strings and be worried about typos and things like that.
So we're going to create a centralized location for the gameplay tags, at least those that we need
to use in the C plus plus domain.
And those are going to include our attribute gameplay tags.
So in order to store these gameplay tags in a centralized location, we're going to create a C plus
plus class to store them.
And this is going to be a C plus plus class or struct that we will only have one of in our project.
We're going to enforce that by using the singleton pattern.
So let's go into our C plus plus classes ora folder and we'll go into public.
And I'd like our class to be right here, sort of at the project level so we can access it quite easily
from any class.
So I'm going to right click new C plus plus class, and this is not going to be based on any of the
engine classes.
It's going to be none, an empty C plus plus class.
So we're going to click next and we can let this go into Ora slash public and Ora slash private respectively.
And this will be our singleton for gameplay tags.
Now I'm going to call this ora gameplay tags because the project is Ora, so this will be the tags for
this project.
So let's go ahead and create the class.
I'm going to close out of the editor and go into writer and here I see my new Ora gameplay tags.
It's created a new class for me and included core minimal and alt O is going to bring up my class CPP
file.
Now we can make this a class or a struct.
It doesn't matter.
I'm going to make this a struct as this will be a pretty simple type for us.
So I'm actually going to delete the class declaration and delete the constructor and destructors and
instead I'm going to declare a struct and this will be my f ora gameplay tags.
So let's make that class body and structs have a public body by default.
Even so, I'm going to explicitly make a public a protected and a private section.
Now this is going to be a singleton.
In fact, I'm going to go ahead and put a comment here.
We're going to say ora gameplay tags, and we'll also say that this is a singleton containing native
gameplay tags, native in a sense that they're created from within C plus plus and available in C plus
plus.
Now these will be available in the editor in Blueprint as well.
Now we're going to be using the gameplay tag type and that means we need to include where that type
is defined.
So we're going to add the include here and that's in gameplay tag container dot H, We're going to make
sure to include that and here in F or a gameplay tags, because this is a singleton, we're going to
design this in a specific way with a singleton.
What you do is you create a static getter function so you don't need an instance of the class to exist
to be able to call one of its static functions.
So if we make a static function, I'll make it const and its return type will be F or a game.
Play tags and it'll return a reference.
We want to return a reference to the one and only instance of or a gameplay tags that will exist in
the game.
And we call this get and get is simple.
It returns well.
It's going to return the one and only instance that exists.
Now what is that instance?
Well, it's going to be a static variable on this class, so the class itself will have a variable to
store the one and only instance of itself.
So here's how we'll do it.
We'll make a private static variable of type F or a gameplay tags called gameplay tags, and the static
function gets will return gameplay tags.
So once one of these is constructed, then we can just call the static function, get to get the one
and only instance of gameplay tags.
Now, for a static variable like this, we need to go into the CPP file and explicitly declare the type
here.
So we say f or a gameplay tags and then we declare the variable fully qualified with F or a gameplay
tags.
Gameplay tags like so.
So what we're going to do here is we're going to want a public function to initialize our tags.
We want to be able to create those native gameplay tags.
So we'll create a function here that will also be static.
It's a void function and we'll call this initialize native gameplay tags.
So again, a static function that can be called without one of these or a gameplay tag instances even
in existence because it's static, right?
Let's generate the definition and what are we going to do in initialize native gameplay tags?
Well, this is where we're going to kick off initializing gameplay tags.
So here's how we can do it.
We can get the gameplay tag manager.
Remember when we create a gameplay tag, it's registered with the gameplay tag manager.
This is a object in our project there's only one of them and it manages the gameplay tags and we can
also use it to add gameplay tags even natively here in C plus plus.
And that's how we're going to do it.
So we need to access that type the gameplay tag manager, we're going to include that, its gameplay
tag manager dot h and we're going to get you gameplay tag manager and we're going to call a static function
called get interesting, right?
Get a static function that returns the one and only gameplay tag manager.
That's the pattern we're using with our aura gameplay tags here.
So we get that, we get the gameplay tags manager and we can use functions on it such as add native
gameplay tag.
Now add native gameplay tag requires the tag name and it also has a tag dev comment.
Just like when we create gameplay tags in the editor we specify the name of the tag and then we specify
some kind of comment that's optional.
Right?
It could be empty if we don't want to add that.
So we're going to define a native gameplay tag.
Let's start with some of our secondary attributes, shall we?
We'll make an F name as this requires an F name and we'll call this attributes dot secondary dot armor.
And then our next input is an F string and the f string is the comment.
Now for the F string for armor.
This is of course optional, but we'll go ahead and add the comment.
We'll say reduces damage taken, improves blockchains like so.
And this is how we can declare native gameplay tags.
We do it through the gameplay tag Manager.
Okay, so initializing native gameplay tags is just doing this, creating the gameplay tag.
And now we have our gameplay tags, a singleton that we can always get with the get function and we've
created our static gameplay tags instance here.
So we have basically a global singleton.
Now the question that's going to pop up in your mind is at what point in our project should we call
this function to initialize the tags?
Well, probably early on, right, as soon as we can before any of those tags are attempted to be used.
So we're going to learn how to do that by creating our very own asset manager and we'll learn what that
is in the next video.
So great job and I'll see you soon.