WEBVTT

00:06.940 --> 00:08.030
Welcome back.

00:08.050 --> 00:15.520
Now, we had a list of steps and we've accomplished step one where we've created our secondary attribute

00:15.520 --> 00:19.210
gameplay tags and we handle them in C plus plus.

00:19.210 --> 00:27.100
Now as we're creating them natively with our singleton or a gameplay tags, now we need an attribute

00:27.100 --> 00:35.500
info data asset, basically an asset that we can use to store info in the form of a struct which we're

00:35.500 --> 00:38.800
going to create called f or attribute info struct.

00:38.800 --> 00:42.550
So we're really going to knock out two and three in this video.

00:42.550 --> 00:43.720
So let's do it.

00:44.020 --> 00:50.740
So from within the editor, I'm going to make another C plus plus class and this time it's going to

00:50.740 --> 00:52.750
be a data asset.

00:52.750 --> 00:56.950
So I'm going to go to C plus plus classes or a public.

00:56.950 --> 00:59.680
And this is related to the ability system.

00:59.680 --> 01:04.630
I'm going to open ability system here and make a new C plus plus class.

01:04.630 --> 01:07.150
And this is going to be a data asset.

01:07.150 --> 01:11.050
So I'm going to go to all classes and search for data asset.

01:12.210 --> 01:15.900
And choose data asset and click next.

01:15.930 --> 01:21.810
Now this can be in ability system and I'm going to add a subfolder called data.

01:21.810 --> 01:28.040
So ability system slash data and this will be for attribute info.

01:28.050 --> 01:31.470
So I'm going to call it attribute info.

01:31.500 --> 01:35.370
Let's go ahead and create the class and close the editor.

01:35.670 --> 01:42.060
So we should get our attribute info data asset inside of the data folder.

01:42.330 --> 01:49.800
I'm going to go ahead and collapse both public and private and reopen ability system data and open attribute

01:49.800 --> 01:50.340
info.

01:50.340 --> 01:51.300
And here we go.

01:51.330 --> 01:55.620
We have you attribute info, which is a new data asset.

01:55.710 --> 02:02.190
Now, if you've never used a data asset before, I think you're really going to like them because they

02:02.190 --> 02:09.500
give us the opportunity to store asset information in a nice blueprint settable class.

02:09.510 --> 02:17.320
So I'm going to go ahead and right click on attribute info, close other tabs and use control K or alt

02:17.320 --> 02:23.950
O in writer to open up the companion file so I have the H and CP files.

02:24.500 --> 02:31.700
And in attribute info, we're going to want to store some structs and we haven't created this struct

02:31.700 --> 02:38.450
yet, but we want to create a struct to store all the information associated with a given attribute.

02:38.450 --> 02:46.790
So once an attribute changes, then we can broadcast this struct object up to the widget blueprints

02:46.790 --> 02:51.050
who will receive it and update themselves with that information.

02:51.170 --> 02:56.570
So I'd like to make a struct and I'd like it to be for attribute info.

02:56.570 --> 03:06.110
So I'm going to declare a new struct called f ora attribute info and we'd like to be able to use this

03:06.140 --> 03:07.120
in blueprint.

03:07.130 --> 03:08.600
It needs to be blueprint type.

03:08.600 --> 03:15.740
So we're going to give it a use struct macro with blueprint type and that means it needs a generated

03:15.740 --> 03:16.940
body of course.

03:17.210 --> 03:25.950
Now attribute info is going to need a gameplay tag to identify which attribute this info is for.

03:25.950 --> 03:29.430
So we're going to use gameplay tags to identify attributes.

03:29.670 --> 03:35.190
This will be an F gameplay tag then and we're going to call it attribute tag.

03:35.190 --> 03:43.380
And if we're using F gameplay tag well we now need to include the header file for gameplay tag container

03:43.410 --> 03:44.400
dot h.

03:44.550 --> 03:46.320
So there we have it.

03:46.320 --> 03:52.130
And we also need a U property and we want to set this from the blueprint of our data asset.

03:52.140 --> 03:57.780
So we're going to make this edit, at least edit defaults only and blueprint read only.

03:57.780 --> 04:03.360
And we can initialize this with an empty gameplay tag like so.

04:03.360 --> 04:08.850
So that's how we'll identify each of these struct objects is by gameplay tag.

04:08.850 --> 04:17.250
Now the information that we need to pass up to the widget side is going to require some text for the

04:17.250 --> 04:22.320
attribute name so we can set that attribute name in the attribute menu.

04:22.320 --> 04:28.650
And whenever we have text that's user facing in a widget, we use F text.

04:28.650 --> 04:32.730
So if you're ever wondering when to use F text, that's for the widgets.

04:32.730 --> 04:37.350
That's when we set the text for a widget to show to the user.

04:37.350 --> 04:41.310
So we're going to have an F text called attribute name.

04:42.120 --> 04:47.670
This will be an empty F text and these will all get the same uproperty macro.

04:47.670 --> 04:54.000
So we'll go ahead and copy that over and we'll also have another F text for the description.

04:54.000 --> 04:58.560
So I'm going to go ahead and copy this and this will be attribute description.

04:59.790 --> 05:04.530
And aside from that, we just need an attribute value.

05:04.530 --> 05:08.880
So we're going to have a float for attribute value.

05:08.880 --> 05:11.850
This will be broadcast up to the blueprint.

05:11.880 --> 05:16.560
We'll initialize it to zero and give it a U property.

05:16.560 --> 05:22.530
But I don't want to be able to edit this from within our data asset, so we're not going to expose it

05:22.530 --> 05:23.850
to the data asset.

05:23.880 --> 05:27.900
We're just going to expose to blueprint to read from.

05:27.900 --> 05:30.330
But it's public in the struct.

05:30.330 --> 05:38.010
So here in C plus plus we can set its value before we broadcast it up to the blueprint side, but we're

05:38.010 --> 05:44.700
not going to expose it to the data asset just because that's not where the attribute value is set.

05:44.700 --> 05:50.820
So if we did set it from the data asset, we'd just be overwriting it later when we check that attributes

05:50.820 --> 05:51.960
true value.

05:52.080 --> 05:58.590
So now we have our struct and if we need to later, we can always add more fields to the struct.

05:58.590 --> 06:07.620
But for now this is great and we want our data asset to contain something filled with structs.

06:07.620 --> 06:09.990
To me an array comes to mind.

06:09.990 --> 06:19.200
So let's make a public section here and we'll create a T array of type F or attribute info.

06:19.200 --> 06:23.010
And this is going to be called attribute information.

06:23.130 --> 06:26.420
This will contain our attribute info structs.

06:26.420 --> 06:29.510
Now we need to fill this in and we're going to fill it in in the blueprint.

06:29.510 --> 06:34.160
So we're going to give it a U property and make this edit defaults only.

06:35.830 --> 06:37.390
Blueprint read only.

06:38.270 --> 06:40.940
So this is our list of actor info.

06:41.180 --> 06:43.550
So we'll set that from the blueprint.

06:43.640 --> 06:50.330
But I'd like a function here that will take a gameplay tag and return the correct info.

06:50.360 --> 06:55.340
The correct attribute info from this array based on the gameplay tag.

06:55.460 --> 07:06.020
So I want a function that returns an attribute info called find attribute info for tag and this will

07:06.020 --> 07:14.900
take a const f gameplay tag reference called attribute tag and we'll pass in a boolean called B log

07:14.900 --> 07:16.610
not found.

07:18.840 --> 07:21.120
And I'll make it false by default.

07:21.390 --> 07:30.930
And if we pass true into this, then if we try to find an attribute info struct from this array that

07:30.930 --> 07:38.390
does not exist there, then we'll use a log to log an error and this can be a const function.

07:38.400 --> 07:40.520
So let's make this lookup function.

07:40.530 --> 07:46.910
Now we have an array and this function is taking in a game play tag for the attribute.

07:46.920 --> 07:54.210
So how are we going to find the ability info struct in our array that has this attribute tag?

07:54.300 --> 07:55.950
Well, we can use a for loop.

07:55.950 --> 08:03.690
We can say for let's do a const for attribute info reference called info.

08:05.460 --> 08:10.890
So for each of these in attribute information, then we can check the tag.

08:10.890 --> 08:21.010
We can say if info dot attribute tag double equals our attribute tag passed in so we can use double

08:21.010 --> 08:21.820
equals.

08:21.820 --> 08:26.710
There's also the matches tag exact function.

08:26.710 --> 08:37.360
So if you don't want to use double equals, you could use info dot attribute tag dot matches tag exact

08:37.390 --> 08:40.120
passing in attribute tag.

08:40.120 --> 08:42.310
This will check for an exact match.

08:42.310 --> 08:45.760
So if you wanted to you could do this instead.

08:45.790 --> 08:47.440
Either way is fine.

08:47.470 --> 08:51.220
If it does match, then we return this info that we're on.

08:51.220 --> 09:00.760
So we just simply return info and if we loop through the entire array and we never return, then we

09:00.760 --> 09:08.260
make it down here, which means we never found an attribute info in the array and we can log an error

09:08.260 --> 09:11.530
if b log not found is true.

09:11.530 --> 09:17.710
So if we pass in true, that means we want to see an error when we don't get a successful attribute

09:17.710 --> 09:18.190
info.

09:18.220 --> 09:21.760
When we don't find one from the array so we can use log.

09:22.900 --> 09:30.850
Now, we haven't defined our own custom log category, but for now we can use log temp error and for

09:30.850 --> 09:40.990
the message we can say can't find info capital info for attribute tag and we can even say what the tag

09:40.990 --> 09:51.400
is percent there on attribute info and we can even have the name of this class here.

09:52.500 --> 09:56.430
We'll put a period there and we need two strings.

09:56.490 --> 09:59.580
First will be our attribute tag.

10:00.970 --> 10:02.380
We can use to string.

10:03.190 --> 10:12.400
And next will be the name of this class and we can use with an asterisk get name safe passing in this.

10:15.600 --> 10:22.260
And this is going to print an error message if we can't find anything in the array, but we still need

10:22.260 --> 10:23.130
to return something.

10:23.130 --> 10:27.780
So in that case, we'll return an empty or attribute info.

10:28.290 --> 10:36.300
So now we have a function we can call and it's a public function that we can simply pass in a tag to

10:36.300 --> 10:38.880
and receive the attribute info.

10:38.910 --> 10:45.540
This was one of those challenges that we had mapped out that we needed to be able to find Once we have

10:45.540 --> 10:53.010
a gameplay tag that is associated with an attribute, we can get this attribute info data asset and

10:53.010 --> 10:58.260
get the aura attribute info structure out of this data asset.

10:58.590 --> 11:03.090
So now that we have the data asset, we can fill it in with information.

11:03.090 --> 11:10.260
So I can go ahead and compile and launch the editor and we can make a blueprint based on this data asset.

11:11.720 --> 11:18.110
So back in the editor, let's make our data asset by going to Blueprints and ability system.

11:18.110 --> 11:23.090
And we already have a data folder where we've placed data tables.

11:23.120 --> 11:26.750
Now we're going to have our data assets be placed here as well.

11:26.750 --> 11:30.920
So we right click, we go to miscellaneous and look for data asset.

11:30.920 --> 11:37.770
Here is one and we search for our class attribute info and here it is.

11:37.790 --> 11:40.190
Let's grab that, select it.

11:40.220 --> 11:50.360
We'll prefix it with D A for data asset and we'll call this D a attribute info and we'll open this up

11:50.360 --> 11:54.080
and here's our array called attribute information.

11:54.080 --> 12:02.330
And if we click plus we now have an element with index zero and we have three fields we can set attribute

12:02.360 --> 12:07.130
tag, attribute name that's an F text and attribute description.

12:07.130 --> 12:08.570
Another F text.

12:08.600 --> 12:16.260
Now there's an attribute value in this struct, but we did not make it exposed so that we can set it

12:16.260 --> 12:17.580
in details panels.

12:17.580 --> 12:22.290
Remember we made it only exposed to the event graph with blueprint read only.

12:22.410 --> 12:29.700
The others are exposed to the details panel and we can set them so we can go ahead and add elements

12:29.700 --> 12:32.880
to this array for each of our attributes.

12:32.880 --> 12:34.800
And I'll start with the primaries.

12:34.800 --> 12:43.170
So first I'm going to expand the dropdown, go to attributes primary and choose intelligence, and we

12:43.170 --> 12:47.670
can go ahead and fill in the attribute name intelligence.

12:48.780 --> 12:56.550
We can fill in the attribute description which I have already in my C plus plus project, if you'll

12:56.550 --> 12:57.510
recall.

12:57.540 --> 13:01.890
All I have to open is my aura gameplay tags.

13:01.920 --> 13:05.630
Actually not the header file but the CPP file.

13:05.640 --> 13:13.500
And here I've already added comments for each of these tags and the intelligence one has increases magical

13:13.500 --> 13:14.400
damage.

13:14.820 --> 13:22.320
I'm not sure why I chose intelligence first, but it's there and I can go ahead and paste that comment

13:22.320 --> 13:22.860
there.

13:23.250 --> 13:30.870
So all we have to do is put all the attributes here, and that's a repetitive process and I'm going

13:30.870 --> 13:34.410
to go ahead and time lapse it and fill this out.

14:49.230 --> 14:54.360
Okay, so I've added all the primary and all the secondary attributes here.

14:54.450 --> 14:56.160
Now there's kind of a lot of them.

14:56.160 --> 15:01.740
So if you really wanted to, you could have multiple arrays here, but I'm just going to have one single

15:01.740 --> 15:08.400
array where I can set this information and all it has is the tag, that attribute name and the attribute

15:08.400 --> 15:15.420
description which we'd like to use once we start broadcasting delegates that our widgets can bind to

15:15.420 --> 15:17.250
and receive this information.

15:17.250 --> 15:23.970
So this is looking great and we've already conquered the first three steps here in our next steps for

15:23.970 --> 15:25.140
the attribute menu.

15:25.140 --> 15:28.020
In fact, number four was to fill in the data assets.

15:28.020 --> 15:29.700
So we've already done that.

15:29.730 --> 15:37.140
Next, we need to create our widget controller for the attribute menu so we can start driving data to

15:37.140 --> 15:40.980
the attribute menu to show the values of our attributes.

15:40.980 --> 15:44.340
So that is our next step and we'll do that next.

15:44.460 --> 15:45.450
Excellent.

15:45.480 --> 15:46.440
I'll see you soon.
