WEBVTT

00:07.390 --> 00:08.720
Welcome back.

00:08.740 --> 00:13.850
So we're setting up our ability system components and we've set our replication mode.

00:13.870 --> 00:20.110
Now, something should still be bothering you at this point, and that is that our Aura character base

00:20.110 --> 00:25.930
class has an ability system component pointer and an attribute set pointer.

00:25.930 --> 00:34.240
And it's only on Aura Enemy that those pointers have been set with valid values for Aura character.

00:34.330 --> 00:41.620
Those pointers are uninitialized because we constructed the ability system component and attribute set

00:41.620 --> 00:46.210
on the player state instead for our player controlled character.

00:46.240 --> 00:51.550
These pointers have valid values for the player state, but not for the character.

00:52.090 --> 00:54.880
So I want that to keep bothering you.

00:54.910 --> 01:00.100
Keep that in the back of your mind, because it's something we do want to fix.

01:00.220 --> 01:07.210
Now, another thing we have to do is make sure that the ability system component itself knows who its

01:07.210 --> 01:08.650
owner is.

01:08.680 --> 01:15.070
Now, that could mean something different for our enemy versus our player controlled character, right?

01:15.070 --> 01:21.330
Because for our enemy, the owner of the ability system component is clearly this enemy class.

01:21.340 --> 01:25.660
But for the character, that's not necessarily the case, is it?

01:25.660 --> 01:32.020
Because the player state is who actually constructs the ability system component?

01:32.380 --> 01:35.590
So how do we decide who's the owner of it?

01:35.620 --> 01:37.300
Let's talk about that.

01:37.330 --> 01:43.510
Now the Ability system component has this concept of ability actor info.

01:43.540 --> 01:51.910
That way, the ability system component can always know the actor info such as who owns this ability

01:52.010 --> 01:53.360
system component.

01:53.450 --> 02:01.160
But the ability system component also understands the concept that it might be owned by some actor,

02:01.160 --> 02:07.430
by some pawn, or it could be owned by another type of entity such as a player state.

02:07.520 --> 02:16.370
So for that reason, the ability system component has two variables an owner actor and an avatar actor.

02:16.730 --> 02:22.570
You see, the owner actor is whatever class actually owns the ability system component.

02:22.580 --> 02:30.890
But the Avatar actor is the representation in the world associated with this ability system component.

02:31.130 --> 02:39.440
Now for our enemy character, these two are the same because our enemy character class is the class

02:39.440 --> 02:42.500
that constructs our ability system component.

02:42.500 --> 02:49.330
So the owner actor is the enemy character, and the avatar actor is also the enemy character.

02:49.340 --> 02:51.290
That's what we see in the world.

02:51.290 --> 02:53.240
That's the visual representation one.

02:53.270 --> 03:00.020
Now for the player controlled character, this is a little different because our ability system component

03:00.020 --> 03:06.110
is constructed by the player state, and that's the class we would like to think of as the owner for

03:06.110 --> 03:07.960
the ability system component.

03:07.970 --> 03:15.200
So the owner actor in this case should be the player state and the avatar actor, that actor that we

03:15.200 --> 03:18.890
actually see in the world that should be the character.

03:19.040 --> 03:26.300
So in this case, the owner, actor and Avatar actor are two different actors and the ability system

03:26.300 --> 03:29.690
component distinguishes between those two.

03:29.720 --> 03:38.090
So it's important to understand that the owner, actor and avatar actor may or may not be the same actor

03:38.390 --> 03:41.510
in our project For the Enemy, they are the same.

03:41.510 --> 03:45.080
And for the player controlled character, they are different.

03:45.110 --> 03:48.350
Now we are the ones who decide these things.

03:48.350 --> 03:53.680
We call the function to set the owner and avatar actors.

03:53.680 --> 03:59.800
It's a function on the ability system component called init ability actor info.

04:00.010 --> 04:06.250
So we need to initialize the ability system component with these actors ourselves.

04:06.280 --> 04:09.970
Now where and when do we call this function?

04:10.210 --> 04:13.390
Well, that's something that we have to give some thought to.

04:13.420 --> 04:15.580
You see, it depends.

04:16.020 --> 04:21.880
Now here are some rules of thumb and good places to do so in a multiplayer game, the first thing we

04:21.880 --> 04:28.660
need to know is that calling init ability actor info must be done after possession.

04:28.660 --> 04:33.270
In other words, the controller has to have been set for the pawn.

04:33.280 --> 04:38.190
So it's important that we do this after the controller has been set for the pawn.

04:38.200 --> 04:39.640
So when is that?

04:39.670 --> 04:47.440
Well, for a player controlled character in which the ability system component lives on the pawn itself,

04:47.440 --> 04:54.980
this would be if perhaps we had constructed the ability system component on a character instead of the

04:54.980 --> 04:56.960
player state, which we're not doing.

04:56.960 --> 05:04.790
But if we did a good place to call init ability actor info would be in the possessed by function on

05:04.790 --> 05:05.720
the pawn.

05:05.930 --> 05:13.250
This ensures that the ability system component is initialized with the avatar actor and owner actor

05:13.250 --> 05:18.740
values on the server, but this function only applies on the server.

05:18.770 --> 05:19.720
On the client.

05:19.730 --> 05:21.580
We have to use a different function.

05:21.590 --> 05:24.980
There's a function called acknowledge possession for that.

05:24.980 --> 05:28.880
And in this function we know that possession has occurred.

05:28.880 --> 05:32.060
Our pawn does have a valid controller.

05:32.060 --> 05:39.080
So in this case, if we were to put our ability system component on the pawn or in our case the character

05:39.080 --> 05:47.000
class itself, these two functions are where we would call init ability actor info in order to initialize

05:47.000 --> 05:50.390
the ability system so it knows who its owners are.

05:50.420 --> 05:51.140
Both.

05:51.270 --> 05:52.980
The owner and the avatar.

05:52.980 --> 05:55.350
And in this case, they would both be the same.

05:55.350 --> 05:57.930
They would be the pawn itself.

05:58.050 --> 06:04.020
Now, for player controlled characters in which the ability system component lives on the player state,

06:04.020 --> 06:11.130
which is our case for Aura character, then we're going to call init ability actor info for the server

06:11.160 --> 06:12.450
on possessed by.

06:12.480 --> 06:19.980
But for the client we're not going to use acknowledge possession we're going to use on rep player state.

06:20.010 --> 06:20.610
Why?

06:20.640 --> 06:25.440
Because our AC our ability system component lives on the player state.

06:25.440 --> 06:31.950
So not only do we need to make sure that our controller has been set, but we also need to make sure

06:31.950 --> 06:36.720
that our player state is valid at this point in time as well.

06:36.720 --> 06:39.450
Now on Rep, Player State is safe.

06:39.450 --> 06:43.650
Both of those things will have been done by that point in time.

06:43.650 --> 06:46.440
We'll have a valid controller and a valid player.

06:46.440 --> 06:51.030
State Now on rep Player state is something called a rep.

06:51.030 --> 06:58.280
Notify the rep notifies are functions that are called as a result of something being replicated.

06:58.280 --> 07:04.730
In this case, the player state will have been set on the server and the player state is a replicated

07:04.730 --> 07:12.290
entity, which means that as soon as that player state has been set for our pawn, that will be replicated

07:12.290 --> 07:18.140
down, triggering this rep notify, which will be called in response to the replication happening.

07:18.140 --> 07:25.010
And at that point we know that our player state has been set on the server and down here on the client

07:25.040 --> 07:28.610
it's been replicated down and it's a valid pointer.

07:28.610 --> 07:36.140
So that is where we will initialize ability actor info for our ability system component.

07:36.260 --> 07:43.040
And in this case we'll be setting our owner actor to the player state and our avatar actor to the pawn

07:43.040 --> 07:45.770
itself in our case, or a character.

07:45.770 --> 07:49.910
So this is what we'll be doing for our player controlled character.

07:50.300 --> 07:56.050
Now for the AI controlled characters, it's a bit more simple for our AI controlled characters.

07:56.050 --> 07:59.830
We'll have our ability system component on the pawn itself.

07:59.830 --> 08:01.360
That's our aura enemy.

08:01.360 --> 08:09.010
And because of that we really only need to call init ability actor info and begin play.

08:09.010 --> 08:16.840
We know that our AI controlled character is going to have a valid ability system component and controller

08:16.840 --> 08:21.250
and we're just going to call init ability actor info and begin play.

08:21.250 --> 08:24.670
This will work just fine for our AI controlled character.

08:24.670 --> 08:26.350
So that's what we're going to do.

08:26.380 --> 08:32.020
So if you're a note taker, if you like taking notes, this would be one of those important things to

08:32.020 --> 08:38.350
write down so you can pause the video and write these things down because these are the functions that

08:38.350 --> 08:44.290
you want to know about when it comes to calling an IT ability actor info and initializing it.

08:44.290 --> 08:52.240
And now that we know what we're going to do to init ability actor info, it's time to actually do it

08:52.240 --> 08:53.590
in our project.

08:53.590 --> 08:56.710
And this is going to be your quest.

08:56.830 --> 09:03.700
I want you to initialize the actor info by calling init ability actor info and you're going to do this

09:03.700 --> 09:05.500
for the aura enemy class.

09:05.500 --> 09:06.790
That's going to be easy.

09:06.790 --> 09:08.860
You'll just do it and begin play right?

09:08.860 --> 09:11.680
But also handle this for Aura character.

09:11.680 --> 09:15.130
And remember, this one's a little bit more complicated.

09:15.130 --> 09:17.380
And also remember the ASC.

09:17.410 --> 09:22.210
The ability system component is on the player state, which means you're going to need to access the

09:22.210 --> 09:23.200
player state.

09:23.200 --> 09:29.800
And while you're at it, this is a great opportunity to set the Aura character's ability system component

09:29.800 --> 09:31.930
and attribute set pointers.

09:31.930 --> 09:35.320
Remember I told you that should be bothering you in the back of your mind.

09:35.350 --> 09:37.510
Those pointers are uninitialized.

09:37.510 --> 09:43.900
Well, as soon as we access the player state, we should then have access to the ability system component

09:43.900 --> 09:45.460
and attribute sets.

09:45.460 --> 09:51.550
The player state has getters for those and our Aura character will now have the ability to set those

09:51.550 --> 09:52.330
pointers.

09:52.330 --> 09:56.260
So pause the video and initialize your ability.

09:56.260 --> 09:58.420
Actor info now.

10:02.690 --> 10:04.610
Okay, so we're ready to init.

10:04.640 --> 10:06.170
Ability actor info.

10:06.170 --> 10:10.190
And I'd like to do the enemy first because that's the simplest case.

10:10.190 --> 10:13.370
We're going to do this in begin play now.

10:13.430 --> 10:18.830
Our enemy doesn't have begin play, which means we're going to need to override that here.

10:19.100 --> 10:23.740
And while I'm at it, I'd like to make this a little more organized.

10:23.750 --> 10:32.810
I'm going to put a comment up here above our interface functions because I know that this belongs to

10:33.260 --> 10:34.700
our enemy interface.

10:34.700 --> 10:38.090
So I'm going to say enemy interface right here.

10:38.090 --> 10:44.480
And I'm going to put a comment below these two that says End enemy interface.

10:44.480 --> 10:49.670
That way I know that these are from that interface and these are public.

10:49.700 --> 10:51.050
Begin play is protected.

10:51.050 --> 10:56.510
So we'll make a protected section and we'll override begin play down here.

10:56.510 --> 11:03.150
So we're going to say virtual void begin play override.

11:03.150 --> 11:11.670
Let's generate the definition, we'll get our super call and then we can init ability actor info here.

11:11.670 --> 11:21.180
So to do that we access our ability system component pointer and we call init ability actor info and

11:21.180 --> 11:29.010
we can see that the first input is the owner actor that will be this and the avatar actor will also

11:29.010 --> 11:30.420
be this.

11:30.690 --> 11:33.660
Now if you like, you can check the pointer first.

11:33.660 --> 11:39.030
You can even put an assert such as check ability system component.

11:39.030 --> 11:40.230
You can do that.

11:40.350 --> 11:43.860
But if I get a crash on this line, then I know why.

11:43.860 --> 11:49.950
It's because the ability system component pointer is null, but I don't expect it to be null because

11:49.950 --> 11:53.250
I'm initializing that in the constructor.

11:53.250 --> 11:55.440
So something is terribly wrong.

11:55.440 --> 12:01.440
If I crash accessing this pointer, I'm confident enough to use it without checking.

12:01.650 --> 12:02.250
Okay.

12:02.250 --> 12:04.860
So that takes care of the enemy.

12:04.890 --> 12:09.960
Now for the character, which is going to be a little more complicated, but not much.

12:09.990 --> 12:19.050
Let's find our Aura character class, the CPP version, and we're going to want to override a couple

12:19.050 --> 12:20.220
of functions.

12:20.220 --> 12:28.110
I'll just pull up my slide here again and remind myself that this is the case where concerned with where

12:28.110 --> 12:34.080
the ability system component lives on the player state, we're going to initialize ability actor info

12:34.080 --> 12:39.900
in possessed by for the server and on player state for the client.

12:39.900 --> 12:42.780
So we need to override those functions.

12:42.780 --> 12:51.390
So that means I'm going to hit alt O or control k o on Visual Studio to come into Aura character, and

12:51.390 --> 12:55.080
I'm going to override a couple of virtual functions.

12:55.080 --> 13:04.050
First, we need possessed by so virtual void possessed by and if I right click and go to declaration

13:04.050 --> 13:12.990
or usages, we'll see that this possessed by belongs to the a character class right here and if I go

13:12.990 --> 13:22.110
to character should search for possessed by I can see that it is in the public section.

13:22.200 --> 13:31.380
And by the way notice that we see this comment thing happening here for functions that belong to interfaces.

13:31.380 --> 13:37.020
We're actually seeing the comment for parent classes being referred to as interfaces.

13:37.050 --> 13:38.820
Now, we could do that too, if we want.

13:38.850 --> 13:44.670
In fact, if you want to copy the same sort of comment style, you can do that as well.

13:44.670 --> 13:45.630
It's up to you.

13:45.660 --> 13:49.140
We can say begin interface and end interface.

13:49.410 --> 13:52.680
So if you want to use that comment style, feel free.

13:52.800 --> 14:00.270
But I wanted to see that possessed by is a public function and we're also going to want to override

14:00.300 --> 14:09.980
virtual void on wrap player state and we can go ahead and generate the definitions for both of these

14:09.980 --> 14:11.090
functions.

14:11.730 --> 14:12.900
There they are.

14:13.140 --> 14:21.690
And if we hit shift shift that allows us to search, we can search for on rep player state and we see

14:21.690 --> 14:24.860
that that one belongs to the pawn class.

14:24.870 --> 14:27.660
Here it is on rep player state.

14:27.960 --> 14:33.570
And we see here in the pawn class that this function is also public.

14:33.990 --> 14:38.010
So we'll go ahead and override that one.

14:38.010 --> 14:45.780
Now that we have these two functions, we can do what we need to do, which is call init ability actor

14:45.780 --> 14:46.470
info.

14:46.470 --> 14:49.560
So we'll start with possessed by now.

14:49.560 --> 14:52.260
Remember this one's for the server, so I'm going to make a comment.

14:52.260 --> 15:03.810
So we remember init ability actor info for the server and remember we need to access the player state.

15:03.810 --> 15:12.640
So I need to call get player state and we have a template version of this so we can pass in a or a player

15:12.640 --> 15:17.620
state as the type and that will return the appropriate type.

15:17.650 --> 15:21.520
Now I'm going to make a local or a player state variable.

15:21.520 --> 15:27.580
I'm going to say A or a player state called or a player state.

15:28.690 --> 15:30.790
And I'm going to wrap this in an if statement.

15:30.790 --> 15:39.160
So if that way, if this is valid, which it should be at this point, in fact, it's kind of important.

15:39.160 --> 15:43.450
Let's go ahead and just use an assert instead.

15:43.450 --> 15:45.720
This should not be a null pointer.

15:45.730 --> 15:47.800
We should be pretty confident.

15:47.950 --> 15:56.650
So we'll say check or a player state and then we'll take or a player state and we're going to get the

15:56.650 --> 15:58.600
ability system component from this.

15:58.600 --> 16:02.170
We're going to call get ability system component.

16:02.170 --> 16:09.520
And from that we now have the ability system component we can call init ability actor info and we can

16:09.520 --> 16:13.000
pass in the owner, actor and the avatar actor.

16:13.180 --> 16:17.740
Now in this case, the owner actor is going to be the player state.

16:17.740 --> 16:24.610
So we're going to pass in or a player state for the owner actor and the Avatar actor will be the character

16:24.610 --> 16:26.890
itself that's going to be this.

16:26.980 --> 16:28.510
So that's the difference.

16:28.510 --> 16:33.700
When you have the ask or ability system component on the player state.

16:33.700 --> 16:40.750
But we have to set this here in possessed by because we need to be sure that we have a valid player

16:40.750 --> 16:48.100
controller set already and that our player state is valid and accessible and we can call this function

16:48.100 --> 16:48.370
here.

16:48.370 --> 16:49.720
So that takes care of this.

16:49.720 --> 16:57.790
But remember, we have the player state now that's a good opportunity to set the Aura character's ability

16:57.790 --> 16:59.200
system component pointer.

16:59.200 --> 17:06.280
So we're going to say ability system component equals and we'll take Aura player state and call get

17:06.310 --> 17:07.870
ability system component.

17:07.870 --> 17:11.260
We'll set that and we'll set our attribute set as well.

17:11.260 --> 17:12.880
We'll say attribute set.

17:14.600 --> 17:16.490
Equals or a player state.

17:16.520 --> 17:17.930
Get attribute set.

17:17.930 --> 17:22.100
And now we're starting to see the benefit of having those getter functions.

17:22.400 --> 17:29.750
Okay, so these pointers are set here on the server and we've initialized ability actor info here on

17:29.750 --> 17:30.230
the server.

17:30.230 --> 17:33.620
We're going to want to initialize it for the client as well.

17:33.620 --> 17:40.070
That's why we're doing it in on Rep Player State, which means we're going to do the very same thing

17:40.070 --> 17:40.760
we did here.

17:40.760 --> 17:48.290
We're going to get the player state, check it and call init ability actor info and set these to pointers.

17:48.290 --> 17:53.600
We're going to do the same thing now rather than just repeating myself.

17:53.690 --> 17:57.080
You may have heard of the dry principal dry.

17:57.110 --> 17:58.580
Don't repeat yourself.

17:58.850 --> 18:06.050
Rather than copying several lines of code and pasting them, I would like to instead create a function

18:06.050 --> 18:08.960
that I can reuse in both of these.

18:08.960 --> 18:18.690
So let's go ahead and go to Ora character here and make a private function that we can just call twice.

18:18.690 --> 18:24.900
So I'm going to say void and I'll just call this init ability actor info.

18:26.430 --> 18:28.290
That's really all it's doing.

18:28.290 --> 18:33.900
So let's make a function definition and it's going to be these lines of code here.

18:34.200 --> 18:40.200
So I'm going to go ahead and control X and control V.

18:40.230 --> 18:43.140
Now we have a function that does these things for us.

18:43.140 --> 18:49.500
We can call it here and possessed by and we can call it here and on Player state.

18:49.500 --> 18:58.800
And we'll have a comment here that says init ability actor info for the client and that's it.

18:58.830 --> 19:04.020
Now if you didn't do this refactor into a function, that's totally fine.

19:04.020 --> 19:06.600
It's okay if you repeated yourself not a big deal.

19:06.600 --> 19:10.020
I do recommend making a function, but you don't have to.

19:10.020 --> 19:12.660
And now we've achieved a couple things.

19:12.660 --> 19:16.950
For one, our ability system components know who their owner is.

19:16.980 --> 19:20.880
They know who the owner actor is and they know who the Avatar actor is.

19:20.910 --> 19:27.360
That's going to be very, very useful and convenient as we continue programming in gas throughout this

19:27.360 --> 19:34.260
course, because there will be many, many times when we need to access those owners in our abilities

19:34.260 --> 19:37.230
in our various gas classes.

19:37.230 --> 19:40.530
So this is a very important and crucial step.

19:40.710 --> 19:47.340
And before we end the video, I'm going to bring your attention back to the replication mode.

19:47.340 --> 19:54.420
Again, remember, we set our ability system component for the player controlled character to mixed

19:54.420 --> 19:55.500
replication mode.

19:55.500 --> 19:59.790
And it's important to know a couple of details when you do this.

20:00.680 --> 20:02.420
For mixed replication mode.

20:02.450 --> 20:08.250
It's important to know that the owner actors, owner must be the controller.

20:08.270 --> 20:15.080
Now, in our case the owner actor for our ability system component, at least for the player controlled

20:15.080 --> 20:19.070
character that has mixed replication mode is the player state.

20:19.070 --> 20:24.410
That's who we set as the owner actor in an ability actor info.

20:24.440 --> 20:29.720
Now we don't need to set the player state's owner to the controller because that's what happens.

20:29.720 --> 20:30.920
By default.

20:30.920 --> 20:36.620
The player state's owner is automatically set to the controller, so we don't really need to do anything.

20:36.650 --> 20:40.780
Similarly for pawns this is automatically set in possessed by.

20:40.790 --> 20:48.470
So if the owner actor for the ability system component is the pawn well in possessed by the pawns owner

20:48.470 --> 20:50.210
will be set to the controller.

20:50.540 --> 20:57.680
But if your owner actor is not the player state and you're using mixed replication mode, you must call

20:57.680 --> 21:03.580
set owner on the owner actor and set its owner to the controller.

21:03.600 --> 21:10.410
So even though we don't need to worry about it because our owner actor is the player state and the player

21:10.410 --> 21:13.710
state's owner is already set to the controller.

21:13.740 --> 21:20.640
You need to know this because your owner actor may be some class that does not automatically get its

21:20.640 --> 21:23.070
owner set to the controller.

21:23.070 --> 21:27.870
In that case, you're going to want to make sure that it is if applicable.

21:28.080 --> 21:32.730
You might have an ability system component on some actor that doesn't have a controller.

21:32.730 --> 21:35.770
In that case, that's fine, don't worry about it.

21:35.790 --> 21:42.120
But for mixed replication mode, the owner actor's owner must be the controller.

21:42.120 --> 21:43.700
So keep this in mind.

21:43.710 --> 21:49.620
This is not something that you'll worry about in this course, in this project, but keep it in mind

21:49.620 --> 21:52.860
for your future gas projects where things might be different.

21:53.220 --> 21:55.510
So just something you might want to jot down.

21:55.530 --> 21:56.130
Okay.

21:56.130 --> 21:57.180
Excellent job.

21:57.210 --> 22:00.720
We'll continue with this in the next video.
