Welcome back.
So now that we know that our ability system component has some inherited delegates, let's see what
happens when we bind to one of these and apply a gameplay effect.
Now I'm interested in on gameplay effect applied delegate to self.
This seems like a pretty nice one and we need to know what the function signature should be for a callback
that can be bound to this.
So I'm just going to right click on its type, go to declaration or usages and here it is delegate for
when an effect is applied and we see that it takes an ability system component pointer, a gameplay
effect spec and an active gameplay effect handle.
So in other words, when the ability system component broadcasts this delegate, it's going to pass
this information in and we'll be able to receive that, which is actually pretty nice.
Now if you've seen a declare multicast delegate signature, you might have seen sometimes that these
macros have the parameter names, but in declare multicast delegate, you can just have the types Without
the names there, that's totally fine and that's why we have this here.
So we know that our callback needs to have these three input parameters.
It needs this signature.
So let's make a callback for our ability system component that we can bind to the delegate.
So I think what I'm going to do is right click on ability system components and close the other tabs
for now and open my public folder ability system and get my aura ability system component H And look
at that.
So far it's clean.
So we're going to add our first function to it and I'd like to make this function protected.
So I'll make a protected section and the function is going to be void and it's going to be, let's just
call it effect applied.
And we know that it needs to have this signature.
If we go back to ability system component, it needs to have these three inputs.
So I'm going to copy them and I'll paste them here.
Now funny thing is, those parameter names are actually optional here too, so bet you didn't know that.
But I prefer to give them names here so they're descriptive.
So I'm at least going to give them a name.
I'll call it ability system component for that one.
For the gameplay effect spec we'll call it effect spec for the active gameplay effect handle, we'll
call this active effect handle and we can generate a definition.
So now we have a callback, but we want to bind this to that delegate back in ability system component.
We want to bind it to this one.
The delegate of this type.
I'm going to copy it, control F to find it and here it is on gameplay effect Applied Delegate to self.
I want to bind to this.
Where can I bind to it?
Well, we typically like to do this when the actual game starts and not really in constructors as those
are fired off quite early.
So it'd be nice if we had some sort of spot to bind to this delegate early on and really a pretty easy
way would be to make a function that we can call as soon as something happens like we've initialized
our ability actor info, for example.
That's pretty early on.
So we could call some function to let the ability system know, okay, it's time to go ahead and bind
to your delegates.
And we know that we have a function here in Aura character.
We call it an ability actor info.
We're calling that an aura character when we want to call init the ability actor info on the ability
system itself.
Well, we could make this a virtual function on aura character base and just implement it in both aura
character and aura enemy.
And then whenever they call it, they can also call some function on the ability system to let it know
it's time to bind to any delegates it wants to bind to.
So I'm going to take this function init ability actor info.
I'm going to declare it in aura character base and make it virtual and it can be protected.
So I'm going to make a virtual void init ability actor info and I can just give it a empty definition
here.
But then in Aura character, we're now going to be overriding it.
So it's a virtual override and.
In aura an innate ability Actor Info.
I'm going to open the CPP file.
We can call some function on the ability system component here.
Tell it to go ahead and start binding its delegates.
So we'll get to that in a second.
I'll keep that open, but I also want to override this in Aura enemy so Aura Enemy can do it as well.
So in the protected section I'm going to say virtual void init ability actor info override and I'll
generate the definition here.
I don't care about the super call.
So now Aura enemy and aura character can implement this each in their own ways.
Now Aura enemy is just calling init ability actor info and it's beginplay right here.
So now instead of calling it on the ability system component directly, I'm going to cut that line and
put it right here in init ability actor info and then just call this function here in beginplay instead.
But now we can do other things like call some function on the ability system component which we still
haven't made.
So why don't we make one?
So aura ability system component here can get a public function.
So let's give it a public section and it'll be a void function.
And let's just say ability actor info set.
So when this function is called, we know that the ability actor info has been set, so let's create
a definition for it.
And there we can call this when we set the ability actor info.
So we'll do that in aura character in init ability actor info as soon as we call init ability actor
info which is right here.
Now we're getting the ability system component from aura player state, but we are going to need to
cast it now.
So we're going to say cast to you aura ability, system component.
And by the way, writer is going to give me the aura ability system component header file now and we'll
cast the aura player state get ability system component that's going to give us the ability system component
we're casting now and we know that Aura character should have an aura ability system component.
So we're going to take the result of this cast and call ability actor info set.
Since we've set that cool, now we can do this on the enemy as well.
So we have the ability system components we're going to cast to you aura, ability, system component,
we're casting ability system component and then we're going to call ability actor info set.
Now keep in mind that means the character is now dependent on the ability system component.
And so we'll make sure that our ability system component doesn't have to know about the character.
We'll keep the dependency one way in that sense.
Okay, so now our aura enemy and aura character, as soon as they set their ability actor info, they'll
call ability actor info set, which means the ability system component can now do things like bind to
delegates.
And that's what I'd like to do.
So I'm going to go ahead and close Aura character.
I'm done with it.
I'm closing Aura Enemy or a character base and we're going to go into aura ability system component
and we're going to bind our delegate.
So let's recall what that delegate is called.
It's this one on gameplay effect Applied delegate to Self.
Let's go ahead and paste that into our ability actor info set and we're going to hit the dot and we're
going to bind to this delegate.
Now, what kind of delegate is it?
We can go ahead and go to its declaration.
It's a multicast delegate three params.
It's not dynamic, so we can't use Add dynamic.
We have to use add you object or any of the others.
Right?
But we're going to add you object, which means we're going to pass in this for the user object and
for the function we'll pass in this function here.
Don't forget the address of operator and don't forget to make sure it's fully qualified with the class
name.
Now we're binding this right, which means we have effect applied a callback that will be called in
response to really any effect that gets applied to this ability system component.
So why don't we just test this out by, say, printing a debug message.
So we'll say G engine add on screen debug message, which takes a key we'll use one time.
To display, let's say, eight point F, so eight seconds F color.
Let's make it blue for the string.
We'll make an F string that says effect applied and the rest of the inputs are optional.
So that's all I want to do.
And now I really, really want to test this out.
So I'm going to run, but I'm going to run in debug mode.
That way we could place a breakpoint there and see what the values are for all these input parameters
passed in.
But first let's get that debug message printed to the screen.
Okay, so we're going to hit play and we're going to pick up a health crystal and there's our effect
applied and we can pick up multiple.
Now I probably should have not used key one because now all messages will replace older messages, but
that's okay.
Let's pick up a instant effect or rather a pickup that applies an instant effect.
We see that we still get effect applied.
Excellent.
Now we're not really formatting a string that has any sort of information in it about the effect.
I'm not going to bother with that.
I'm going to instead place a breakpoint here and that way we can inspect these variables to our heart's
content.
So now I'm going to press play and let's pick up a health crystal.
And we hit that break point.
Now, here at the break point.
Let's let Ryder collect some data.
And here we have our data.
So our callback has the ability system component, and that's owned by BP or a player state.
That's great.
We also have the effect spec which is down here.
We can expand the dropdown and the effect spec has all kinds of information.
We know that it's GE crystal heal, we know basically anything we want to know about it, right?
We have all that information and of course active effect handle.
This is the active effect handle we have that if we want it for whatever reason.
Right?
Remember, we used this before to remove an effect in the past with our health crystal.
So this is really, really nice.
We have the ability to get information at runtime about an effect being applied.
So this is super useful for us and we'll be taking advantage of it in this course.
So great job and I'll see you in the next video.