Welcome back.
Now we're here in our custom ability task target data under mouse.
And we found that just getting our mouse cursor data and broadcasting is not going to work.
As if this is not a locally controlled player, then this cursor hit will not have valid data.
So we need a function that we can use to send data to the server and we should call this function if
we're locally controlled.
So I'm going to make a function on target data under mouse.
This can be private and we'll call this void function send mouse cursor data.
So let's go ahead and generate this definition and we'll call this function if we are locally controlled.
You see, if we're locally controlled, we can call this function and broadcast our delegate.
No problem.
If we're on the server and we're locally controlled, then good.
We're broadcasting the delegate.
If we're on the client and we're locally controlled, we're broadcasting the delegate, yes, but we're
also sending data to the server.
So in activate what we should do at the very top.
First thing is we should check to see if we're locally controlled.
So I'm going to make a const.
Bool called B is locally controlled, so how am I going to set this?
Well, we have access to the ability and through the ability we can use get current actor info and from
the current actor info we can call is locally controlled and now we can check if B is locally controlled.
And if we are, we're going to call send mouse cursor data.
Now, if we're not locally controlled, we have to do something else.
So here we'll have a to do.
We'll say to do we are on the server.
So listen for target data.
Now send mouse cursor data needs to actually create some target data and send it Now.
What is target data anyway?
Well, I'm going to hit double shift and search for gameplay ability target types.
Dot h.
And here we have gameplay ability target types.
Looks like I opened the CP.
Here's the h file and here is where a lot of target data structs are defined.
We can search for F gameplay ability target data and we'll see a lot of things in here, including a
handle to target data and lots of things that have to do with target data.
I'm going to go to the declaration of F gameplay ability target data.
And we'll see that it has a few functions and most of them are virtual that you can override.
And then there are classes derived from game play ability target data.
For example, we have gameplay ability target data, underscore location info.
We have single target hit.
Now single target hit is what I'm interested in because it says right here target data with a single
hit result data is packed into the hit result.
So this is great.
It just has a single hit result and if we send that to the server, the server can get the location
from that hit result.
So this is great.
So I'd like to use this target data type.
So here's what I can do.
I'll go back to target data under mouse in my send mouse cursor data function and I'm going to create
a new object of this target data type, which is F gameplay ability.
Target data underscore single target hit.
I'm going to make a pointer of it called data and use simply the new keyword new F gameplay ability
target data single target hit.
So if I'm locally controlled, send mouse cursor data is going to create a new object of this type.
Now we can just get this data and set its hit result because data is an gameplay ability target data,
single target hit which has a hit result.
So we can set that equal to well the hit result under the cursor.
Right.
So right after I've created data, I can take these lines that I've left over here, control X to cut
them, paste them right here and what are we doing?
We're getting the player controller making a hit result called cursor hit, getting the hit result under
the cursor.
And I don't want to broadcast valid data just yet.
First, I want to take my newly created data and set its hit result to cursor hit.
And in fact, really we could create the local variable data right here just before we set its hit result.
Now this is all great.
We have a target data object, but we're going to have to send this up to the server, right?
And that means we need to get the ability system component.
Well, ability tasks have an ability system component variable that's pretty convenient.
And through that variable we can call functions and there's a function I want to call.
We have server set replicated and there's a lot of server set replicated stuff here.
We want server set, replicated target data.
Now what does this function need?
Well, we'd get some helpful pop ups if ability system component wasn't incomplete type.
So I'm going to go ahead and include its header file here.
Writer won't be so kind as to help me with that.
So I'm going to include ability system components and now we get the useful pop up.
Now the first input is a gameplay ability spec handle well, we can easily get the spec handle from
any ability task with get ability spec handle ability tasks have easy access to that.
Now next is a prediction key and we'll talk about prediction keys.
It's just about time to start talking about them.
But if we're going to be predicting anything, anything that's predicted is associated with a prediction
key.
Now, this is a prediction, key input called ability original prediction key.
When it says original prediction key, it's talking about when this ability was originally activated.
We can get that from ability tasks with the function get activation prediction key so that will satisfy
that input.
Next, we have a gameplay ability target data handle.
Now we have target data, but we don't have a data handle.
We're going to need to create one and package up this target data into that handle.
So first we're going to make an object of that type.
So F gameplay ability target data handle and we're going to call this data handle.
And after we've created data, we're going to add this target data to our data handle.
So we're going to say data handle and data handle has a handy add function that can take in target data.
We're going to pass data right on in.
That's it.
And now we can pass that data handle in right here.
So we'll pass in data handle.
Now this function requires an application tag and it's going to pass that tag on up whether we use it
or not.
And that's a gameplay tag.
So we need to create one of those as well.
So f gameplay tag application tag and we can pass that in here.
Alternatively, we can pass in gameplay tag and just pass it in as a temporary.
Since I'm not really setting this to anything, that's what I'm going to do.
Now what comes after the tag?
Another prediction key, but this one is the current prediction key.
So what's the difference?
Well, we said that the original prediction key was associated with the activation of the ability.
We need one for right now, this particular context, and we can create one using our ability system
component.
So we take ability system component and from it we get scoped prediction key and that satisfies the
last input.
So the ability system component always has access to the current prediction key.
And again, we'll learn more about those soon.
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
a hefty function call and now send mouse cursor data is sending target data up to the server.
Now that doesn't mean we shouldn't still broadcast the valid data locally so that we can see that cursor
data on the local client so we can go ahead and broadcast that delegate.
But there's a function we should check.
It's called should broadcast ability task Delegates.
Why?
Because there are certain circumstances where we should not broadcast our ability task delegates.
In fact, the pop up says this should be called prior to broadcasting delegates back into the ability
graph.
This makes sure the ability is still active.
So if the ability is not still active, this will prevent us from broadcasting when we shouldn't.
So I'm going to go ahead and wrap this in an if statement before we broadcast, and then we'll broadcast
our valid data.
Now.
Are valid.
Data, though, requires an F vector, but I'd like to change that from vector to.
Data handle so that we can go ahead and pass that whole data handle through the broadcast and then we
can get the hit results and anything else that the target data has inside of it.
In our case, just the hit result, right?
So I'm going to change this valid data.
Let's go back to target data under mouse and change our delegate.
And instead of a const reference to a vector, I'm going to have this be a const reference to an F gameplay
ability.
Target data handle.
That way we can pass data handles and I'll call this data handle now.
So now we're going to broadcast the data handle.
Instead of just an f vector, and then we'll get the vector from that data handle.
Okay, great.
So we'll send that data up to the server and on the server we need to receive it.
We're going to do that very soon.
For now we have this function and it's looking pretty good.
And before we move on, notice we got this scoped prediction key, right?
And it's not a function, it's just a variable.
So when is that updated?
Well, we have to do that.
What we do is we say we're creating a scoped prediction window, which is a window during which everything
we do here locally is going to be predicted.
It's scoped, meaning that it's limited to the scope of where we are when we create the window.
I'm going to create one right here before doing anything in this function.
So right up here at the top, I'm creating a scoped prediction window.
So we create f scoped prediction window.
I'm going to call this scoped prediction on.
And this requires an ability system component.
So we're going to pass an ability system component.
Now this is a pointer wrapper, so we're going to call get on it.
And then we have a Boolean in set replicated prediction key, and that's an optional parameter set to
true by default.
So we'll leave it out.
So what we're doing is we're saying that everything within this scope should be predicted.
So server, please allow us to do what we're doing here locally, no problem.
And then the server will do it when the server knows about it.
And this is how we can do predicted things here in our ability task functions.
And if we right click on scope prediction window go to declaration or usages, we see it's in gameplay
prediction H, which is a file that contains lots of comments that can help you understand how prediction
works.
We see that the comment says to be called on server when a new prediction key is received from the client
and an RPC.
That's for when we're on the server.
But then we also see F scope prediction window that says to be called and the call site where the predictive
code will take place.
This generates a new prediction key and acts as a synchronization point between client and server for
that key.
And again, we'll talk about this more in detail later, but we see that this is how we can predict
things.
Okay, So we're going to stop here and we'll flesh out more of the code in this class in the lectures
to come.
But for now, we have completed our send mouse cursor data function.
All that's left is to receive that data on the server and do something with it.
Great job and I'll see you in the next video.