WEBVTT

00:06.810 --> 00:07.890
Welcome back.

00:07.920 --> 00:09.540
Now things are looking pretty cool.

00:09.540 --> 00:15.540
We can level up and as we level up, we see our level up here in the HUD change.

00:16.440 --> 00:18.870
Goes from 1 to 2, which is great.

00:18.900 --> 00:24.270
Now, we could continue testing that and go up to level three, but we'll do plenty of testing throughout

00:24.270 --> 00:25.110
the course.

00:25.140 --> 00:27.330
We can also test in multiplayer.

00:28.630 --> 00:29.590
So.

00:31.020 --> 00:32.490
We have our.

00:33.050 --> 00:34.400
Client here.

00:37.730 --> 00:40.790
See if I can actually get enough XP to level up.

00:40.790 --> 00:41.240
There we go.

00:41.240 --> 00:42.500
And it works on the client.

00:42.500 --> 00:49.700
So things are working there, but usually a level up is accompanied by some dramatic effects, some

00:49.700 --> 00:51.110
sound, some particles.

00:51.110 --> 00:55.220
We need more than just this number changing that's barely even noticeable.

00:55.250 --> 00:57.770
We need something better than that.

00:57.800 --> 01:00.770
So we'll start with a particle effect.

01:00.770 --> 01:05.990
But we also want to show something in the HUD that lets us know that we've leveled up and what level

01:05.990 --> 01:06.950
we've reached.

01:06.950 --> 01:08.930
So first things first.

01:08.960 --> 01:10.400
We need a particle effect.

01:10.400 --> 01:14.870
Let's go into our assets folder, into effects.

01:14.900 --> 01:19.220
Notice there's a level up folder and we can take a look at this system.

01:19.220 --> 01:21.920
Now here's what it looks like, actually.

01:21.920 --> 01:23.690
Looks pretty amazing.

01:23.840 --> 01:29.810
We have some sparkles, we have some gold kind of vapor smoke looking stuff.

01:29.810 --> 01:35.360
I'd like to spawn this and I'd like to spawn it at the location of our character.

01:35.360 --> 01:38.250
So that's what we're going to start out with.

01:38.550 --> 01:40.650
So I'm going to close the editor.

01:40.830 --> 01:48.960
I'm going to go into my character class, so I'm going to go ahead and just close all tabs and go into

01:49.290 --> 01:57.000
public character and we'll just put it in or a character or a character is the only character that will

01:57.000 --> 01:58.470
level up in this game.

01:58.800 --> 02:04.790
And I'm just going to go ahead and put a t object pointer here for a U.

02:04.800 --> 02:06.420
Niagara component.

02:08.550 --> 02:15.420
So we'll just have this Niagara component as a component on the character and then we can activate it

02:15.420 --> 02:17.100
every time we level up.

02:17.280 --> 02:27.540
So we'll call this level up Niagara component and I'd like to be able to see it and set its Niagara

02:27.540 --> 02:29.310
system in the editor.

02:29.310 --> 02:32.730
And since it's a component, we give it visible anywhere.

02:32.910 --> 02:36.930
I'm going to make it blueprint read only and we'll go ahead and create this.

02:36.930 --> 02:38.390
And the constructor.

02:38.390 --> 02:43.940
So up in the constructor at the very top, I'm going to say level up.

02:44.060 --> 02:51.980
Niagara component equals we're going to use create default Subobject with you, Niagara.

02:53.390 --> 02:59.870
Component and I'm going to just call this level up Niagara component.

03:02.890 --> 03:11.770
Now I'm going to need to include Niagara component, and that's simply going to be include Niagara component.

03:12.760 --> 03:18.130
Dot age and I'm going to go ahead and attach this straight to Ora's root component.

03:18.370 --> 03:24.970
So we'll take level up Niagara component call, set up attachment and get root component.

03:25.840 --> 03:28.810
Now, we don't want this activated automatically.

03:28.810 --> 03:34.900
So there's a variable we can set on Niagara components so they don't automatically activate.

03:34.930 --> 03:39.940
So we're going to take our component level up Niagara component and set that Boolean.

03:39.940 --> 03:42.820
It's called Be Auto Activate.

03:43.390 --> 03:45.070
We're going to set that to false.

03:45.490 --> 03:49.510
So we have to activate this and we'll do that every time we level up.

03:49.600 --> 03:53.890
So let's go ahead and do that in our level up function.

03:54.190 --> 03:55.120
So here it is.

03:55.120 --> 03:56.920
It's level up implementation.

03:56.920 --> 03:58.150
But here's the thing.

03:58.150 --> 04:01.720
Level up implementation is only called on the server, right?

04:01.840 --> 04:08.080
And that's okay in a single player game, but we're going to want this spawned everywhere.

04:08.080 --> 04:10.820
I'd like everyone to see when everyone levels up.

04:10.840 --> 04:14.530
So for that reason we should make a multicast RPC.

04:14.830 --> 04:22.480
So here in our character in the private section, I'm just going to make a little void function called

04:22.480 --> 04:26.480
level up particles, and it's going to be a multicast.

04:26.480 --> 04:33.860
So I'm going to call it multicast level up particles actually, and it can be a const function and we'll

04:33.860 --> 04:44.510
make it a new function with net multicast reliable, you can make it unreliable, but I'd like it to

04:44.510 --> 04:45.420
be reliable.

04:45.440 --> 04:51.230
I'm going to generate a definition and it has to have implementation in it and we're going to call this

04:51.230 --> 04:59.870
multicast level up particles in our implementation of the level up function right here, level up implementation.

04:59.870 --> 05:04.910
We'll just call our net multicast and we'll handle this here in the net multicast, which I'm going

05:04.910 --> 05:09.770
to cut and move up to just beneath level up implementation.

05:10.310 --> 05:10.730
Okay.

05:10.730 --> 05:13.190
So we have our level up Niagara component.

05:13.220 --> 05:14.540
We'll check it.

05:16.290 --> 05:25.320
So we'll use is valid level up Niagara component and we'll take level up Niagara component and activate

05:25.320 --> 05:25.710
it.

05:25.740 --> 05:33.360
We can use activate passing in a boolean for be reset and we can pass in true to reset it.

05:33.900 --> 05:41.220
So with that we can set the Niagara components Niagara system and see what happens when we level up.

05:41.550 --> 05:44.310
I'm going to go ahead and start in debug mode.

05:45.170 --> 05:50.420
Okay, so I forgot to forward declare my Niagara component.

05:50.450 --> 05:52.910
Let's go ahead and just do that real quick.

05:52.940 --> 06:00.650
I'm going to go up to the top forward, declare you Niagara component there and try again.

06:02.040 --> 06:02.430
Okay.

06:02.430 --> 06:10.950
So I can open up Aura and set her Niagara system on the Niagara component by going to blueprints, character

06:11.190 --> 06:18.420
opening, aura, aura, character and selecting level up Niagara component.

06:18.420 --> 06:24.960
And for the Niagara system asset I can search for level up and set that here.

06:25.110 --> 06:33.000
Now it's not going to activate by default as we disabled auto activate, but once we level up we should

06:33.000 --> 06:33.790
see it.

06:33.810 --> 06:38.040
So I'm going to save all and play test and just kill two goblins.

06:38.070 --> 06:39.210
There's one.

06:40.680 --> 06:41.750
And there's two.

06:41.760 --> 06:45.740
Now, this looks great, but it's oriented to aura.

06:45.750 --> 06:50.280
It's not oriented toward the camera or toward the screen.

06:51.040 --> 06:55.700
Which is okay, but I would really like to control its orientation.

06:55.720 --> 06:58.570
Let's see what happens if Aura's facing this way.

07:02.900 --> 07:03.290
Yeah.

07:03.290 --> 07:07.220
So, you know, it looks good, but I'd like it always facing the screen.

07:07.220 --> 07:10.820
So I'm going to go back and make that happen.

07:11.090 --> 07:18.680
Now I'm going to basically turn this to face the camera so I can make a const f vector for the camera

07:18.680 --> 07:23.630
location and we need the camera location.

07:23.630 --> 07:27.440
But notice that I have no camera component.

07:27.470 --> 07:31.190
That's because my camera was set up in Blueprint.

07:31.280 --> 07:38.510
So now that I need the camera in C plus plus, I'm going to need to move that camera component into

07:38.510 --> 07:40.310
C plus plus instead.

07:40.430 --> 07:47.030
So what I can do is make that a C plus plus variable now right here in my private section.

07:47.030 --> 07:52.400
And I'll go ahead and make my camera spring arm a C plus plus variable as well.

07:52.400 --> 07:57.620
So I'm going to make a T object pointer of type U camera component.

08:00.370 --> 08:07.030
I'm going to forward declare it all the way up at the top with class you camera component.

08:07.060 --> 08:10.900
While I'm here, I'm going to forward declare you spring arm component as well.

08:11.410 --> 08:13.790
And I'll make my variable for it.

08:13.810 --> 08:17.710
And I'm going to call this top down camera component.

08:18.550 --> 08:20.480
It's going to be visible anywhere.

08:20.500 --> 08:24.400
So I'll give it a new property with visible anywhere.

08:24.670 --> 08:30.580
And I'll go ahead and make another T object pointer for the spring arm component.

08:31.420 --> 08:33.910
And I'm going to call this camera boom.

08:35.380 --> 08:37.630
It's also going to be visible anywhere.

08:38.260 --> 08:46.450
Now I'm going to have to go ahead and set it up in the constructor and these will be first before our

08:46.450 --> 08:48.070
Niagara component even.

08:48.340 --> 08:51.100
So first, I'm going to construct the camera boom.

08:51.100 --> 08:56.500
I'm going to say camera boom, We're going to use create default subobject.

08:58.240 --> 09:00.400
It's going to be a youth spring arm component.

09:01.360 --> 09:04.660
I'm going to call it camera boom.

09:05.200 --> 09:10.210
I got my auto include for spring arm component here and I'm going to attach it to the root.

09:10.210 --> 09:15.790
So camera boom, set up attachment, get root component.

09:17.500 --> 09:24.820
Now, I'm going to also set some properties on it, such as set using absolute rotation.

09:25.390 --> 09:27.460
I don't want it to rotate when the character does.

09:27.460 --> 09:29.700
I'm going to use absolute rotation.

09:29.710 --> 09:36.550
We'll adjust its target arm length and its rotation in the blueprint, but I do want to take camera

09:36.550 --> 09:41.140
boom and set the boolean be do collision test to false.

09:41.770 --> 09:44.890
That way we won't even try to do the collision test.

09:45.310 --> 09:47.410
Now let's create our camera component.

09:47.410 --> 09:52.450
So top down camera component equals create default Subobject.

09:53.910 --> 10:02.880
Using new camera components, we'll call it top down camera components, and I'm going to attach it

10:02.880 --> 10:03.840
to the camera boom.

10:03.840 --> 10:12.630
So we're going to say top down camera component, set up attachment, setting it up to attach to the

10:12.630 --> 10:13.740
camera boom.

10:13.980 --> 10:24.870
And I'm going to use you spring arm component, double colon socket name, and we'll attach to the end

10:24.870 --> 10:25.910
socket there.

10:26.340 --> 10:32.130
Top down camera component also has use pon control rotation.

10:32.280 --> 10:34.260
I'm going to set that to false.

10:35.850 --> 10:40.080
Okay, so now we have a camera boom and a top down camera component.

10:40.110 --> 10:46.740
We're going to need to set that up and I'm going to go ahead and make sure we're using that in blueprint

10:46.740 --> 10:53.140
before going to my level up particles and using my camera and all that stuff.

10:53.140 --> 10:58.030
So I'm going to go ahead and run and debug mode as we got some things we need to do now.

10:59.130 --> 10:59.940
All right.

10:59.940 --> 11:07.020
So opening up our character, we're going to have two cameras and two spring arms now, and we can probably

11:07.020 --> 11:08.700
see them in the viewport.

11:08.790 --> 11:10.440
Sure enough, we do.

11:10.620 --> 11:16.740
Now, first of all, before I go and delete my camera and spring arm that I made in Blueprint, I'm

11:16.740 --> 11:21.360
going to want this box component attached to my other spring arm.

11:21.360 --> 11:25.470
So that's going to be the one called camera Boom.

11:25.470 --> 11:29.400
So I'm going to take my box component and drag it onto camera boom.

11:29.400 --> 11:31.410
So it's attached to that one.

11:31.410 --> 11:38.790
And I'm also going to go ahead and hit the curved arrow on the box for the location and the rotation

11:38.790 --> 11:45.150
and the scale for that matter, as I just want to adjust those from their defaults.

11:45.150 --> 11:50.310
But now my camera and spring arm that I had before can go away.

11:50.310 --> 11:53.520
I'm going to delete the camera and delete the spring arm.

11:53.520 --> 11:57.090
And now we have our new camera and spring arm.

11:57.300 --> 12:02.350
Now I'm going to take this camera boom and adjust its target arm length.

12:02.350 --> 12:04.210
I'll put it up to about 800.

12:04.270 --> 12:10.180
And I believe I had my rotation at about 45 degrees.

12:10.180 --> 12:17.980
I'm going to set snapping to 45 to make this easy and change its rotation to 45.

12:18.010 --> 12:22.720
It's actually -45 for its absolute rotation in the Y.

12:22.720 --> 12:28.270
And then I can take this box component and bring it down to about there.

12:28.300 --> 12:30.690
So now I have my.

12:30.710 --> 12:32.950
Cplusplus variables that I'm using.

12:32.950 --> 12:37.330
Let's just make sure nothing else breaks by testing in.

12:38.190 --> 12:38.790
The game.

12:38.790 --> 12:39.870
It looks okay.

12:43.770 --> 12:45.570
Let's go into.

12:46.400 --> 12:50.000
This area, make sure that our fade actors are fading out.

12:52.640 --> 12:53.060
Yeah.

12:53.060 --> 12:54.410
These all look okay?

12:55.440 --> 12:58.770
Now we have our camera and spring arm and C plus plus.

12:59.440 --> 12:59.800
Okay.

12:59.800 --> 13:06.660
That's all I needed because now I can orient my level up Niagara component towards the camera.

13:06.670 --> 13:08.750
So that's what I'm going to do now.

13:08.770 --> 13:11.860
So I want to get my camera's location.

13:12.040 --> 13:16.180
That's going to be a local const f vector called camera location.

13:16.180 --> 13:21.700
And I can take my top down camera component and call get component location.

13:23.740 --> 13:29.620
Now I can also take my level up Niagara component and get its component location.

13:29.740 --> 13:32.430
So I'm going to do that const F vector.

13:32.440 --> 13:41.380
I'm going to call this Niagara system location and I'm going to get my level up Niagara component.

13:41.380 --> 13:48.700
And on this one call, get component location and then I can make a rotator for the rotation from the

13:48.700 --> 13:51.220
Niagara system to the camera.

13:51.220 --> 13:56.260
And I can get that from a vector that goes from the Niagara system to the camera.

13:56.290 --> 14:01.970
That vector would be camera, location minus Niagara system location.

14:01.970 --> 14:07.190
And if I wrap this subtraction in parentheses, this returns a vector.

14:07.190 --> 14:14.840
And from this vector I can call rotation to get a rotator and I can store this in a const local rotator

14:16.100 --> 14:19.940
and I'll call this two camera rotation.

14:20.540 --> 14:27.170
Now that I have that rotation, I can set the world rotation of level up Niagara component so I can

14:27.170 --> 14:35.150
take it level up Niagara component and call set world rotation and pass in two camera rotation.

14:36.170 --> 14:41.600
And with that, my Niagara component should be rotated toward the camera.

14:41.690 --> 14:43.460
Let's test that theory.

14:44.690 --> 14:48.680
So I'm going to level up by killing two goblins.

14:49.650 --> 14:50.910
One to go.

14:51.930 --> 14:52.980
And there it is.

14:53.010 --> 14:55.530
And it looks like it was oriented correctly.

14:55.770 --> 15:02.190
Now, this is a net multicast and it's always oriented towards the camera, but it's oriented towards

15:02.190 --> 15:04.030
this character's camera.

15:04.050 --> 15:06.510
So let's see how this looks in multiplayer.

15:07.200 --> 15:13.050
I'm going to press play and level up on a client, but I'm going to keep my eye on the client on the

15:13.050 --> 15:16.290
server's machine and see what it looks like here.

15:20.480 --> 15:21.500
Not too bad.

15:31.550 --> 15:33.380
Looks like it looks just fine.

15:33.380 --> 15:35.030
So this is going to work.

15:35.700 --> 15:39.990
Let's try this in a play as client situation.

15:40.870 --> 15:42.640
I'm just going to full screen it here.

15:47.760 --> 15:48.900
Looks fine.

15:48.900 --> 15:54.090
And let's take a look at one client from another client's perspective as they level up.

16:00.680 --> 16:02.090
And it looks great.

16:04.610 --> 16:09.140
Okay, I'm going to set it back to play as listen server set the number of players to one and we're

16:09.140 --> 16:14.660
now playing a Niagara particle system or spawning one when we level up.

16:14.660 --> 16:19.220
So we're one step closer to having a nice effect.

16:20.080 --> 16:22.660
I think it looks really, really good.

16:23.260 --> 16:28.180
Now, as we level up, I notice that my system was turning with my character.

16:28.180 --> 16:35.230
So if I level up and then I run around, notice that that particle system is kind of rotating along

16:35.230 --> 16:36.030
with me.

16:36.040 --> 16:39.760
So that's something that you may be okay with.

16:39.790 --> 16:42.070
It may be something you're not okay with.

16:42.070 --> 16:43.180
Let's see if I can.

16:43.810 --> 16:44.500
Turn.

16:44.500 --> 16:44.920
Yeah.

16:44.920 --> 16:47.410
So actually, I'm kind of okay with that.

16:47.680 --> 16:51.490
I think I'm actually like it, so I'm just going to leave it as is.

16:51.520 --> 16:52.180
Awesome.

16:52.180 --> 16:53.800
So excellent job.

16:53.800 --> 16:59.200
We'll continue making leveling up feel more epic in the next video.

17:00.470 --> 17:01.490
I'll see you soon.
