WEBVTT

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

00:08.070 --> 00:14.970
So we have click to run and auto running and that's all implemented nicely and we're ready to move on.

00:14.970 --> 00:19.390
But before we do, I'd like to clean up the player controller just a little bit.

00:19.410 --> 00:22.810
There are a couple of things that we could make a little bit better.

00:22.830 --> 00:30.150
For one, we're getting the hit results under the cursor twice every frame when we're holding down the

00:30.150 --> 00:31.380
left mouse button.

00:31.470 --> 00:38.160
So we can see that if we go to ability input tag held, we see that we're getting the hit result here,

00:38.160 --> 00:43.400
but we're already getting that hit result in cursor trace all the way up here.

00:43.410 --> 00:46.050
So we already have that value.

00:46.080 --> 00:51.540
We can just store that every frame if we're going to be using it, every frame, and then other functions

00:51.540 --> 00:53.280
that need it can access it.

00:53.280 --> 00:55.200
And this can be used even later on.

00:55.200 --> 01:01.380
If we want to do something like show a decal at the cursor, hit location or something like that.

01:01.380 --> 01:05.010
So I'd like to make a cursor hit member variable.

01:05.010 --> 01:11.950
So instead of making a local variable here in cursor trace, I'm going to take this F hit result Ctrl

01:11.950 --> 01:19.870
X to cut it and go into the player controller header file and just under cursor trace and these I enemy

01:19.870 --> 01:27.520
interfaces, I'm going to have an F hit result cursor hit right here and that way we're just filling

01:27.520 --> 01:31.570
in our member variable and get hit result under cursor.

01:31.690 --> 01:37.810
And if we search for get hit results under cursor we'll find where we're using it here and ability input

01:37.840 --> 01:38.770
tag held.

01:38.800 --> 01:41.320
We don't need to get it again.

01:41.320 --> 01:46.300
We just need to access the impact point from the one we already have.

01:46.330 --> 01:52.240
So rather than creating a new hit result here, let's get our cursor hit and we can check to see if

01:52.240 --> 01:59.770
it has a blocking hit so we can say cursor hit, dot blocking hit and then we can get our impact point

01:59.770 --> 02:04.510
from cursor hit here so we don't have to go and do another trace.

02:04.510 --> 02:08.620
That work has already been done, so that's a nice optimization.

02:08.620 --> 02:14.230
And the rest of the stuff I'd like to do in player controller is just kind of clean it up and make sure

02:14.230 --> 02:16.840
that it looks concise and nice.

02:17.080 --> 02:22.360
So I'm going to scroll down and if I see anything that I think can be cleaned up, I'm going to clean

02:22.360 --> 02:22.480
it.

02:22.480 --> 02:24.040
Now, here's something.

02:24.040 --> 02:31.150
The cursor trace function itself has a lot of code here that really could be condensed down.

02:31.150 --> 02:36.540
Now, we made these comments for educational purposes, right?

02:36.550 --> 02:41.890
We wanted to make sure we understand that we've covered all of the scenarios that can happen when we're

02:41.890 --> 02:42.730
highlighting.

02:42.730 --> 02:44.980
I don't think we need that comment anymore.

02:44.980 --> 02:52.480
And I also think that all of these cases with these empty comments are unnecessary.

02:52.480 --> 02:55.240
This can actually be condensed down quite a bit.

02:55.240 --> 02:57.310
So I'm going to go ahead and remove it.

02:57.340 --> 02:57.730
Now.

02:57.730 --> 03:01.000
How can we write this in the most concise way possible?

03:01.360 --> 03:08.350
Well, really, we just care if this actor and last actor are not the same right?

03:08.350 --> 03:11.110
If we say if last actor.

03:11.110 --> 03:13.270
We'll check last actor first.

03:13.270 --> 03:19.120
Because if last actor is not equal to this actor, they're different.

03:19.150 --> 03:20.860
Well, then we should do something.

03:20.860 --> 03:26.350
If these pointers are valid, we can say if last actor.

03:26.380 --> 03:34.030
Well, we know that last actor is not this actor and last actor is valid, which means we should unhighlight

03:34.030 --> 03:39.850
it because this actor, whether it's null or not, is not last actor.

03:39.850 --> 03:48.040
So if last actor is a valid pointer, we can take last actor and call Unhighlight actor on it.

03:48.460 --> 03:54.520
Now we also want to check if this actor so if this actor is valid and we know it's not equal to last

03:54.520 --> 03:59.710
actor, then we should highlight it so we can say this actor highlight actor.

03:59.710 --> 04:05.110
So we've now just condensed a lot of code into a really small area.

04:05.110 --> 04:11.770
And yes, I have my if statement all come packed onto a single line, but it only needs to do one thing.

04:11.770 --> 04:14.920
So I think that's fine and it looks a lot cleaner.

04:14.920 --> 04:17.320
So cursor trace is looking a lot better.

04:17.320 --> 04:23.380
And we'll just do a quick test before we end the video to make sure it's still working correctly and

04:23.380 --> 04:28.750
in our ability input tag functions, we can actually do the same thing with these.

04:28.780 --> 04:35.560
If statements that do a single thing, a single line, we can condense these onto a single line and

04:35.560 --> 04:36.970
take up less space.

04:36.970 --> 04:40.090
And I think that that will make them a little bit cleaner.

04:40.090 --> 04:44.620
So that's just a kind of a personal style preference.

04:44.650 --> 04:50.020
The Unreal Engine coding Standards document actually discourages doing this.

04:50.020 --> 04:56.410
It says you should always have a body with curly braces, but there are a number of standards in there

04:56.410 --> 05:02.620
that are treated more like guidelines by many developers, and this is one of them.

05:02.620 --> 05:06.430
I kind of like compact if statements when I only have a single.

05:06.460 --> 05:08.590
Line and I don't plan on adding more.

05:09.220 --> 05:16.030
So I'll go ahead and come down to ability input tag held and compact these single line if statements

05:16.030 --> 05:17.080
here as well.

05:18.790 --> 05:21.220
So doing it there, doing it here.

05:22.090 --> 05:23.620
And that's looking good.

05:23.800 --> 05:27.640
And we can even do that here with this if check.

05:27.670 --> 05:29.950
It's just a quick blocking hit check.

05:30.280 --> 05:31.720
So that looks good.

05:31.720 --> 05:37.480
And we'll get rid of some empty space in between there and just doing a quick scan.

05:37.510 --> 05:38.890
Everything else looks good.

05:38.890 --> 05:40.950
The move function could be made const.

05:40.960 --> 05:42.700
I'm not too worried about that.

05:42.740 --> 05:49.180
Writer tells you every single instance of when anything could be const and to be technically const correct

05:49.180 --> 05:51.460
you would follow its advice every time.

05:51.490 --> 05:57.970
I'll go ahead and remove a space from there in the constructor and I think our player controller is

05:57.970 --> 06:03.790
looking a lot cleaner, a lot smaller, less lines of code to do the same thing, which is always good.

06:03.880 --> 06:10.720
And before we do a quick test, I'd like to just remove any debug drawing that we're doing as we're

06:10.720 --> 06:12.310
done drawing debug shapes.

06:12.310 --> 06:14.770
So I'm going to remove draw debug sphere.

06:15.190 --> 06:22.010
I'm going to quickly add const to this controlled pawn local variable and I see that I'm not drawing

06:22.010 --> 06:24.290
anything else so this looks good.

06:24.290 --> 06:27.170
Let's go ahead and give this a quick test before we move on.

06:28.270 --> 06:28.720
Okay.

06:28.720 --> 06:29.950
So we'll quickly test.

06:29.950 --> 06:31.810
I'll test in multiplayer.

06:31.960 --> 06:37.000
Let's click play and I'm going to click and hold.

06:38.160 --> 06:39.030
Running works.

06:39.030 --> 06:40.740
I'm going to click and release.

06:41.940 --> 06:43.800
Auto running works as well.

06:43.800 --> 06:47.030
If I click on the pillar, we'll go around the pillar.

06:47.040 --> 06:52.280
If we click in the base of the pillar, we'll move to a location and stop.

06:52.290 --> 06:56.220
And if we highlight an enemy, it works.

06:56.340 --> 07:03.690
And we can also try duplicating an enemy, having two next to each other and we can try highlighting.

07:05.320 --> 07:09.400
One and then directly onto another that looks like it works.

07:09.400 --> 07:11.230
And we can try.

07:11.270 --> 07:13.660
Behavior on the server.

07:14.780 --> 07:16.020
And it's working.

07:16.040 --> 07:17.750
Everything works as expected.

07:18.760 --> 07:24.820
Now, one thing actually that doesn't behave as expected is that our clients don't get those messages

07:24.820 --> 07:27.650
popped up like our server does.

07:27.670 --> 07:33.100
So let's just really quickly figure out why and fix that.

07:33.100 --> 07:38.100
And that's going to have to do with our ability system component.

07:38.110 --> 07:43.720
If we go to our ability system component header file, we'll see that we have this effect applied.

07:43.720 --> 07:45.130
When is that called?

07:45.280 --> 07:52.930
Well, we have our ability actor info set, which is where we bind this callback to on gameplay effect

07:52.930 --> 07:54.790
delegate to self.

07:54.790 --> 08:01.120
And if we go to declaration or usages for this, we see that the comment and ability system component

08:01.660 --> 08:03.730
says called on server.

08:03.730 --> 08:06.670
Whenever a gameplay effect is applied to self.

08:06.700 --> 08:12.670
That's why we only get this callback fired off on the server and not on clients.

08:12.670 --> 08:16.440
So how do we make sure that it fires off on clients as well?

08:16.450 --> 08:19.430
Well, it turns out that's actually pretty easy.

08:19.520 --> 08:28.580
You see, if we take this effect applied callback and make it an RPC, specifically a client RPC, then

08:28.580 --> 08:35.100
it'll be called on the server, but it'll also be executed on the owning client.

08:35.120 --> 08:40.880
So client Rpcs are designed to be called on the server and executed on the client.

08:40.910 --> 08:47.660
Now, if it's being called for the server owned ability system component, the hosting player, then

08:47.660 --> 08:54.050
the client RPC will just be called on the server and it won't be replicated down to the owning client

08:54.050 --> 08:56.300
as the owning client is on the server.

08:56.300 --> 08:56.840
Right.

08:57.110 --> 09:03.800
So what we're going to do is we're going to go to our ability system component and we're going to take

09:03.800 --> 09:07.280
this effect applied and make this an RPC.

09:07.430 --> 09:11.780
We do that by giving it a new function and saying client here.

09:11.780 --> 09:15.750
So it's now a client RPC and we're going to make it reliable.

09:15.770 --> 09:22.940
Reliable means it's guaranteed to reach the client even in the case of packet loss, it'll be sent until

09:22.940 --> 09:26.420
it receives confirmation that it has been received.

09:26.450 --> 09:34.970
Now, typical convention is to prefix a client RPC with client in the name, and if we make this an

09:34.970 --> 09:43.400
RPC, then our implementation here in the CPP file has to have underscore implementation in the name.

09:43.400 --> 09:48.950
So it's now going to be called client effect applied underscore implementation.

09:49.250 --> 09:55.790
And this function client effect applied is now what we're going to bind to this delegate, not just

09:55.790 --> 09:58.430
effect applied but client effect applied.

09:58.430 --> 10:00.410
So now this is a client RPC.

10:00.620 --> 10:06.980
And once this delegate is broadcast on the server, it'll be called in the server and executed on the

10:06.980 --> 10:07.670
client.

10:07.670 --> 10:12.770
So this takes care of both server and client behavior for those messages.

10:12.770 --> 10:19.760
And that's how we're getting the messages, is we're broadcasting the asset tags for any applied effect

10:19.760 --> 10:23.500
and our widget controller receives them and handles it from there.

10:23.510 --> 10:31.640
So let's just quickly test this out and make sure we're now getting those messages on the HUD on clients.

10:32.900 --> 10:35.510
Okay, so we have our number of players.

10:35.510 --> 10:37.220
Let's set it to three.

10:37.370 --> 10:39.590
I'd like to test this out with three players.

10:39.590 --> 10:41.630
So we have two clients and a server.

10:41.720 --> 10:45.890
I'm going to take this first client and pick up something.

10:45.890 --> 10:47.240
And there's the message.

10:47.240 --> 10:49.430
Looking good, Looking good.

10:49.700 --> 10:51.860
I'm going to try it on this other client.

10:51.890 --> 10:54.560
Also looking good and we'll try it on the server.

10:54.860 --> 10:56.960
Also looking good.

10:57.350 --> 10:58.400
Perfect.

10:58.640 --> 11:00.730
I'll go ahead and set that back to one player.

11:00.740 --> 11:05.360
Actually, let's test two players on a dedicated server.

11:05.360 --> 11:07.220
That's this player's client.

11:07.250 --> 11:09.050
Let's give that a try.

11:11.080 --> 11:13.870
And that works for both clients.

11:13.900 --> 11:14.830
Perfect.

11:15.010 --> 11:19.180
I'll set this back to listen server and we'll keep it at one for now.

11:19.390 --> 11:24.540
I'm going to save all close out and we've done some good refactoring.

11:24.550 --> 11:27.070
Things are working and it's time to move on.

11:27.100 --> 11:28.120
Excellent job.

11:28.150 --> 11:29.650
See you in the next video.
