WEBVTT

00:06.960 --> 00:07.740
Welcome.

00:07.740 --> 00:13.380
In this video, we're going to add a player level to our player state class, and then we'll create

00:13.380 --> 00:17.580
a combat interface and implement that in our project.

00:17.820 --> 00:26.160
So first, let's go to our public folder into player and open up Aura Player State.

00:26.250 --> 00:31.710
And in Aura Player State, we can have a variable for the level.

00:31.710 --> 00:33.960
And I'd like this to be a private variable.

00:33.960 --> 00:39.060
This will be private here in the player state and it's going to be an int 32.

00:39.060 --> 00:46.710
So level is just going to be an integer and it'll have a default value of one and I'm going to give

00:46.710 --> 00:54.210
it a new property with visible anywhere just in case we want to see it in our blueprint Now level is

00:54.210 --> 00:55.860
going to be replicated.

00:55.860 --> 01:03.720
I'd like it to have its own rep notify as well, so that later on when we're going to be showing this

01:03.750 --> 01:08.680
in the HUD, we're going to want to make a broadcast whenever this replicates.

01:09.140 --> 01:15.020
Now to replicate anything, we need to override git lifetime replicated props, don't we?

01:15.020 --> 01:18.140
So we're going to do that here in the public section.

01:18.140 --> 01:22.130
We're going to say Virtualvoid git lifetime replicated props.

01:22.130 --> 01:30.410
We'll go ahead and create the definition for it and allow the super call and then we can add a rep notify

01:30.440 --> 01:33.770
right here in the private section for level.

01:33.770 --> 01:42.110
So this will be void on rep underscore level and we're going to have an INT 32 as the input called old

01:42.110 --> 01:42.800
level.

01:42.800 --> 01:48.800
That way we can have access to that old level and this gets a new function property.

01:48.830 --> 01:51.200
Otherwise it can't be a rep notify.

01:51.380 --> 02:00.230
And so now we can mark level as replicated and we're going to use replicated using equals on rep level.

02:02.450 --> 02:03.260
Okay.

02:03.260 --> 02:09.270
So we can generate the definition for on rep level and we're going to use that soon enough.

02:09.270 --> 02:16.320
But for now let's just mark it as replicated here and get lifetime replicated props.

02:16.470 --> 02:19.710
Now for this we're just going to use do rep lifetime.

02:19.710 --> 02:27.060
This is the most basic macro for marking something as replicated and writer is going to tell us that

02:27.060 --> 02:27.580
we need.

02:27.600 --> 02:34.320
Net slash unreal network H so I'm going to hit Alt enter to go ahead and include that header file.

02:34.320 --> 02:36.210
And now this is defined.

02:36.360 --> 02:44.850
So we need to use our class name or a player state followed by level the name of the replicated variable.

02:44.850 --> 02:50.040
And now with this level is a replicated variable and we're good.

02:50.040 --> 02:53.820
So the player state is where our level will reside.

02:53.820 --> 02:58.140
But I'd like that to be the case only for the player controlled character.

02:58.140 --> 03:03.750
For enemy characters, their level should not reside on a player state because they're not using or

03:03.750 --> 03:06.540
a player state for enemy characters.

03:06.540 --> 03:12.540
I'd like the level to be on the enemy character itself, on Ora Enemy.

03:12.570 --> 03:20.190
So for that case, let's go back to the character folder and open ora enemy and we'll give Ora Enemy

03:20.220 --> 03:25.140
a private section with its own level variable.

03:25.140 --> 03:33.480
So this will be an int 32, we'll call it level, we'll set it to a default value of one and we'll give

03:33.480 --> 03:34.320
it a new property.

03:34.320 --> 03:45.750
And for this I'd like it to be edit anywhere blueprint read only and I'll give it a category of character

03:45.750 --> 03:47.880
class defaults.

03:47.970 --> 03:52.890
Now the reason I'm not going to make this replicated for the enemy is because we're only going to be

03:52.890 --> 03:57.690
concerned with checking the level on the server for AI controlled enemies.

03:57.690 --> 04:04.200
And that's because important things that will require that level in calculations will only be done on

04:04.200 --> 04:05.010
the server.

04:05.160 --> 04:08.400
So that's all we need to do for the enemies level.

04:08.760 --> 04:12.640
Now for the interface we were talking about earlier.

04:12.660 --> 04:20.820
Ora enemy has a level variable and or a player state has a level variable, and I'd like to create an

04:20.820 --> 04:26.940
interface that can retrieve the level and we can implement that on our character class.

04:26.940 --> 04:31.920
And then any character can call that function to retrieve the level.

04:31.920 --> 04:36.960
And it's up to the individual character to determine how to get that, whether we get it from the player

04:36.960 --> 04:42.300
state or just return that value from the character itself in the case of the enemy.

04:42.300 --> 04:50.220
So we're going to go ahead and launch the editor And of course, Blueprint Read only should not be on

04:50.220 --> 04:52.290
private members, right?

04:52.380 --> 04:55.650
Of course, that's something that is going to pop up.

04:55.650 --> 05:01.200
So rather than trying to get around that, I'm going to move it actually up to the protected section.

05:01.200 --> 05:03.360
I think that's totally fine.

05:04.410 --> 05:07.710
So level is now protected instead of private.

05:07.740 --> 05:09.960
Let's go ahead and launch the editor.

05:11.490 --> 05:13.920
Okay, so what we need is an interface.

05:13.920 --> 05:20.730
So I'm going to go into our C plus plus classes ora public, and we have an interaction folder for our

05:20.730 --> 05:22.050
enemy interface.

05:22.050 --> 05:27.870
We're now going to have a combat interface that will be shared between both enemies and the player controlled

05:27.870 --> 05:28.710
character.

05:28.710 --> 05:33.780
Enemy interface is unique to enemies only, so this one will be shared.

05:33.780 --> 05:40.770
We're going to have this class in the same folder interaction and it will be an unreal interface.

05:40.770 --> 05:46.530
Let's click next, and here in interaction we'll create our combat interface.

05:49.170 --> 05:55.790
So we'll go ahead and close the editor and let writer populate our folders with our new interface.

05:55.800 --> 05:57.990
And we should see it here in interaction.

05:57.990 --> 06:00.090
Here it is combat interface.

06:00.270 --> 06:07.230
And I just want to implement one function here in combat interface right here in the public section.

06:07.230 --> 06:13.230
So it's going to be virtual and it's going to return an INT 32 and we're going to call this get level.

06:13.710 --> 06:18.000
I don't want it to be required that we implement this.

06:18.000 --> 06:22.650
If we don't implement it, I want to simply return zero.

06:22.740 --> 06:24.900
So I'm going to generate a definition.

06:24.900 --> 06:31.860
This will be a default definition that returns zero here and then we can implement this in, say, the

06:31.860 --> 06:35.580
base character class who doesn't need to implement it.

06:35.580 --> 06:41.850
But because the base character class has combat interface, then we don't have to implement it individually

06:41.850 --> 06:45.120
in each subclass of the base character.

06:45.120 --> 06:52.810
So let's go to Aura character base in the character folder and let's implement this interface.

06:52.810 --> 06:58.840
So not only I ability system interface, we're also going to inherit from i combat interface.

07:00.200 --> 07:04.370
And writer should give me the opportunity to include the header file.

07:04.370 --> 07:06.120
And there we go.

07:06.140 --> 07:12.830
So now our base character class or a character base is also a combat interface.

07:12.830 --> 07:19.160
And then we can implement get level in both aura character and aura enemy.

07:19.430 --> 07:23.540
We'll first do it in Aura Enemy, and this is going to be public.

07:23.540 --> 07:32.930
And right here I'm going to make a multi-line comment that says combat interface and beneath it.

07:34.000 --> 07:43.030
We'll close it out with end combat interface and we'll implement that function virtual int 32, get

07:43.030 --> 07:45.490
level override.

07:46.270 --> 07:51.160
And for the enemy, we're simply going to return the level variable.

07:51.160 --> 07:56.260
So let's go ahead and generate this definition and return level.

07:56.260 --> 07:57.850
We don't need to call super.

07:57.880 --> 08:01.240
We're going to return the level variable.

08:01.510 --> 08:05.320
And for a character it's going to be different, isn't it?

08:05.320 --> 08:08.020
Because our level will be on the player state.

08:08.020 --> 08:13.210
So let's go to a character and we'll override that function here.

08:13.210 --> 08:14.680
It's in the public section.

08:14.680 --> 08:20.710
So we're going to have a multi-line comment that says combat interface.

08:22.680 --> 08:29.490
And we'll have another multi-line comment beneath it that says end combat interface and we'll override

08:29.490 --> 08:34.410
the function virtual int 32, get level override.

08:34.950 --> 08:41.070
Let's go ahead and generate a function definition and this one will return something else, won't it?

08:41.100 --> 08:43.650
We have to get our player state.

08:43.680 --> 08:49.260
We're doing that right here in init ability actor info so we can copy that line right here.

08:49.740 --> 08:52.140
We can simply copy that.

08:52.260 --> 08:59.530
We can even do the check for a player state here and we can simply get the level from a player state.

08:59.550 --> 09:07.200
Now an aura player, state level is private, so we should make a public getter to retrieve that level

09:07.200 --> 09:07.770
variable.

09:07.770 --> 09:08.840
So right here, we'll do it.

09:08.850 --> 09:14.340
We're going to say int 32, not 43, but 32 get level.

09:15.660 --> 09:19.320
It'll be const and it'll return level.

09:20.140 --> 09:23.860
Now, in this case, we're hiding a function.

09:23.980 --> 09:28.360
There's a function called get level on the actor class.

09:28.360 --> 09:32.140
Now, that tells me it's going to be a problem for all the other classes.

09:32.140 --> 09:39.520
So for that reason, I'd like to change the function name to get player level on all fronts.

09:39.520 --> 09:41.700
So I'm going to change it here.

09:41.710 --> 09:44.470
I'm going to change it in the interface itself.

09:44.500 --> 09:46.600
Let's go to Combat Interface.

09:46.600 --> 09:52.270
Let's just go ahead and change this to get player level and that means I need to change it here in Combat

09:52.270 --> 09:53.470
Interface TCP.

09:53.950 --> 09:59.050
We also have to change it in Ora enemy dot H and CPP.

09:59.050 --> 10:01.990
So let's change it to get player level there.

10:02.020 --> 10:07.600
CPP will change it to get player level there and an Ora character will change it to get player level

10:07.600 --> 10:11.890
here and get player level here and we can call that getter.

10:11.890 --> 10:16.600
And before we do, let's just go back to Ora Player State for a second.

10:16.690 --> 10:21.380
And I was going to say that this is a nice simple little function.

10:21.380 --> 10:23.270
We can mark it with force inline.

10:23.270 --> 10:29.270
Now you'll notice that I'm not using force inline very much in this course, and I've used it quite

10:29.270 --> 10:31.780
a bit in other courses with getters.

10:31.790 --> 10:39.560
This is one of those micro-optimizations that you tend to kind of see overused a lot and it doesn't

10:39.560 --> 10:42.320
make a huge difference at runtime.

10:42.320 --> 10:44.600
It is a small optimization.

10:44.600 --> 10:52.610
It basically means that whenever we call get player level, the preprocessor is going to replace that

10:52.610 --> 10:58.850
function call when preprocessing before the compilation step with the function body, in this case the

10:58.850 --> 11:00.830
level variable itself.

11:00.830 --> 11:05.930
So ultimately the compiler has the say over whether it ends up doing that or not.

11:05.960 --> 11:12.170
For small things like this, it's usually okay, you're not really going to cause any harm by overusing

11:12.170 --> 11:15.320
it, but that's why I don't use it very much.

11:15.320 --> 11:17.210
I'm going to go ahead and use it here though.

11:17.210 --> 11:23.030
And since we have a getter, we can go back to Ora character and we can get that level.

11:23.030 --> 11:33.680
So we can return with lowercase, of course, return or a player state get player level like so.

11:33.680 --> 11:36.530
And this could be a const local variable here.

11:37.310 --> 11:43.280
So now ora character implements get player level or an enemy implements get player level.

11:43.280 --> 11:44.810
It just returns level.

11:44.840 --> 11:48.800
This could really be on one line know as a matter of style.

11:48.800 --> 11:52.250
You could change it if you wanted all in one line like that.

11:52.250 --> 12:00.320
But now that our character and enemy can have get player level called and in the case of the enemy,

12:00.320 --> 12:03.680
they'll return the level variable that's on the enemy class.

12:03.680 --> 12:09.560
In the case of Ora character, it'll return the player level that's on the player state class.

12:09.560 --> 12:11.000
That's all great.

12:11.030 --> 12:18.590
Now we have an interface we can use to easily get the player level if we want to.

12:18.590 --> 12:24.950
In a custom calculation class and the custom calculation class is what we will make next.

12:24.950 --> 12:29.030
So let's go ahead and make sure our code compiles here.

12:29.930 --> 12:34.580
And suddenly my player controller doesn't like to object.

12:34.580 --> 12:37.900
Pointer being used for last actor in this actor.

12:37.910 --> 12:45.140
It was legal before, but now it's telling me to stop using object pointer for the enemy interface.

12:45.410 --> 12:50.780
So that means we're going to need to use raw pointers for the enemy interface.

12:50.780 --> 12:55.310
We'll go ahead and leave that as a raw pointer.

12:55.310 --> 12:58.340
Instead, let's go ahead and compile again.

12:59.740 --> 13:00.850
And there we go.

13:00.850 --> 13:02.950
We have a successful compile.

13:02.980 --> 13:03.880
Great.

13:04.240 --> 13:05.350
So great job.

13:05.350 --> 13:07.510
And I'll see you in the next video.
