WEBVTT

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

00:08.580 --> 00:14.910
Now, one of the last features I'd like to implement in this game project is the ability of our enemies

00:14.910 --> 00:16.170
to spawn loot.

00:16.350 --> 00:21.990
Now, we don't have too much by the way of loot, but we do have some things we can pick up if we go

00:21.990 --> 00:24.240
into blueprints into actor.

00:24.240 --> 00:27.990
We do have crystals and we have potions.

00:28.020 --> 00:33.840
Now, a loot system can take lots of types of loot into account.

00:33.840 --> 00:39.210
So even though we only have crystals and potions, which are pretty much the same thing, you could

00:39.210 --> 00:45.750
use this system for any types of loot that you add to your game, and I do plan on covering more topics

00:45.750 --> 00:51.930
in future series that have to do with more types of loot, but since we just have crystals and potions,

00:51.930 --> 00:53.250
that's what we'll use.

00:53.250 --> 00:57.510
But we can make a system that's flexible enough to account for other types of loot as well.

00:57.510 --> 01:03.840
Now, I'd like my loot system to be data driven, and I'd like each enemy to be able to spawn loot.

01:03.840 --> 01:11.130
And for this particular system, I'm going to keep it simple and just have tiers of loot that we can

01:11.130 --> 01:21.060
have, and each type of item can have its own chance to spawn, and our enemies can just reference that

01:21.060 --> 01:22.020
data asset.

01:22.020 --> 01:25.410
So let's make a data asset for our loot tiers.

01:25.410 --> 01:28.770
I'm going to go to public ability system and Data.

01:28.770 --> 01:33.960
I have all my data assets here, so I'd kind of like my loot tiers to be here too.

01:33.960 --> 01:41.850
So I'm going to create a new class, choose all classes and search for Data Asset and just choose Data

01:41.850 --> 01:42.450
Asset.

01:42.450 --> 01:44.670
And this can go in data.

01:44.670 --> 01:50.700
And I'm going to call this loot tears tears.

01:50.700 --> 01:57.240
Let's create this class and go ahead and close the editor and get that new class open.

01:57.240 --> 02:00.750
So I'm going to get the cpp file open first.

02:00.780 --> 02:02.550
It's an ability system data.

02:02.550 --> 02:03.750
Here's loot tears.

02:03.750 --> 02:07.260
And I'll go ahead and open up the h file.

02:07.260 --> 02:12.420
Now for loot I'm going to want an array of some kind of structure.

02:12.420 --> 02:15.900
So I'm going to define a new struct here struct.

02:15.900 --> 02:18.660
And I'm going to call this f loot item.

02:18.660 --> 02:23.520
So we can define the properties for spawning a specific item.

02:23.520 --> 02:26.430
And this can be a u struct blueprint type.

02:26.430 --> 02:29.130
We do need generated body.

02:29.130 --> 02:32.790
And we'll add some variables and make sure they're initialized.

02:32.790 --> 02:39.840
And this is reminding me that there was an error that I saw when compiling earlier, referencing an

02:39.840 --> 02:42.030
uninitialized variable in a struct.

02:42.030 --> 02:48.900
I believe it was in my load screen save game and it was in F saved ability.

02:48.900 --> 02:50.160
My ability level.

02:50.160 --> 02:54.330
I'm going to initialize that to one just to get rid of that error.

02:54.330 --> 02:55.920
That's for variables.

02:55.920 --> 02:57.420
Arrays can be empty.

02:57.420 --> 03:03.810
So we're going to add a subclass of of type A actor.

03:03.810 --> 03:06.120
And this will be the class to spawn.

03:06.120 --> 03:07.830
We'll call this loot class.

03:07.830 --> 03:15.930
And this one is going to be a U property with Edit Anywhere blueprint read only.

03:15.930 --> 03:22.620
I want to be able to read this from blueprint in the event graph, and we'll give it a category of loot

03:22.650 --> 03:23.700
tears.

03:24.540 --> 03:26.700
Pipe symbol spawning.

03:28.970 --> 03:31.430
Looks like I have two equal signs.

03:31.880 --> 03:34.580
Okay, so we have the class to spawn.

03:34.580 --> 03:37.580
We can also have a chance to spawn.

03:37.580 --> 03:43.730
So for each loot item we can have a chance to spawn that item.

03:43.730 --> 03:50.360
We'll give it zero by default, but we'll set this as well from our blueprint I'm going to copy this

03:50.360 --> 03:54.830
Uproperty paste it here and use the same U property.

03:54.830 --> 03:59.090
And we can also have a max number of these that we can spawn.

03:59.090 --> 04:06.830
So let's say we'd like to spawn multiple items of the same type, but we need a maximum number to spawn.

04:06.830 --> 04:08.870
So this can be an int 32.

04:10.130 --> 04:13.520
Called max number to spawn.

04:13.820 --> 04:18.680
And then finally we can provide an option to override the level of that loot.

04:18.680 --> 04:20.840
Let's say we're spawning in a potion.

04:20.840 --> 04:22.490
Potions can have their own level.

04:22.490 --> 04:26.570
If we want to override that, then we should have that as an option.

04:26.570 --> 04:33.020
So I'm going to have a bool called be loot level override and set this to true by default.

04:34.700 --> 04:37.490
And if it's true, here's what I'd like to do.

04:37.490 --> 04:43.220
I'd like to set the level of the lutte class to the level of the enemy spawning it.

04:43.220 --> 04:48.440
But if it's false, then we'll just spawn it in without setting its level.

04:48.440 --> 04:50.090
So whatever its level is.

04:50.090 --> 04:56.300
So this gives us a struct, and we can give ourselves an array of these by creating a public section

04:56.300 --> 05:02.390
in the data asset and creating a t array of this new structure f loot item.

05:02.390 --> 05:05.840
And this can be our loot items array.

05:07.150 --> 05:10.870
And this can be filled in in the data asset as well.

05:10.870 --> 05:18.250
We can make it edit anywhere or edit defaults only, and we can make this blueprint read only if we'd

05:18.250 --> 05:24.640
like to access it from the event graph and the same category as the others.

05:24.640 --> 05:25.630
Loot tiers.

05:25.630 --> 05:26.650
Spawning.

05:28.340 --> 05:36.830
And finally, I'd like to handle retrieving loot items with a simple function that can return an array

05:36.830 --> 05:38.180
of F loot items.

05:38.180 --> 05:46.940
And this can do the math for us when it comes to checking the number of items to spawn and the chance

05:46.940 --> 05:53.060
to spawn, we can take all that into account with a function and return a t array of items to spawn,

05:53.060 --> 05:56.030
so we can have a t array of f loot item.

05:56.960 --> 06:00.470
Returning function called get loot items.

06:02.000 --> 06:04.010
And this function can do the math for us.

06:04.010 --> 06:06.470
So we'll go ahead and generate this definition.

06:06.470 --> 06:10.010
And all I want to do is return an array of items.

06:10.010 --> 06:12.680
So I'll make a t array of f loot item.

06:12.680 --> 06:14.030
I can just copy this.

06:15.120 --> 06:21.210
Called return items and at the very end, return return items.

06:21.660 --> 06:26.910
Kind of sounds like we're taking some items to the store with our receipt and returning them for our

06:26.910 --> 06:33.750
money back, but we're actually just returning an array of items, and that means I want to loop over

06:33.750 --> 06:34.740
my loot items.

06:34.740 --> 06:40.260
So for flute item, I'm going to make that a reference called item.

06:40.260 --> 06:48.330
For each item in loot items I'm going to perform this loop, and inside of this I'm going to loop over

06:48.330 --> 06:51.300
for each item their max number to spawn.

06:51.300 --> 06:56.610
So I'm at a given item here and it has its own max number to spawn.

06:56.610 --> 06:58.530
So I'm going to use an int 32.

06:59.250 --> 07:09.990
I started off at zero and loop as long as it's less than item dot max number to spawn and plus plus

07:09.990 --> 07:12.360
I or I plus plus either one.

07:12.360 --> 07:14.940
So there's a max number of items to spawn.

07:14.940 --> 07:17.040
Let's say we have a red potion.

07:17.040 --> 07:21.780
You can spawn a maximum of three of them when you kill an enemy, right?

07:21.780 --> 07:30.180
So for that specific item, if you can spawn a maximum of three, then I want to loop over that number

07:30.180 --> 07:32.310
three and three times.

07:32.310 --> 07:37.920
I want to roll the dice and see if our chance to spawn dictates that we should spawn.

07:37.920 --> 07:45.180
So we're going to say if and we can do a rand range like we've done before F math Rand range.

07:46.660 --> 07:49.840
We'll get a random value between 1 and 100.

07:50.680 --> 07:54.670
And see if it's less than item dot chance to spawn.

07:54.700 --> 08:00.790
Now chance to spawn is a float, so if you wanted to, you could make this float math.

08:00.790 --> 08:04.390
You could make this a float Randrange.

08:04.390 --> 08:10.300
You could use f randrange and use one dot f and 100 dot f if you wanted to do that.

08:10.300 --> 08:11.860
Totally up to you.

08:12.220 --> 08:18.970
But once we've done this, then we'll know for this particular item whether we should spawn it this

08:18.970 --> 08:20.320
particular time.

08:20.320 --> 08:27.040
And if your luck is really good, then for each of the iterations of this loop will spawn an item.

08:27.040 --> 08:32.590
We'll actually add it to this return items array and eventually spawn it later on down the pipeline.

08:32.590 --> 08:41.170
But with perfect roles of this 100 sided die, the best you can do is spawn max number to spawn for

08:41.170 --> 08:42.010
each item.

08:42.130 --> 08:47.950
So if we pass this if check then I'll make a new f loot item called new item.

08:49.330 --> 08:56.680
And I'll go ahead and take new item and set its loot class equal to item dot loot class.

08:57.490 --> 09:07.630
I'll set new item dot be loot level override to item dot be loot level override and then add this to

09:07.630 --> 09:08.470
return items.

09:08.470 --> 09:16.750
We'll say return items dot add not unique because we're going to be adding copies of the same one depending

09:16.750 --> 09:20.050
on max number to spawn and depending on this die roll.

09:20.050 --> 09:26.050
So we're going to add new item as a copy potentially multiple times.

09:26.050 --> 09:27.550
And then we'll add return items.

09:27.550 --> 09:34.720
So if we loop over return items we could go on to spawn one actor for each of the items in here.

09:34.720 --> 09:42.940
So each loot item, even though there might just be one in our loot tiers, loot items array depending

09:42.940 --> 09:48.880
on the chance to spawn and the max number to spawn, there may be duplicates and return items which

09:48.880 --> 09:51.010
results in us spawning them multiple times.

09:51.010 --> 09:53.530
Okay, so we have a data asset.

09:53.530 --> 09:55.780
We could fill that in in the editor.

09:55.810 --> 10:02.560
Our next step is to go ahead and create the ability to spawn loot whenever an enemy dies.

10:02.560 --> 10:04.120
That's something I'd like to do.

10:04.120 --> 10:12.370
So this I'd like to handle most of it in blueprint, because it's going to be something that will be

10:12.370 --> 10:17.710
easier to implement in blueprint, especially if we're spawning multiple items from an enemy.

10:17.710 --> 10:22.090
Let's say we'd like to spawn them one after the other with a short delay in between.

10:22.090 --> 10:27.790
That kind of async type stuff is easy to do in blueprint and see the flow of logic, so I'd like to

10:27.790 --> 10:35.680
do that in blueprint, and for that reason I'm just going to go to my aura enemy class and add a blueprint

10:35.680 --> 10:38.620
implementable event for spawning loot.

10:38.830 --> 10:47.860
So we'll go ahead and go to the character folder into Aura Enemy and just add a function here to spawn

10:47.860 --> 10:48.670
loot.

10:48.670 --> 10:51.310
We can make it a protected function.

10:52.090 --> 10:59.110
It can be a void function called Spawn loot, and we can make this a blueprint implementable event.

10:59.440 --> 11:02.080
So blueprint implementable event.

11:02.080 --> 11:05.350
And we can simply call this when the enemy dies.

11:05.350 --> 11:07.690
And that can be on the server.

11:07.690 --> 11:13.570
We can go to the enemies die function and simply call spawn loot.

11:13.570 --> 11:18.130
We could do it right before calling super Die spawn loot.

11:18.160 --> 11:24.100
Now when we spawn loot, even though we're implementing this in blueprint, we're going to need to access

11:24.100 --> 11:25.120
the data asset.

11:25.120 --> 11:33.190
It needs to exist somewhere, and since we'll be spawning loot on the server, we could put this onto

11:33.190 --> 11:34.510
the game mode class.

11:34.510 --> 11:40.960
And when an enemy dies, we could simply retrieve that data asset from the game mode, perhaps with

11:40.960 --> 11:45.160
a blueprint function library function that's static.

11:45.160 --> 11:46.450
So we could do that.

11:46.450 --> 11:52.030
So if we're going to add it to the game mode we need to go to aura game mode base and add a new data

11:52.030 --> 11:52.840
asset.

11:52.990 --> 11:54.880
Let's find where we have our others.

11:54.880 --> 11:55.660
They're up here.

11:55.660 --> 12:03.160
We can simply copy one of these and paste it and change its type from what it was before to you.

12:03.160 --> 12:12.640
Loot tears and add a forward declaration and call this loot tears and change the category to Loot tears.

12:12.640 --> 12:22.300
And we can simply make a function to retrieve this in our ability system library, much like get ability

12:22.300 --> 12:23.440
info for instance.

12:23.440 --> 12:33.100
So I can simply copy this function, paste it beneath and call this get Loot tears and this can retrieve

12:33.100 --> 12:35.260
a you loot tears.

12:37.630 --> 12:44.290
Object, we can forward declare it here and generate the definition, and it can be very similar to

12:44.290 --> 12:50.980
get ability info, we can copy its definition here where we're getting our game mode returning null

12:50.980 --> 12:52.690
if the game mode is null.

12:52.690 --> 12:56.410
Otherwise get the game mode and return loot tears from it.

12:56.410 --> 13:01.960
And that's going to result in the inclusion of the correct header here, at least with writers auto

13:01.960 --> 13:02.500
include.

13:02.500 --> 13:08.410
And now we have a get loot tears, which we can call from blueprint to get the loot tears provided that

13:08.410 --> 13:10.540
we check for validity, of course.

13:11.650 --> 13:15.640
So with that, our enemies are calling spawn loots.

13:15.640 --> 13:17.290
It's up to us to implement that.

13:17.290 --> 13:24.340
We can implement it in blueprint and we have to create this data asset, fill it in and add it to our

13:24.340 --> 13:28.300
aura game mode base blueprint so that we can access that.

13:28.300 --> 13:30.610
So a couple things to do in the editor.

13:30.610 --> 13:32.290
Let's compile and launch.

13:32.710 --> 13:39.520
So back in the editor we can make our data asset blueprint and ability system data.

13:39.670 --> 13:41.380
We'll make a new one here.

13:41.620 --> 13:43.390
We'll go to miscellaneous.

13:43.980 --> 13:44.550
Data.

13:44.550 --> 13:45.360
Asset.

13:45.360 --> 13:46.410
Searching for loot.

13:46.440 --> 13:47.280
Tears.

13:47.920 --> 13:51.970
And we'll make our da lute tears.

13:53.110 --> 13:55.660
So what is lute tears going to contain?

13:55.690 --> 13:59.980
Well, it has under the spawning category, lute items.

13:59.980 --> 14:05.200
And we can click plus to add one, expand its dropdown and choose a lute class.

14:05.620 --> 14:09.280
So for the lute class we can search for a couple things.

14:09.280 --> 14:15.310
We can search for beep health potion and give it a chance to spawn for testing purposes.

14:15.310 --> 14:22.900
I'm going to give it 100% chance to spawn and about three, not 33, but three max numbers to spawn,

14:22.900 --> 14:26.710
which should result in spawning three each time.

14:26.710 --> 14:32.620
And for lute level override, well, we can decide what to do with that boolean when we spawn it.

14:32.620 --> 14:34.360
Now that's for the health potion.

14:34.360 --> 14:37.630
I'm going to add another for the Mana Potion.

14:37.630 --> 14:44.260
So choosing Mana Potion and again for testing purposes, I'll set the chance to spawn to 100 and the

14:44.260 --> 14:46.660
number to spawn to three.

14:46.660 --> 14:47.740
The max number.

14:47.740 --> 14:51.880
And we'll add another one for our crystals, one for each.

14:51.880 --> 14:56.470
We'll have a BP health crystal again 100% chance to spawn.

14:56.470 --> 15:05.230
We'll spawn two of them and our mana crystal BP mana Crystal 100% chance to spawn and we'll spawn two

15:05.230 --> 15:05.800
of them.

15:05.800 --> 15:12.370
Now with these numbers, we should be spawning six potions and four crystals, all from the same enemy

15:12.400 --> 15:14.110
100% of the time.

15:14.110 --> 15:21.370
That's a lot to spawn in one place, so we're going to want to devise a method to separate them out

15:21.370 --> 15:22.480
somehow, right?

15:22.480 --> 15:31.600
So let's go into our enemy base blueprint as we're going to implement Spawn Lute so we can go to BP

15:31.600 --> 15:34.390
enemy base and implement spawn lute.

15:34.390 --> 15:41.770
So we're going to type spawn lute, get event spawn lute and figure out how we can spawn the lute.

15:41.770 --> 15:43.390
What are we going to do here.

15:43.390 --> 15:47.380
Now the first thing we need is the lute tears data asset.

15:47.380 --> 15:48.250
Right.

15:48.250 --> 15:55.450
That's the first thing we have to do is get that so we can right click type get lute tears.

15:55.450 --> 15:59.170
And here's our ability system library function.

15:59.170 --> 16:01.180
It needs a world context object.

16:01.180 --> 16:07.840
And in hindsight I think it would have been better if we went to our ability system library and set

16:07.840 --> 16:10.750
that world context object to default to self.

16:10.750 --> 16:18.970
Now we do have an example of how to do that in our meta attributes up here for get spell menu widget

16:18.970 --> 16:25.000
controller, for example, I'm going to copy that and place it right here in the U function for lute

16:25.000 --> 16:25.210
here.

16:25.210 --> 16:29.560
So next time we compile we'll have that defaulted to self.

16:30.000 --> 16:34.140
But for now I can get a reference to self and pass it in.

16:34.380 --> 16:39.450
Now we need to check to make sure this is a valid loop tiers data asset.

16:39.450 --> 16:44.250
So is valid and will only continue if it is.

16:44.340 --> 16:46.620
Let's give ourselves some room here.

16:46.860 --> 16:48.900
I'm going to move this off to the side.

16:49.080 --> 16:53.790
And let's think about what we're going to do with get loot tiers.

16:54.030 --> 16:58.530
Remember, get loot tiers has a function to get the loot items right.

16:58.530 --> 17:01.260
We have this get loot items.

17:01.620 --> 17:03.990
Now we can make this blueprint callable.

17:03.990 --> 17:07.830
And then we could call it in the Enemy Blueprint.

17:07.830 --> 17:09.000
I'd like to do that.

17:09.000 --> 17:11.460
So I'm going to give it a new function macro.

17:13.330 --> 17:14.980
Give it blueprint callable.

17:14.980 --> 17:18.040
And for that reason I'm going to recompile.

17:18.040 --> 17:22.270
So we'll close down and come back in and we'll see those two new changes.

17:22.270 --> 17:24.460
So let's go ahead and run this.

17:25.640 --> 17:28.160
And let's get that blueprint back open.

17:28.160 --> 17:32.750
Here in BP enemy base, we can go back to event spawn loot.

17:32.750 --> 17:39.590
We no longer need to pass the self in that's defaulted to self and from our loot tiers.

17:39.590 --> 17:43.820
If it's valid, we can call get loot items.

17:43.850 --> 17:49.100
Notice there's a getter for the loot items array, but that's not what we want because the function

17:49.100 --> 17:55.580
is going to return a different array that could have less or more depending on chances to spawn with.

17:55.580 --> 17:58.070
The numbers we've configured will have more.

17:58.070 --> 18:02.900
So we're going to get the loot items first thing, and we're going to promote this to a variable.

18:02.900 --> 18:05.390
So we have this as a variable.

18:05.390 --> 18:07.490
We'll call it loot items.

18:07.490 --> 18:11.810
And at this point we can decide how to spawn these.

18:11.960 --> 18:15.470
Now I don't want to spawn them all at the same location.

18:15.470 --> 18:19.340
I want them spread out a little bit around the enemy.

18:19.340 --> 18:21.950
So in the viewport, here's the enemy.

18:21.950 --> 18:24.350
And let's say I'm spawning four items.

18:24.350 --> 18:29.630
I'd like to spawn them spread out evenly, perhaps along these grid lines.

18:29.630 --> 18:30.080
Right.

18:30.080 --> 18:33.740
And we have a function that can give us evenly spaced rotators.

18:33.740 --> 18:41.000
If we right click and type evenly spaced rotators, we have this function to give us evenly spaced rotators.

18:41.000 --> 18:50.750
Now this requires a spread for one which 360 means spread these rotators out 360 degrees, right.

18:50.750 --> 18:53.300
It also requires a number of rotators.

18:53.300 --> 18:56.270
And that's going to be how many items we want to spawn.

18:56.270 --> 19:00.350
Conveniently, that's how many items are in my loot items array.

19:00.350 --> 19:03.440
So I need to get the number right.

19:04.400 --> 19:09.890
We can get the length and we can hook that in to num rotators.

19:09.890 --> 19:13.790
Now forward is going to be the enemies forward vector.

19:13.790 --> 19:16.250
That's as good a forward vector as any.

19:16.250 --> 19:19.490
So get actor forward vector can go in here.

19:19.610 --> 19:23.420
And for the axis we can get the up vector.

19:23.540 --> 19:28.010
So the vectors get up vector function requires a rotator.

19:28.340 --> 19:33.560
There's also vector up 3D vector unreal up direction constant.

19:33.560 --> 19:34.880
That's the one we'd like.

19:34.880 --> 19:37.100
So we'll pass that in as the axis.

19:37.100 --> 19:43.970
And now we have evenly spaced rotators which we can also promote to a variable.

19:43.970 --> 19:50.090
So promoting this to a variable I'm going to have I'll just call this loot rotations.

19:51.350 --> 19:57.170
So we have loot items, we have loot rotations and this function could easily be collapsed.

19:57.170 --> 20:00.800
In fact, really all of this could be easily collapsed.

20:00.800 --> 20:04.700
But I'd like to keep things very organized.

20:04.700 --> 20:10.970
So I'm going to take this set of nodes and collapse it to a function and call this.

20:11.630 --> 20:16.490
Get loot rotations and make this a blueprint pure function.

20:19.920 --> 20:26.490
Now once we have our loot rotations and loot items, I would like to spawn them one after the other.

20:26.490 --> 20:30.210
Now that means I don't want to use a for each loop.

20:30.210 --> 20:38.550
I'd rather use a timer that I can fire an event off repeatedly, and for that I can call set timer by

20:38.550 --> 20:42.420
event and I can create a custom event.

20:44.140 --> 20:49.330
And this can be called spawn loot item.

20:49.330 --> 20:50.710
And I can hook this up.

20:50.710 --> 20:56.680
And I'd like this to be looping with a time of say 0.1.

20:56.800 --> 21:05.200
So 0.1 seconds between each time and I can promote the timer handle to a variable called loot timer.

21:06.760 --> 21:11.410
And I can even start this off by calling spawn loot item.

21:12.340 --> 21:13.450
First thing.

21:15.430 --> 21:22.690
Now each iteration of the loop, I'm going to want to keep track of how many times this has happened.

21:22.720 --> 21:31.270
So in spawn loot item, I'm going to want to increment a loop count, and that means I'm going to need

21:31.270 --> 21:35.200
to know how many times this loop has occurred.

21:35.320 --> 21:43.330
So I'm going to make a new variable for this called spawn loop count.

21:44.380 --> 21:46.210
This will be an integer.

21:46.720 --> 21:49.990
And I'm going to first of all set it to zero.

21:49.990 --> 21:53.320
Set spawn loop count here to zero.

21:54.540 --> 21:58.890
And we'll increment it each time.

21:59.040 --> 22:03.810
But first we're going to use that loop count to index our arrays.

22:03.810 --> 22:09.210
We're going to want to spawn an actor and set some information on that actor.

22:09.210 --> 22:17.310
We'll want to spawn it at a specific location and perhaps spread these out from the center of the enemy.

22:17.310 --> 22:24.840
So if I spawn this for a given loot actor, I can rotate the loot actor to a given rotation so it's

22:24.840 --> 22:31.680
facing sort of offset from the enemy's forward vector, and then I can move it in its own forward direction,

22:31.680 --> 22:34.770
out just a little bit so that it's spread out.

22:34.770 --> 22:37.140
And each of these can be rotated evenly.

22:37.140 --> 22:40.950
So what I'm going to want is first of all a rotation.

22:40.950 --> 22:43.710
And I can get that from loot rotations.

22:43.710 --> 22:52.830
If I get loot rotations and I use get I can get a copy or a ref either one and I can get spawn loop

22:52.830 --> 22:53.550
count.

22:53.550 --> 22:58.800
And for the first one this will be the first rotation, the second one will give me the second, and

22:58.800 --> 22:59.430
so on.

22:59.430 --> 23:08.100
So this gives me a rotation and I can get the location of the enemy base with get actor location.

23:08.220 --> 23:15.930
And I can take this actor location and I can add a vector to it in the direction of this location.

23:15.930 --> 23:23.400
So if I take this location and call get forward vector, this is the Kismet math library function that

23:23.400 --> 23:28.950
gives me a forward vector from a rotator, so I can get the forward vector from this rotator.

23:28.950 --> 23:40.020
And if I add this to get actor location, I now have a location that is at the enemy's location, plus

23:40.020 --> 23:44.580
a vector pointing outward in the direction of that rotator.

23:45.690 --> 23:54.480
So if I add these together with vector addition, that gives me a new location, and I can even scale

23:54.480 --> 24:01.560
this by some distance so that all these items are evenly spaced from the enemy.

24:01.560 --> 24:05.370
For example, I can multiply this forward vector.

24:06.600 --> 24:11.340
And I can right click on this pin to convert its type.

24:12.660 --> 24:14.040
To afloat.

24:14.740 --> 24:22.750
Single precision, and I can promote this to a variable and call this spawn distance.

24:23.590 --> 24:28.600
And this means that this vector created from the rotator.

24:29.130 --> 24:31.890
Will now be scaled by spawn distance.

24:31.890 --> 24:39.660
And if we add that instead, well, now our spawn location is a little farther away from the enemy.

24:39.660 --> 24:43.770
So now we have this vector that we can use for a location.

24:43.770 --> 24:48.630
And we also have this rotator that we can use for a rotation.

24:48.630 --> 24:50.310
And we can make a transform.

24:50.310 --> 24:53.940
If I take this vector I can call make transform.

24:55.080 --> 24:57.450
We'll make a transform from this vector.

24:57.450 --> 25:01.560
And we'll use the rotation here for the rotation.

25:05.900 --> 25:07.100
So with that.

25:08.230 --> 25:10.000
We now have a transform.

25:14.260 --> 25:17.140
And this depends on the spawn loop count.

25:18.420 --> 25:22.980
So now that we have a transform, we can spawn the actor at that transform.

25:22.980 --> 25:28.380
So that means we need to take our loot items array and we need to get.

25:28.380 --> 25:34.890
We can call get, we can get a ref or a copy, and we can get our spawn loop count here and get this

25:34.890 --> 25:37.560
item which is a struct.

25:37.560 --> 25:38.850
And we can break it.

25:38.850 --> 25:45.750
And if we break it, then we have the class the chance to spawn, the max number to spawn, and the

25:45.750 --> 25:47.100
loot level override.

25:47.100 --> 25:53.430
Now we don't need actually chance to spawn or max number to spawn, because those were already taken

25:53.430 --> 25:56.640
into account when creating the loot items array.

25:56.640 --> 26:03.150
So if we wanted to foolproof this and make sure that no one in blueprints uses these thinking that they

26:03.150 --> 26:10.050
should use them, we could actually remove these from exposure to the event graph, and we could even

26:10.050 --> 26:17.970
remove our array in the data asset, because we saw that we could have accessed the array directly instead

26:17.970 --> 26:19.350
of get loot items.

26:19.350 --> 26:23.940
And then of course our loot items would not contain the same information.

26:23.940 --> 26:29.760
So what I'm going to do is go ahead and remove blueprint read only from chance to spawn and max number

26:29.760 --> 26:30.570
to spawn.

26:30.570 --> 26:38.160
So back here in loot tiers, we can take blueprint read only away from chance to spawn and max number

26:38.160 --> 26:39.120
to spawn.

26:39.120 --> 26:44.430
And then our loot items could be no longer blueprint read only.

26:44.430 --> 26:49.770
And then we're forced to get loot items here, which already takes these two into account.

26:49.770 --> 26:55.950
So in blueprint we don't need to see those that would just confuse us into thinking we should use them

26:55.950 --> 26:57.000
here when we shouldn't.

26:57.000 --> 27:00.240
So now that we have the loot class, we can spawn an actor.

27:02.250 --> 27:07.440
Using spawn actor from class passing in the class we have the transform we can pass.

27:07.440 --> 27:11.220
In the transform I'd like to use always spawn.

27:11.220 --> 27:12.600
Ignore collisions.

27:14.480 --> 27:16.940
And we'll hook this up to spawn loot item.

27:17.510 --> 27:22.340
And after we've spawned a single item, we need to increase that spawn loop count.

27:22.340 --> 27:25.130
And we also need a way to get out of this loop.

27:25.130 --> 27:30.590
If that spawn loop count is higher, is high enough so we can take spawn loop count.

27:30.590 --> 27:34.100
We can increment it by one using plus plus.

27:36.990 --> 27:41.700
And before we even do anything here, we should check the spawn loop count.

27:41.700 --> 27:46.440
So let's move these nodes a little bit over and make a branch.

27:49.890 --> 27:55.380
And we'll check spawn loop count and make sure spawn loop count is less than.

27:57.490 --> 28:01.000
The number of loot items so we can use.

28:02.260 --> 28:03.580
Loot items.

28:05.410 --> 28:13.360
Get the length and make sure that spawn loop count is always less than that before we continue.

28:13.360 --> 28:17.560
And if it's less than, then we can spawn.

28:18.220 --> 28:20.740
If it's not less than.

28:20.830 --> 28:23.830
In other words, we should stop the loop.

28:23.860 --> 28:29.440
Then we can clear and invalidate the timer so we can move these up or to the right.

28:29.440 --> 28:36.700
And we can take our loop timer and call clear and invalidate timer by handle.

28:37.980 --> 28:40.350
So there's our out for the loop.

28:40.350 --> 28:43.200
So we have an asynchronous loop like so.

28:43.200 --> 28:50.910
Now this here is basically performing a calculation that depends on spawn loop count.

28:50.910 --> 28:56.370
So we could make this a function to get the spawn transform for loop.

28:56.370 --> 29:04.950
So I can collapse this to a function, get loot transform and make it a blueprint pure function.

29:06.870 --> 29:08.820
And this depends on.

29:09.550 --> 29:11.170
Spawn loop count.

29:11.170 --> 29:13.420
So we'll call this loop count.

29:14.840 --> 29:17.480
And return value will be spawn.

29:17.480 --> 29:18.650
Transform.

29:20.520 --> 29:23.700
So that cleans up the nodes here a bit.

29:27.740 --> 29:31.400
Now here we have loot level override.

29:32.320 --> 29:33.910
And we can check this.

29:36.400 --> 29:41.950
We can set the lute's level if lute level override is true.

29:41.980 --> 29:47.320
We can just set it right here based on the enemy's level.

29:47.530 --> 29:50.530
Now, in order to do that, we'd have to cast it.

29:50.530 --> 29:58.390
And if our lute is, say, an effect actor, well, I believe our effect actor has a level, doesn't

29:58.390 --> 29:58.540
it?

29:58.540 --> 30:02.950
If we go to, let's say, a potion and open it up.

30:02.950 --> 30:05.650
This is an effect actor, of course.

30:05.650 --> 30:10.270
And the effect actor has a level called actor level.

30:10.540 --> 30:14.050
So if we want to override it, we can.

30:14.050 --> 30:15.700
I'm just going to reroute it.

30:20.050 --> 30:21.640
And add a branch.

30:23.980 --> 30:28.210
And if this is true, we can take the spawned actor.

30:29.560 --> 30:32.440
I'm going to move this count for now.

30:32.440 --> 30:34.210
We'll take the spawned actor.

30:34.750 --> 30:39.070
I'm going to cast to aura effect actor.

30:41.440 --> 30:42.850
And if it's valid.

30:42.850 --> 30:44.440
And this is true.

30:45.230 --> 30:50.690
Then I'll take Aura Effect actor and get its actor level.

30:51.890 --> 30:53.480
And set it.

30:53.510 --> 30:56.930
Of course we'd have to make it blueprint read write for that.

30:56.930 --> 30:58.790
So two aura effect.

30:58.790 --> 31:01.610
Actor two actor level.

31:02.210 --> 31:04.880
Changing this from blueprint read only to blueprint.

31:04.880 --> 31:05.330
Read.

31:05.330 --> 31:06.140
Write.

31:07.630 --> 31:10.780
And with that, we'll need to restart again.

31:11.500 --> 31:14.560
So closing down and recompiling.

31:14.770 --> 31:21.700
Another alternative to needing to set this would be to just restrict our loot tiers, not to actors,

31:21.700 --> 31:30.010
but to our effect actors or some other pickup class, and only spawn those and then make their actor

31:30.010 --> 31:35.680
level exposed on spawn using the expose on spawn meta specifier.

31:35.680 --> 31:39.010
But either way, back to our.

31:39.800 --> 31:44.120
Enemy base after casting as aura effect actor.

31:44.120 --> 31:48.350
If this boolean is true, then we're going to set actor level.

31:51.720 --> 31:54.630
And we'll set that equal to level.

31:54.810 --> 31:58.530
We can get from character class defaults our level.

31:58.560 --> 32:01.380
It's going to convert to a float.

32:03.570 --> 32:04.530
Okay.

32:06.310 --> 32:07.360
Now here's the thing.

32:07.360 --> 32:13.840
We need to increment spawn loop count whether or not this cast succeeds and whether or not this boolean

32:13.840 --> 32:14.800
is true.

32:14.800 --> 32:16.270
So I'm going to set it.

32:16.270 --> 32:19.030
Before we even try any of those things.

32:19.030 --> 32:20.380
We'll set it right here.

32:20.470 --> 32:26.560
With that, we should be spawning loot so we can compile and test this out.

32:26.560 --> 32:33.460
We do need to make sure, however, that our game mode in Game Beep or Game mode has loot tiers set.

32:33.460 --> 32:36.160
So we need to make sure that's set there.

32:36.160 --> 32:37.420
Now it is.

32:37.420 --> 32:39.370
And we can test this out.

32:40.660 --> 32:43.180
So we need to slay one of these enemies.

32:43.180 --> 32:46.630
And I can't because I didn't load in with any spells.

32:46.630 --> 32:49.060
I have to load in through the load menu.

32:49.060 --> 32:49.810
Now.

32:49.840 --> 32:53.620
I'll go ahead and delete this slot and make a new one.

32:55.560 --> 32:59.850
Will spawn some enemies and we'll go ahead and kill them.

33:08.780 --> 33:10.970
And there we go.

33:10.970 --> 33:16.310
Now our distance is zero, so we're not actually spawning them.

33:16.310 --> 33:17.660
Okay, so I got an error.

33:17.660 --> 33:24.890
Attempted to access index ten from an array loot items of length ten, which means we need to go back

33:24.890 --> 33:32.330
to where we're checking our spawn loop count and make sure that our spawn loop count is never greater

33:32.330 --> 33:34.790
than our loot items array.

33:34.790 --> 33:35.660
Right?

33:35.930 --> 33:40.130
So we do need to make sure not to have a.

33:41.610 --> 33:43.020
Off by one error.

33:43.020 --> 33:49.890
So let's take our loot items length and we'll use loot items length minus one.

33:50.340 --> 33:52.980
So we don't try to access that array out of bounds.

33:52.980 --> 33:54.450
Blueprints is more forgiving.

33:54.450 --> 34:01.230
We get an error rather than a crash when it's in blueprint when the violation is in blueprint.

34:01.230 --> 34:04.470
Let's try this again and make sure there are no errors.

34:08.520 --> 34:10.350
And I'm seeing some loot.

34:16.380 --> 34:18.900
And no errors when I stop.

34:19.170 --> 34:28.860
Now in enemy base where pushing that spawn location and get loot transform pushing it out by spawn distance.

34:28.860 --> 34:32.370
But this doesn't have a value if I give it a value of 50.

34:32.400 --> 34:38.640
Now we should see that loot spawned 50 units away.

34:45.220 --> 34:45.970
There it is.

34:46.000 --> 34:47.830
And it spawns out in a circle.

34:52.440 --> 34:53.610
There we go.

34:54.150 --> 34:57.180
So it spawns out in a nice arc there.

34:57.180 --> 35:00.810
And of course I picked up a few of them, so there's that.

35:00.810 --> 35:03.570
But now I'm getting a blueprint.

35:03.570 --> 35:04.440
Runtime error.

35:04.440 --> 35:10.890
Attempted to access BP Health Potion C5 via Property Dynamic Cast.

35:10.890 --> 35:16.650
So we're casting here, but BP Health Potion C5 is not valid pending kill.

35:16.650 --> 35:25.620
So I picked up a potion and because I picked it up, it was pending kill, which means that attempting

35:25.650 --> 35:29.460
to access it here to set properties on it, we were too late.

35:29.460 --> 35:37.380
So the cast needs to also be accommodated by an invalid node as well.

35:37.380 --> 35:43.380
So we can use is valid here and we could only continue if is valid is true.

35:44.080 --> 35:46.030
That should fix that problem.

35:46.060 --> 35:50.200
Of course, that means if we pick it up too soon, we won't override its level.

35:50.200 --> 35:54.550
So for that reason, you may wish to go ahead and.

35:59.740 --> 36:00.430
There we go.

36:00.430 --> 36:01.630
We got that same problem.

36:01.630 --> 36:06.700
You may wish to go ahead and use expose on spawn for those cases.

36:06.700 --> 36:07.330
Okay.

36:07.330 --> 36:13.960
So now that we're spawning these and we're spawning them out in a circle around the enemy, we could

36:13.960 --> 36:15.910
also randomize that distance.

36:15.910 --> 36:17.050
If we wanted to.

36:17.050 --> 36:20.020
We could go to get loot transform.

36:20.020 --> 36:28.120
And for spawn distance we can set spawn distance based on a minimum and a maximum we can say.

36:29.360 --> 36:31.970
Random float and range.

36:34.280 --> 36:37.610
And we can promote min and max to variables.

36:37.610 --> 36:38.960
Promote to variable.

36:38.960 --> 36:40.430
We'll call this.

36:41.600 --> 36:44.390
Min spawn distance.

36:45.430 --> 36:51.520
And we'll promote this to a variable, not local max spawn distance.

36:53.940 --> 37:01.650
And then if we set these min spawn distance and max spawn distance variables, say minimum of 50 and

37:01.650 --> 37:04.470
max spawn distance of 100.

37:04.470 --> 37:10.650
Now, as soon as we create this random float, though, we are no longer going to need spawn distance

37:10.650 --> 37:21.030
and we can simply delete that variable and use our random value, which means this multiply still needs

37:21.030 --> 37:21.990
this one.

37:21.990 --> 37:24.690
This input pin a float.

37:24.690 --> 37:27.390
So we'll plug that in like so.

37:27.390 --> 37:30.510
And now spawn distance is no longer needed.

37:30.990 --> 37:32.700
And we can try this out.

37:32.700 --> 37:36.450
Looks like I have some visual artifacts that I'm going to need to restart.

37:36.450 --> 37:37.050
The editor.

37:37.050 --> 37:41.460
Sometimes that happens in the engine but a restart will fix that.

37:41.460 --> 37:42.180
There we go.

37:42.180 --> 37:44.430
So we do have some randomness now.

37:46.910 --> 37:56.960
Mean spawn distance could be, say, 25 and max spawn distance could be a bigger value, say 150, for

37:56.960 --> 37:57.860
instance.

38:07.420 --> 38:09.490
And that's going to give us a bigger spread.

38:12.840 --> 38:15.630
So that gives us more randomness to it.

38:15.870 --> 38:19.980
Now we may wish to have some nicer looking pickups.

38:19.980 --> 38:24.570
They might need some bobbing or sinusoidal behavior so we can add that as well.

38:24.570 --> 38:31.590
But for now we have our loot system in place and we can change our chances to spawn the number we can

38:31.590 --> 38:34.290
spawn, and so on here in our loot tiers.

38:34.290 --> 38:37.320
And so this gives us some options for spawning loot.

38:37.680 --> 38:38.400
All right.

38:38.400 --> 38:40.890
Excellent job and I'll see you in the next video.
