WEBVTT

00:06.830 --> 00:08.000
Welcome back.

00:08.240 --> 00:13.760
Now we're here in our custom ability task target data under mouse.

00:13.760 --> 00:20.270
And we found that just getting our mouse cursor data and broadcasting is not going to work.

00:20.300 --> 00:29.030
As if this is not a locally controlled player, then this cursor hit will not have valid data.

00:29.150 --> 00:35.750
So we need a function that we can use to send data to the server and we should call this function if

00:35.750 --> 00:37.280
we're locally controlled.

00:37.430 --> 00:41.090
So I'm going to make a function on target data under mouse.

00:41.090 --> 00:47.810
This can be private and we'll call this void function send mouse cursor data.

00:48.110 --> 00:55.460
So let's go ahead and generate this definition and we'll call this function if we are locally controlled.

00:55.490 --> 01:01.130
You see, if we're locally controlled, we can call this function and broadcast our delegate.

01:01.160 --> 01:02.410
No problem.

01:02.420 --> 01:05.590
If we're on the server and we're locally controlled, then good.

01:05.600 --> 01:07.740
We're broadcasting the delegate.

01:07.740 --> 01:12.510
If we're on the client and we're locally controlled, we're broadcasting the delegate, yes, but we're

01:12.510 --> 01:14.610
also sending data to the server.

01:14.760 --> 01:18.510
So in activate what we should do at the very top.

01:18.510 --> 01:22.080
First thing is we should check to see if we're locally controlled.

01:22.080 --> 01:23.340
So I'm going to make a const.

01:23.340 --> 01:28.850
Bool called B is locally controlled, so how am I going to set this?

01:28.860 --> 01:36.420
Well, we have access to the ability and through the ability we can use get current actor info and from

01:36.420 --> 01:44.040
the current actor info we can call is locally controlled and now we can check if B is locally controlled.

01:44.040 --> 01:48.090
And if we are, we're going to call send mouse cursor data.

01:50.730 --> 01:54.600
Now, if we're not locally controlled, we have to do something else.

01:54.600 --> 01:56.160
So here we'll have a to do.

01:56.190 --> 02:00.900
We'll say to do we are on the server.

02:00.960 --> 02:04.620
So listen for target data.

02:05.070 --> 02:11.700
Now send mouse cursor data needs to actually create some target data and send it Now.

02:11.700 --> 02:14.070
What is target data anyway?

02:14.070 --> 02:22.110
Well, I'm going to hit double shift and search for gameplay ability target types.

02:22.110 --> 02:23.230
Dot h.

02:23.890 --> 02:27.130
And here we have gameplay ability target types.

02:27.130 --> 02:28.390
Looks like I opened the CP.

02:28.510 --> 02:35.340
Here's the h file and here is where a lot of target data structs are defined.

02:35.350 --> 02:45.250
We can search for F gameplay ability target data and we'll see a lot of things in here, including a

02:45.280 --> 02:52.090
handle to target data and lots of things that have to do with target data.

02:52.450 --> 02:56.680
I'm going to go to the declaration of F gameplay ability target data.

02:57.220 --> 03:03.300
And we'll see that it has a few functions and most of them are virtual that you can override.

03:03.310 --> 03:09.130
And then there are classes derived from game play ability target data.

03:09.310 --> 03:18.010
For example, we have gameplay ability target data, underscore location info.

03:18.040 --> 03:20.380
We have single target hit.

03:20.410 --> 03:25.900
Now single target hit is what I'm interested in because it says right here target data with a single

03:25.900 --> 03:28.740
hit result data is packed into the hit result.

03:28.750 --> 03:30.280
So this is great.

03:30.280 --> 03:35.650
It just has a single hit result and if we send that to the server, the server can get the location

03:35.650 --> 03:37.090
from that hit result.

03:37.240 --> 03:38.620
So this is great.

03:38.770 --> 03:42.760
So I'd like to use this target data type.

03:42.760 --> 03:43.810
So here's what I can do.

03:43.810 --> 03:51.040
I'll go back to target data under mouse in my send mouse cursor data function and I'm going to create

03:51.040 --> 03:57.860
a new object of this target data type, which is F gameplay ability.

03:57.890 --> 04:03.080
Target data underscore single target hit.

04:03.110 --> 04:11.630
I'm going to make a pointer of it called data and use simply the new keyword new F gameplay ability

04:11.690 --> 04:14.090
target data single target hit.

04:14.600 --> 04:20.840
So if I'm locally controlled, send mouse cursor data is going to create a new object of this type.

04:20.840 --> 04:29.120
Now we can just get this data and set its hit result because data is an gameplay ability target data,

04:29.120 --> 04:32.120
single target hit which has a hit result.

04:32.360 --> 04:36.470
So we can set that equal to well the hit result under the cursor.

04:36.470 --> 04:37.250
Right.

04:37.250 --> 04:45.350
So right after I've created data, I can take these lines that I've left over here, control X to cut

04:45.350 --> 04:48.380
them, paste them right here and what are we doing?

04:48.380 --> 04:53.630
We're getting the player controller making a hit result called cursor hit, getting the hit result under

04:53.630 --> 04:54.590
the cursor.

04:54.590 --> 04:58.790
And I don't want to broadcast valid data just yet.

04:58.790 --> 05:04.940
First, I want to take my newly created data and set its hit result to cursor hit.

05:06.050 --> 05:13.850
And in fact, really we could create the local variable data right here just before we set its hit result.

05:14.270 --> 05:16.370
Now this is all great.

05:16.370 --> 05:23.660
We have a target data object, but we're going to have to send this up to the server, right?

05:23.660 --> 05:27.170
And that means we need to get the ability system component.

05:27.230 --> 05:33.380
Well, ability tasks have an ability system component variable that's pretty convenient.

05:33.380 --> 05:39.170
And through that variable we can call functions and there's a function I want to call.

05:39.170 --> 05:47.210
We have server set replicated and there's a lot of server set replicated stuff here.

05:47.210 --> 05:51.110
We want server set, replicated target data.

05:51.920 --> 05:53.810
Now what does this function need?

05:53.810 --> 05:59.740
Well, we'd get some helpful pop ups if ability system component wasn't incomplete type.

05:59.740 --> 06:02.950
So I'm going to go ahead and include its header file here.

06:04.070 --> 06:07.190
Writer won't be so kind as to help me with that.

06:07.190 --> 06:12.920
So I'm going to include ability system components and now we get the useful pop up.

06:12.920 --> 06:19.430
Now the first input is a gameplay ability spec handle well, we can easily get the spec handle from

06:19.430 --> 06:27.830
any ability task with get ability spec handle ability tasks have easy access to that.

06:28.160 --> 06:32.180
Now next is a prediction key and we'll talk about prediction keys.

06:32.210 --> 06:34.940
It's just about time to start talking about them.

06:34.940 --> 06:40.820
But if we're going to be predicting anything, anything that's predicted is associated with a prediction

06:40.820 --> 06:41.390
key.

06:41.420 --> 06:46.880
Now, this is a prediction, key input called ability original prediction key.

06:46.880 --> 06:53.750
When it says original prediction key, it's talking about when this ability was originally activated.

06:53.750 --> 07:01.970
We can get that from ability tasks with the function get activation prediction key so that will satisfy

07:01.970 --> 07:02.820
that input.

07:02.840 --> 07:08.220
Next, we have a gameplay ability target data handle.

07:08.220 --> 07:12.180
Now we have target data, but we don't have a data handle.

07:12.180 --> 07:17.760
We're going to need to create one and package up this target data into that handle.

07:17.760 --> 07:20.580
So first we're going to make an object of that type.

07:20.580 --> 07:26.940
So F gameplay ability target data handle and we're going to call this data handle.

07:27.150 --> 07:33.180
And after we've created data, we're going to add this target data to our data handle.

07:33.180 --> 07:40.260
So we're going to say data handle and data handle has a handy add function that can take in target data.

07:40.260 --> 07:42.690
We're going to pass data right on in.

07:43.020 --> 07:44.190
That's it.

07:44.190 --> 07:48.120
And now we can pass that data handle in right here.

07:48.120 --> 07:50.610
So we'll pass in data handle.

07:50.850 --> 07:56.490
Now this function requires an application tag and it's going to pass that tag on up whether we use it

07:56.490 --> 07:57.090
or not.

07:57.090 --> 07:58.680
And that's a gameplay tag.

07:58.680 --> 08:01.290
So we need to create one of those as well.

08:01.290 --> 08:07.760
So f gameplay tag application tag and we can pass that in here.

08:10.310 --> 08:17.270
Alternatively, we can pass in gameplay tag and just pass it in as a temporary.

08:17.300 --> 08:20.360
Since I'm not really setting this to anything, that's what I'm going to do.

08:20.480 --> 08:22.790
Now what comes after the tag?

08:22.820 --> 08:27.020
Another prediction key, but this one is the current prediction key.

08:27.170 --> 08:28.330
So what's the difference?

08:28.340 --> 08:34.010
Well, we said that the original prediction key was associated with the activation of the ability.

08:34.130 --> 08:40.910
We need one for right now, this particular context, and we can create one using our ability system

08:40.910 --> 08:41.900
component.

08:42.170 --> 08:51.560
So we take ability system component and from it we get scoped prediction key and that satisfies the

08:51.560 --> 08:52.670
last input.

08:52.850 --> 08:58.480
So the ability system component always has access to the current prediction key.

08:58.490 --> 09:01.160
And again, we'll learn more about those soon.

09:01.310 --> 09:07.820
I'm going to go ahead and put each of these inputs on their own line so we can see them as this is quite

09:07.820 --> 09:15.240
a hefty function call and now send mouse cursor data is sending target data up to the server.

09:15.420 --> 09:22.650
Now that doesn't mean we shouldn't still broadcast the valid data locally so that we can see that cursor

09:22.650 --> 09:27.360
data on the local client so we can go ahead and broadcast that delegate.

09:27.360 --> 09:29.490
But there's a function we should check.

09:29.520 --> 09:33.750
It's called should broadcast ability task Delegates.

09:33.780 --> 09:34.140
Why?

09:34.170 --> 09:40.950
Because there are certain circumstances where we should not broadcast our ability task delegates.

09:41.040 --> 09:45.870
In fact, the pop up says this should be called prior to broadcasting delegates back into the ability

09:45.870 --> 09:46.620
graph.

09:46.650 --> 09:49.460
This makes sure the ability is still active.

09:49.470 --> 09:54.860
So if the ability is not still active, this will prevent us from broadcasting when we shouldn't.

09:54.870 --> 10:00.750
So I'm going to go ahead and wrap this in an if statement before we broadcast, and then we'll broadcast

10:00.750 --> 10:02.040
our valid data.

10:02.430 --> 10:03.360
Now.

10:03.980 --> 10:04.580
Are valid.

10:04.580 --> 10:11.540
Data, though, requires an F vector, but I'd like to change that from vector to.

10:11.570 --> 10:17.900
Data handle so that we can go ahead and pass that whole data handle through the broadcast and then we

10:17.900 --> 10:22.400
can get the hit results and anything else that the target data has inside of it.

10:22.400 --> 10:24.500
In our case, just the hit result, right?

10:24.500 --> 10:26.710
So I'm going to change this valid data.

10:26.720 --> 10:31.340
Let's go back to target data under mouse and change our delegate.

10:31.340 --> 10:38.300
And instead of a const reference to a vector, I'm going to have this be a const reference to an F gameplay

10:38.300 --> 10:39.440
ability.

10:40.220 --> 10:42.590
Target data handle.

10:42.620 --> 10:47.510
That way we can pass data handles and I'll call this data handle now.

10:47.750 --> 10:51.200
So now we're going to broadcast the data handle.

10:51.790 --> 10:57.040
Instead of just an f vector, and then we'll get the vector from that data handle.

10:57.640 --> 10:58.540
Okay, great.

10:58.540 --> 11:03.680
So we'll send that data up to the server and on the server we need to receive it.

11:03.700 --> 11:05.490
We're going to do that very soon.

11:05.500 --> 11:08.530
For now we have this function and it's looking pretty good.

11:08.530 --> 11:13.000
And before we move on, notice we got this scoped prediction key, right?

11:13.000 --> 11:15.820
And it's not a function, it's just a variable.

11:15.820 --> 11:18.190
So when is that updated?

11:18.190 --> 11:19.690
Well, we have to do that.

11:19.720 --> 11:26.860
What we do is we say we're creating a scoped prediction window, which is a window during which everything

11:26.860 --> 11:29.920
we do here locally is going to be predicted.

11:29.920 --> 11:36.100
It's scoped, meaning that it's limited to the scope of where we are when we create the window.

11:36.250 --> 11:40.930
I'm going to create one right here before doing anything in this function.

11:40.930 --> 11:44.890
So right up here at the top, I'm creating a scoped prediction window.

11:44.890 --> 11:49.420
So we create f scoped prediction window.

11:49.570 --> 11:52.240
I'm going to call this scoped prediction on.

11:53.970 --> 11:56.280
And this requires an ability system component.

11:56.280 --> 11:58.680
So we're going to pass an ability system component.

11:58.710 --> 12:02.940
Now this is a pointer wrapper, so we're going to call get on it.

12:04.220 --> 12:11.300
And then we have a Boolean in set replicated prediction key, and that's an optional parameter set to

12:11.300 --> 12:12.290
true by default.

12:12.290 --> 12:13.370
So we'll leave it out.

12:13.370 --> 12:18.830
So what we're doing is we're saying that everything within this scope should be predicted.

12:18.920 --> 12:25.490
So server, please allow us to do what we're doing here locally, no problem.

12:25.490 --> 12:29.090
And then the server will do it when the server knows about it.

12:29.090 --> 12:34.790
And this is how we can do predicted things here in our ability task functions.

12:35.560 --> 12:42.400
And if we right click on scope prediction window go to declaration or usages, we see it's in gameplay

12:42.400 --> 12:49.480
prediction H, which is a file that contains lots of comments that can help you understand how prediction

12:49.480 --> 12:50.290
works.

12:50.470 --> 12:56.530
We see that the comment says to be called on server when a new prediction key is received from the client

12:56.530 --> 12:57.690
and an RPC.

12:58.240 --> 13:00.820
That's for when we're on the server.

13:00.820 --> 13:06.640
But then we also see F scope prediction window that says to be called and the call site where the predictive

13:06.640 --> 13:07.920
code will take place.

13:07.930 --> 13:14.290
This generates a new prediction key and acts as a synchronization point between client and server for

13:14.320 --> 13:15.090
that key.

13:15.100 --> 13:21.400
And again, we'll talk about this more in detail later, but we see that this is how we can predict

13:21.400 --> 13:22.060
things.

13:22.420 --> 13:29.470
Okay, So we're going to stop here and we'll flesh out more of the code in this class in the lectures

13:29.470 --> 13:30.130
to come.

13:30.130 --> 13:34.960
But for now, we have completed our send mouse cursor data function.

13:34.990 --> 13:40.130
All that's left is to receive that data on the server and do something with it.

13:40.520 --> 13:42.740
Great job and I'll see you in the next video.
