WEBVTT

00:06.820 --> 00:08.040
Welcome back.

00:08.050 --> 00:11.680
In this video, we're concerned with receiving the target data.

00:11.800 --> 00:15.820
We know that we're sending it client side up to the server now.

00:15.820 --> 00:17.290
We need to listen for it.

00:17.290 --> 00:18.970
So we have our to do here.

00:18.970 --> 00:25.300
Now, when target data reaches the server, there's a delegate broadcast, as we've said, and we can

00:25.300 --> 00:28.450
get that delegate through the ability system component.

00:28.450 --> 00:36.160
So I'm going to say ability system component dot get and I'm going to call a function ability target

00:36.160 --> 00:39.520
data set delegate.

00:39.850 --> 00:49.960
Now this returns the target data set delegate, but it's the delegate for a given ability slash prediction

00:49.960 --> 00:51.100
key pair.

00:51.100 --> 00:58.000
In other words, it needs to know that prediction key associated with the target data.

00:58.000 --> 01:06.250
So in order to know that information, the function we're calling here needs the spec handle for the

01:06.250 --> 01:10.220
ability that's associated with this specific task.

01:10.220 --> 01:12.800
So we need to get that spec handle.

01:12.800 --> 01:16.520
Now we can call get ability spec handle for that.

01:16.550 --> 01:24.050
Next, we need the prediction key and that's the activation prediction key as this says original, right?

01:24.050 --> 01:30.860
That's the activation prediction key we can pass in get activation prediction key.

01:30.890 --> 01:37.130
Now this function gives us the delegate and from the delegate right here at the very end, we can hit

01:37.130 --> 01:40.130
the dot and we can bind a function to it.

01:40.130 --> 01:44.750
We can use add you object, or we could bind a lambda to it.

01:44.750 --> 01:48.740
If we wanted to do that, we could say add lambda, right?

01:49.070 --> 01:55.460
Let's go ahead and make a function that we can bind to it just so that we can encapsulate that functionality

01:55.460 --> 01:56.690
into a little function.

01:56.690 --> 02:02.030
So I'm going to go to target data under mouse dot H and make that function.

02:02.030 --> 02:06.590
Now the function needs to have a specific signature and we're going to make sure that it has one.

02:06.590 --> 02:08.540
So it's going to be a void function.

02:08.540 --> 02:16.550
I'd like to call it on target data replicated callback, just so it's clear that this is a callback

02:16.550 --> 02:20.570
and this callback has to have the correct signature, right?

02:20.570 --> 02:24.710
Because it's going to be bound to this target data set delegate.

02:24.740 --> 02:28.330
Now target data set is going to broadcast two things.

02:28.340 --> 02:35.330
It's going to broadcast the target data handle and it's going to broadcast that activation tag associated

02:35.330 --> 02:35.990
with it.

02:36.080 --> 02:39.950
Now we're just sending an empty tag, but it's still going to come through.

02:39.950 --> 02:42.290
So this function needs to take both of those.

02:42.320 --> 02:49.130
The first is a const reference to gameplay ability target data handle.

02:49.130 --> 02:52.580
That's a const reference and we'll call this data handle.

02:53.390 --> 02:59.450
And the second input is a gameplay tag just passed by value.

02:59.870 --> 03:02.990
And this is called activation tag.

03:03.730 --> 03:05.860
So we'll generate this callback.

03:08.790 --> 03:13.920
So we have it down here and this is the function will bind to the delegate.

03:13.950 --> 03:16.770
Up here we'll use add to object.

03:17.190 --> 03:27.240
So passing in this for the user object and the address of you target data under mouse on target data

03:27.240 --> 03:28.800
replicated callback.

03:29.190 --> 03:31.320
So we're binding that function to it.

03:31.320 --> 03:32.580
So that's good.

03:32.580 --> 03:38.850
So as soon as activate is called on the server, the server will bind its callback to this delegate.

03:38.970 --> 03:46.530
But what happens if we're too late and the target data has already been sent and the delegate has already

03:46.530 --> 03:47.550
been broadcast?

03:47.580 --> 03:51.730
Well, in that case we should call that callback anyway.

03:51.750 --> 03:59.640
So there's a way to check, or at least a way to call that target data delegate if it's already received

03:59.670 --> 04:00.770
target data.

04:00.780 --> 04:04.020
So we can do that through the ability system component.

04:04.140 --> 04:14.110
So we'll use ability system component dot get and the function is call replicated target data delegate

04:14.110 --> 04:15.130
if set.

04:15.400 --> 04:17.650
Now this requires the spec handle.

04:17.800 --> 04:28.300
Now I'm just going to create a local gameplay ability spec handle called spec handle here just so I

04:28.300 --> 04:31.060
don't have to keep calling that getter function.

04:31.060 --> 04:40.870
So I'm going to say spec handle equals, get ability spec handle and pass that in both here and here.

04:41.560 --> 04:45.340
And then our activation prediction key, I'm going to do the same thing.

04:45.340 --> 04:55.810
I'm going to make an F prediction key called activation prediction key and call get activation prediction

04:55.810 --> 05:02.590
key and simply pass that in right here and right here.

05:03.040 --> 05:05.170
Then we don't have to call those getters twice.

05:05.170 --> 05:06.850
And there we go.

05:07.120 --> 05:10.750
So this will ensure that we're calling that function.

05:10.750 --> 05:17.260
Now, this returns a boolean that will be true or false, depending on if that delegate had already

05:17.260 --> 05:25.240
been set and if we should still listen for it so we can go to the function call replicated target data

05:25.240 --> 05:26.110
if set.

05:26.110 --> 05:34.780
And we see that there's this local bool called delegate set to false, but it's set to true if the broadcast

05:34.780 --> 05:38.740
is made right because we're broadcasting the target set delegate here.

05:38.740 --> 05:46.600
If target data has already reached the server and in that case, well cool, the server will now receive

05:46.600 --> 05:47.790
that data.

05:47.800 --> 05:57.460
So this function returns a boolean, we can store it in a const bool called be called delegate.

05:58.690 --> 06:05.920
And the reason I'm doing this is because we need to tell the server to wait for player data to come

06:05.920 --> 06:06.670
through.

06:06.940 --> 06:13.030
So if it's already been set and we're broadcasting it well, we don't have to care about anything anymore.

06:13.210 --> 06:17.140
Otherwise though, if be called delegate is false.

06:17.140 --> 06:24.730
In other words, if not be called delegate, then we need to call set waiting on remote player data

06:25.300 --> 06:31.570
and that's going to tell the server, look, we're still waiting for remote player data and we can go

06:31.570 --> 06:33.790
to this definition to see what it does.

06:33.790 --> 06:40.960
It just sets a wait flag and tells the ability, Look, we're waiting for player data.

06:40.960 --> 06:47.050
So in our task, if we did not call this delegate, that means it hasn't reached the server yet.

06:47.050 --> 06:49.780
So we'll be waiting for that data to come back.

06:50.170 --> 06:50.980
Okay.

06:51.280 --> 06:54.130
And these both can be const variables here.

06:55.190 --> 06:56.900
Since we're not going to change them.

06:57.200 --> 06:57.860
All right.

06:57.860 --> 07:04.040
So the last thing is to decide how on target data replicated callback will behave.

07:04.040 --> 07:05.450
What is it going to do?

07:05.480 --> 07:13.700
Well, if we go into this function, we know this function will be called in response to receiving target

07:13.700 --> 07:16.760
data, receiving replicated target data.

07:16.760 --> 07:22.040
Now, I know we've mentioned early on in the course that replication only happens from server to client,

07:22.040 --> 07:27.200
but in gas you'll see a lot of functions that kind of use the term both ways.

07:27.200 --> 07:32.210
Replicated data being sent from client to server via Rpcs.

07:32.240 --> 07:38.810
Sometimes the gas system refers to that as replicated data, so that's something to be aware of.

07:39.140 --> 07:44.690
But this function will be called on the server when replicated data has been received.

07:44.690 --> 07:51.830
And in that case we need to broadcast it so that our ability task in the game play ability will have

07:51.830 --> 07:55.800
its valid data execution pin executed.

07:55.800 --> 08:03.000
So what we can do is we can broadcast that data, but we also need to make sure that the ability system

08:03.000 --> 08:09.540
component knows that that data has been received because when replicated target data is received by

08:09.540 --> 08:15.870
the server, it's stored in a specific data structure and we can tell the ability system component we

08:15.870 --> 08:17.340
have received the data.

08:17.430 --> 08:21.090
You don't need to store it, you don't need to keep it cached anymore.

08:21.090 --> 08:29.850
So we do that by taking the ability system component and calling consume client replicated target data.

08:29.850 --> 08:37.020
And this requires the ability spec handle so we can call get ability spec handle and it requires the

08:37.020 --> 08:41.460
ability original prediction key that's get activation prediction key.

08:41.460 --> 08:44.250
So this tells the ability system.

08:44.250 --> 08:48.870
Okay, target data has been received, don't keep it stored.

08:48.870 --> 08:50.940
We don't need to keep that cached.

08:50.940 --> 08:57.570
And if we go to the definition of this, we see that through the ability spec handle and the prediction

08:57.570 --> 09:05.430
key, the ability system component is able to find something called ability replicated data cache.

09:05.430 --> 09:09.390
And this is inside of the ability target data map.

09:09.390 --> 09:15.720
So this map associates the ability spec handle and prediction key with target data.

09:15.720 --> 09:24.030
And so for each ability spec handle and prediction key, there is a target data in that cached data

09:24.030 --> 09:29.760
data structure that will be cleared when we call consume client replicated target data.

09:29.760 --> 09:36.180
And it also has Target confirmed and Target canceled Booleans so that it knows whether or not the target

09:36.180 --> 09:38.490
data has been sent or received and so on.

09:38.490 --> 09:45.060
So consume is going to tell the ASC we've received the data, don't worry about it anymore, just clear

09:45.060 --> 09:50.040
it from your cache for this specific ability, spec and prediction key.

09:50.040 --> 09:57.180
So now that we've done that, we can broadcast the delegate, but of course we should check should broadcast

09:57.180 --> 09:58.800
ability task delegates.

09:58.800 --> 10:06.150
So just like we did up here in send mouse cursor data, we're going to check first before broadcasting

10:06.150 --> 10:08.400
the delegate just like that.

10:08.490 --> 10:12.300
And we're just broadcasting that data handle straight on through.

10:12.720 --> 10:13.170
Okay.

10:13.170 --> 10:16.770
So our task is looking pretty much complete.

10:16.800 --> 10:18.870
We're almost ready to test it out.

10:18.870 --> 10:25.230
But there's one last step that we have to do in our project before we can even use target data.

10:25.380 --> 10:27.060
And this is a very important step.

10:27.060 --> 10:32.940
If you had tried to use target data by play testing in the last video, you might have run into an issue.

10:32.940 --> 10:35.760
In fact, let's see what that issue is.

10:35.790 --> 10:39.360
Let's go ahead and just compile and run and debug mode.

10:41.390 --> 10:41.870
Okay.

10:41.870 --> 10:45.170
So I'm going to go ahead and open up the ability.

10:45.200 --> 10:49.220
Now, this target data under mouse is no longer valid.

10:49.250 --> 10:50.690
We've changed it quite a bit.

10:50.690 --> 10:54.560
So I'm going to go ahead and right click refresh nodes.

10:54.560 --> 11:03.080
And now we get a data handle when target data under mouse is activated and from the data handle, if

11:03.080 --> 11:11.810
we drag off and we can type target data, hit and say get hit, result from target data that returns

11:11.810 --> 11:18.500
us a hit result and from the hit result we can break that hit result and get location.

11:19.260 --> 11:24.420
And or impact point either one hook that in to draw debug sphere.

11:24.690 --> 11:26.850
Okay so we think that's going to work.

11:26.850 --> 11:29.100
All right, let's press play.

11:29.670 --> 11:31.590
And click on the client.

11:31.590 --> 11:33.630
Actually, we need to click on an enemy.

11:34.480 --> 11:36.800
And look what happened.

11:36.820 --> 11:37.780
Interesting.

11:37.780 --> 11:41.580
And you might not really even realize what's happened.

11:41.590 --> 11:42.780
Look at what's happened.

11:42.790 --> 11:47.860
If I fullscreen the client, it's in a completely new game instance.

11:47.890 --> 11:49.840
The server character is gone.

11:49.840 --> 11:52.570
And if we look at the server, look, the client is gone.

11:52.570 --> 11:53.600
What happened?

11:53.620 --> 11:55.810
The client got disconnected.

11:55.930 --> 11:58.870
Let's see what happens in the output log.

12:00.330 --> 12:03.300
Going to press play here on the client.

12:03.300 --> 12:05.260
I'm going to click on an enemy.

12:05.280 --> 12:06.790
Oh, there was some red.

12:06.810 --> 12:12.660
Let's look at that red text that we got there and we got kind of a few things.

12:12.660 --> 12:15.480
But look at our first log ability.

12:15.480 --> 12:23.150
System error could not find gameplay ability target data, single target hit in script struct cache.

12:23.160 --> 12:28.170
So we get errors related to target data because I told you there was something we need to do.

12:28.170 --> 12:29.640
That's very important.

12:29.640 --> 12:32.340
In order for our target data to work.

12:32.340 --> 12:37.290
We can't use target data without performing this very, very important step.

12:37.290 --> 12:46.680
And that very important step is to go into our class or asset manager and in fact we need to go into

12:46.680 --> 12:51.600
the CPP file for it and right here and start initial loading.

12:51.600 --> 12:58.020
There's something we have to do that's very, very important if we want to use target data and that

12:58.020 --> 13:06.220
is to use you ability system globals and call the function.

13:06.580 --> 13:12.970
First of all, get because this is a singleton and call the function init global data.

13:13.360 --> 13:14.830
So why do we have to do that?

13:14.830 --> 13:22.510
Well, if we go to init global data then we'll see that it initializes some things, including target

13:22.510 --> 13:23.230
data.

13:23.260 --> 13:28.480
Specifically it calls init target data script struct cache.

13:28.630 --> 13:31.120
That's what that error was talking about.

13:31.150 --> 13:33.580
It couldn't find the script struct cache.

13:34.410 --> 13:41.070
If we go to this definition, we see that there's something called a target data script struct cache

13:41.070 --> 13:46.650
and it's initializing it for game playability target data.

13:46.680 --> 13:50.160
It's calling static struct on there to get that struct.

13:50.250 --> 13:52.620
So this is a very important step.

13:52.650 --> 14:00.300
We won't get into the details of what this is doing until we get more into data serialization, which

14:00.300 --> 14:02.370
we will in videos to come.

14:02.370 --> 14:07.950
But now that we've called this very important function in our asset manager, we can use target data.

14:07.950 --> 14:09.300
So it might even be worth it.

14:09.300 --> 14:15.930
Sticking a comment in here and say this is required to use target data.

14:16.320 --> 14:18.480
It just might be worth it to do that.

14:18.630 --> 14:24.540
So now that we've called init Global Data, we can test this out and see how it works.

14:26.220 --> 14:26.640
All right.

14:26.640 --> 14:27.900
We're back in the editor.

14:27.900 --> 14:35.280
And all we're doing in our ability is drawing a debug sphere once we get that target data and then ending

14:35.280 --> 14:36.300
the ability.

14:36.330 --> 14:39.430
So why don't we give this a try?

14:39.450 --> 14:40.620
We'll press play.

14:40.800 --> 14:45.770
And really, first things first, we're going to check this out on the client.

14:45.780 --> 14:50.640
So here on the client, I'm going to click and we see that sphere over there.

14:50.670 --> 14:52.650
Do we see it on the server?

14:52.690 --> 14:54.540
Oh, yes, we do.

14:54.570 --> 14:55.980
We definitely do.

14:56.010 --> 14:57.840
So here I'm on the client.

14:57.840 --> 14:59.660
I'm going to click on this guy over here.

14:59.670 --> 15:00.750
Boom, Look at that.

15:00.750 --> 15:03.840
We see it both on client and on server.

15:03.840 --> 15:10.560
We're successfully sending target data up to the server and that target data just contains a hit result.

15:10.560 --> 15:16.800
But this is huge because now our clients are sending data to the server and now we're both on the same

15:16.800 --> 15:17.520
page.

15:17.520 --> 15:22.020
Both client and server knows where that target data is.

15:22.050 --> 15:24.450
Now don't worry about other clients.

15:24.450 --> 15:30.300
They shouldn't really even need to know where that target data is on this client.

15:30.310 --> 15:35.500
If I click over here, no, we're not doing it over on that client over there.

15:35.500 --> 15:37.840
That's not really necessary.

15:37.840 --> 15:40.750
All we care about is getting that data up to the server.

15:40.780 --> 15:46.810
I just want my target data sent to the server so the server can know where I'm clicking and then the

15:46.810 --> 15:53.410
server can launch that authoritative fireball in the correct direction.

15:53.500 --> 15:59.620
So I'm going to go ahead and close the output log and we now know which direction to send that fireball

15:59.620 --> 16:07.720
and that's going to be what we're concerned with next, is launching the fireball in the correct direction.

16:07.720 --> 16:08.770
So great job.

16:08.770 --> 16:11.500
We'll continue with this in the next video.
