WEBVTT

00:06.900 --> 00:08.070
Welcome back.

00:08.190 --> 00:14.760
So our attribute menu is looking pretty good so far, but we do need a way to broadcast data to the

00:14.760 --> 00:15.270
menu.

00:15.270 --> 00:18.570
And we know that we have a few steps in the way of that.

00:18.600 --> 00:24.600
One of those steps is we need to have a gameplay tag associated with all of our attributes.

00:24.600 --> 00:27.060
Each one gets its own gameplay tag.

00:27.360 --> 00:31.490
Now we've seen a couple of ways to add gameplay tags to our project.

00:31.500 --> 00:38.130
If we go to project settings and gameplay tags, we've seen that we can add tags directly from within

00:38.130 --> 00:39.470
the project settings.

00:39.480 --> 00:46.170
We can also add them from a source, which is a config file and we can add them from data tables that

00:46.170 --> 00:48.180
use the gameplay tag table row.

00:48.210 --> 00:50.860
We've done that for our primary attributes.

00:50.880 --> 00:57.630
Now the problem with these methods is when we need to use those tags in C plus plus.

00:57.780 --> 01:02.620
The way to do so is by the use of request gameplay tag.

01:02.640 --> 01:08.370
Now we do this in our widget controller class overlay widget controller.

01:08.380 --> 01:12.370
We're using request gameplay tag using message.

01:12.370 --> 01:18.490
So this is for part of a gameplay tag and this is a pretty good use case for request gameplay tag.

01:18.490 --> 01:22.810
But we don't want to have to do this every time we need a gameplay tag.

01:22.810 --> 01:29.710
We want to be able to use variables and have some kind of central source for variables for all the gameplay

01:29.710 --> 01:31.060
tags in our project.

01:31.060 --> 01:36.190
And then we don't have to type out these strings and be worried about typos and things like that.

01:36.190 --> 01:42.670
So we're going to create a centralized location for the gameplay tags, at least those that we need

01:42.670 --> 01:45.220
to use in the C plus plus domain.

01:45.220 --> 01:49.450
And those are going to include our attribute gameplay tags.

01:49.570 --> 01:55.990
So in order to store these gameplay tags in a centralized location, we're going to create a C plus

01:55.990 --> 01:57.880
plus class to store them.

01:57.880 --> 02:05.800
And this is going to be a C plus plus class or struct that we will only have one of in our project.

02:05.830 --> 02:09.490
We're going to enforce that by using the singleton pattern.

02:09.490 --> 02:16.900
So let's go into our C plus plus classes ora folder and we'll go into public.

02:16.900 --> 02:24.100
And I'd like our class to be right here, sort of at the project level so we can access it quite easily

02:24.100 --> 02:25.240
from any class.

02:25.240 --> 02:30.640
So I'm going to right click new C plus plus class, and this is not going to be based on any of the

02:30.640 --> 02:31.750
engine classes.

02:31.750 --> 02:35.830
It's going to be none, an empty C plus plus class.

02:35.830 --> 02:44.290
So we're going to click next and we can let this go into Ora slash public and Ora slash private respectively.

02:44.410 --> 02:47.590
And this will be our singleton for gameplay tags.

02:47.860 --> 02:56.200
Now I'm going to call this ora gameplay tags because the project is Ora, so this will be the tags for

02:56.200 --> 02:57.310
this project.

02:57.310 --> 02:59.860
So let's go ahead and create the class.

02:59.860 --> 03:07.450
I'm going to close out of the editor and go into writer and here I see my new Ora gameplay tags.

03:07.480 --> 03:16.540
It's created a new class for me and included core minimal and alt O is going to bring up my class CPP

03:16.570 --> 03:17.260
file.

03:17.590 --> 03:20.080
Now we can make this a class or a struct.

03:20.080 --> 03:20.950
It doesn't matter.

03:20.950 --> 03:25.630
I'm going to make this a struct as this will be a pretty simple type for us.

03:25.630 --> 03:33.400
So I'm actually going to delete the class declaration and delete the constructor and destructors and

03:33.400 --> 03:41.350
instead I'm going to declare a struct and this will be my f ora gameplay tags.

03:42.010 --> 03:48.280
So let's make that class body and structs have a public body by default.

03:48.400 --> 03:56.050
Even so, I'm going to explicitly make a public a protected and a private section.

03:57.280 --> 03:59.440
Now this is going to be a singleton.

03:59.440 --> 04:02.440
In fact, I'm going to go ahead and put a comment here.

04:02.440 --> 04:13.180
We're going to say ora gameplay tags, and we'll also say that this is a singleton containing native

04:13.180 --> 04:21.460
gameplay tags, native in a sense that they're created from within C plus plus and available in C plus

04:21.460 --> 04:22.000
plus.

04:22.030 --> 04:25.330
Now these will be available in the editor in Blueprint as well.

04:25.540 --> 04:32.050
Now we're going to be using the gameplay tag type and that means we need to include where that type

04:32.050 --> 04:33.010
is defined.

04:33.010 --> 04:38.800
So we're going to add the include here and that's in gameplay tag container dot H, We're going to make

04:38.800 --> 04:46.330
sure to include that and here in F or a gameplay tags, because this is a singleton, we're going to

04:46.330 --> 04:49.600
design this in a specific way with a singleton.

04:49.630 --> 04:56.860
What you do is you create a static getter function so you don't need an instance of the class to exist

04:56.860 --> 04:59.770
to be able to call one of its static functions.

04:59.890 --> 05:06.550
So if we make a static function, I'll make it const and its return type will be F or a game.

05:06.620 --> 05:08.990
Play tags and it'll return a reference.

05:09.010 --> 05:14.770
We want to return a reference to the one and only instance of or a gameplay tags that will exist in

05:14.770 --> 05:15.520
the game.

05:15.520 --> 05:18.670
And we call this get and get is simple.

05:18.670 --> 05:20.320
It returns well.

05:20.320 --> 05:23.860
It's going to return the one and only instance that exists.

05:23.980 --> 05:25.720
Now what is that instance?

05:25.720 --> 05:32.590
Well, it's going to be a static variable on this class, so the class itself will have a variable to

05:32.590 --> 05:35.080
store the one and only instance of itself.

05:35.080 --> 05:37.330
So here's how we'll do it.

05:37.540 --> 05:47.380
We'll make a private static variable of type F or a gameplay tags called gameplay tags, and the static

05:47.380 --> 05:50.770
function gets will return gameplay tags.

05:51.550 --> 05:58.780
So once one of these is constructed, then we can just call the static function, get to get the one

05:58.780 --> 06:00.880
and only instance of gameplay tags.

06:00.910 --> 06:09.140
Now, for a static variable like this, we need to go into the CPP file and explicitly declare the type

06:09.140 --> 06:09.530
here.

06:09.530 --> 06:15.920
So we say f or a gameplay tags and then we declare the variable fully qualified with F or a gameplay

06:15.920 --> 06:16.730
tags.

06:16.760 --> 06:19.820
Gameplay tags like so.

06:19.910 --> 06:26.060
So what we're going to do here is we're going to want a public function to initialize our tags.

06:26.060 --> 06:30.050
We want to be able to create those native gameplay tags.

06:30.290 --> 06:34.220
So we'll create a function here that will also be static.

06:34.310 --> 06:41.090
It's a void function and we'll call this initialize native gameplay tags.

06:42.670 --> 06:49.510
So again, a static function that can be called without one of these or a gameplay tag instances even

06:49.510 --> 06:52.170
in existence because it's static, right?

06:52.180 --> 06:58.840
Let's generate the definition and what are we going to do in initialize native gameplay tags?

06:58.840 --> 07:02.590
Well, this is where we're going to kick off initializing gameplay tags.

07:02.950 --> 07:04.570
So here's how we can do it.

07:04.600 --> 07:08.080
We can get the gameplay tag manager.

07:08.080 --> 07:13.120
Remember when we create a gameplay tag, it's registered with the gameplay tag manager.

07:13.150 --> 07:20.770
This is a object in our project there's only one of them and it manages the gameplay tags and we can

07:20.770 --> 07:25.750
also use it to add gameplay tags even natively here in C plus plus.

07:25.750 --> 07:27.370
And that's how we're going to do it.

07:27.370 --> 07:32.800
So we need to access that type the gameplay tag manager, we're going to include that, its gameplay

07:32.830 --> 07:40.840
tag manager dot h and we're going to get you gameplay tag manager and we're going to call a static function

07:40.840 --> 07:43.580
called get interesting, right?

07:43.610 --> 07:48.440
Get a static function that returns the one and only gameplay tag manager.

07:48.440 --> 07:52.520
That's the pattern we're using with our aura gameplay tags here.

07:52.520 --> 08:01.280
So we get that, we get the gameplay tags manager and we can use functions on it such as add native

08:01.280 --> 08:02.300
gameplay tag.

08:02.300 --> 08:09.560
Now add native gameplay tag requires the tag name and it also has a tag dev comment.

08:09.560 --> 08:15.500
Just like when we create gameplay tags in the editor we specify the name of the tag and then we specify

08:15.500 --> 08:18.320
some kind of comment that's optional.

08:18.320 --> 08:18.590
Right?

08:18.590 --> 08:21.260
It could be empty if we don't want to add that.

08:21.260 --> 08:24.290
So we're going to define a native gameplay tag.

08:24.290 --> 08:27.620
Let's start with some of our secondary attributes, shall we?

08:27.650 --> 08:37.670
We'll make an F name as this requires an F name and we'll call this attributes dot secondary dot armor.

08:38.000 --> 08:44.510
And then our next input is an F string and the f string is the comment.

08:44.540 --> 08:46.910
Now for the F string for armor.

08:46.940 --> 08:50.720
This is of course optional, but we'll go ahead and add the comment.

08:50.720 --> 08:58.850
We'll say reduces damage taken, improves blockchains like so.

08:58.850 --> 09:02.210
And this is how we can declare native gameplay tags.

09:02.210 --> 09:05.000
We do it through the gameplay tag Manager.

09:05.120 --> 09:11.750
Okay, so initializing native gameplay tags is just doing this, creating the gameplay tag.

09:11.750 --> 09:19.010
And now we have our gameplay tags, a singleton that we can always get with the get function and we've

09:19.010 --> 09:22.730
created our static gameplay tags instance here.

09:22.730 --> 09:25.340
So we have basically a global singleton.

09:25.370 --> 09:32.630
Now the question that's going to pop up in your mind is at what point in our project should we call

09:32.630 --> 09:34.730
this function to initialize the tags?

09:34.730 --> 09:42.590
Well, probably early on, right, as soon as we can before any of those tags are attempted to be used.

09:42.590 --> 09:47.990
So we're going to learn how to do that by creating our very own asset manager and we'll learn what that

09:47.990 --> 09:49.790
is in the next video.

09:49.970 --> 09:52.130
So great job and I'll see you soon.
