‫Hey.
‫Welcome back.
‫Now we've set ourselves up with a callback function bound to the delegate on take any damage.
‫And the last step is to actually generate that damage event.
‫And we want to do this when our projectile hits something.
‫Once we broadcast for this delegate, we can apply damage to the thing that we hit.
‫And we're going to broadcast this event using applied damage, which belongs to the gameplay statics
‫class.
‫So let's take a look at the applied damage function.
‫Now here's the documentation for applied damage it says hurts the specified actor with generic damage.
‫So this is a generic function for applying damage.
‫And what we do in response to broadcasting for this delegate is up to us.
‫Now here we see we need to include gameplay statics and in the syntax we see several input parameters.
‫Now we actually get some description of the parameters.
‫If we keep scrolling down, we see that damaged actor is well, the actor that will be damaged base
‫damage is the base damage to apply really descriptive documentation here.
‫Thanks.
‫Epic event instigator is the controller that was responsible for causing this damage.
‫And it says, for instance, the player who shot the weapon.
‫When it says player, it's referring to that controller.
‫Then we have the damage causer, which is the actor that actually caused the damage.
‫It says the grenade that exploded.
‫In our case, it'll be the projectile that exploded.
‫And finally, we have damage type class, which is a class that describes the damage that was done.
‫Now back up in the syntax section, we can see the types of these inputs and we see that damage type
‫class is a subclass of and we've seen before that TW subclass of will satisfy an input parameter of
‫type U class.
‫Well when we call apply damage, we can pass in a U class representing the damage type we'd like to
‫use.
‫So we'll talk about how we're going to satisfy this input parameter in just a moment.
‫So the hue gameplay statics function, applied damage is going to take a few input parameters.
‫So let's strategize on how we're going to pass in the appropriate values when we call this function,
‫we saw that first we need the damaged actor.
‫Well, let's go back into projectile CP where we'd like to call apply damage.
‫We'd like to do it here in on hit and we no longer need these logs.
‫So I'm simply going to remove them and notice that our on hit callback gets some inputs passed in once
‫it gets called.
‫When the on component hit delegate is broadcast, we'll see that we have other actor.
‫So we have access to the actor that got hit by the projectile and this is the actor we would like to
‫damage.
‫So that takes care of the first input parameter.
‫It's going to be that other actor.
‫Next, we need the damage amount, which means our projectile should have a damage variable so that
‫we know how much damage to apply.
‫So why don't we go into projectile FX and add a damage variable and this can be a float.
‫So we can simply call this damage and we can initialize it to a value, let's say something like 50
‫F and since this is something we'd probably want to experiment with, we can give this a U property
‫to expose it and make it edit anywhere.
‫So now we have a damage amount to pass in when we call take damage.
‫Now the next parameter is the instigator and we saw that this is of type A controller.
‫So how are we going to get the controller?
‫Well, we've seen that we can get the owner of a particular component with the get owner function.
‫And this returns the actor that owns a particular component, these projectiles are being spawned dynamically.
‫So we need to make sure if we're going to be calling get owner that the owner is set now we're spawning
‫these from base pawn.
‫So if we go into base pawn.
‫CP Here's the line where we're spawning the actor, but Spawn Actor also returns a pointer to the actor
‫that was spawned so we could store this in a local variable.
‫For example, we could say auto projectile and assign the value returned from spawn actor.
‫Now if you're not familiar with auto, it allows the compiler to figure out the type to assign to this
‫new variable.
‫If you hover over it, you'll see that it has the type A projectile pointer because that is what we're
‫signing from the spawn actor function.
‫So this is the same as if we had put a projectile pointer right here and now we can access that newly
‫spawned projectile.
‫And the reason we want to do that is we'd like to set its owner.
‫We would like to make sure that its owner is set to the pawn that spawned it.
‫So we can say projectile.
‫And there's a function for this called set owner.
‫Set owner takes an actor and we're going to pass in this so that whenever one of our pawns spawns a
‫projectile, it will set that projectiles owner.
‫So that way, if we ever call get owner further down the line, we'll get the instance of the class
‫that owns that projectile.
‫So back here in projectile DHCP, we have our get owner function call and we can store this in a local
‫variable.
‫I'm going to go ahead and use auto again and call this my owner and set it to the result returned by
‫get owner.
‫So now we have a local actor pointer that stores the value of the owner.
‫Now we can access the instigator controller from this actor.
‫Now, before we do so, it's a good idea to check to make sure my owner isn't null.
‫So I'm going to say if my owner is null equals equals null pointer, then I'm simply going to return.
‫Now, if you're if body has a single statement like this, you can place it on the same line without
‫the curly braces in case you didn't know.
‫And null pointer is a keyword in C++ that allows you to check to see if a pointer is a null pointer.
‫So if my owner is null, then we will return out of the function early and not do anything else.
‫Now, as I was saying, we can get the instigator controller from my owner and that's what the use of
‫the function called get instigator controller.
‫And if we hover over this, we'll see that it returns an A controller pointer.
‫I'm simply going to use auto and store this in a local variable that I'll call my owner instigator.
‫So now we know what to pass in as the instigator.
‫The next input is the damage causer and this is the actor doing the damage for the projectile.
‫This is going to simply be this.
‫And that leaves the last input parameter, which is a damage type.
‫And we saw that it's a subclass of which means we need the proper use class to pass.
‫N Now here's the unreal engine documentation for you damage type.
‫It says a damage type is intended to define and describe a particular form of damage and to provide
‫an avenue for customizing responses to damage from various sources.
‫Now, we're not going to customize our damage.
‫We just need to satisfy the input parameter, which means we need a U class value that represents this
‫you damage type class.
‫Now in C++, if we want to get the YOU class of any particular class such as you damage type, we can
‫call a function called static class.
‫This is inherited from the you object class.
‫Now of course we're using you damage type here so we'll need that header.
‫So from the documentation I will copy the include line and I'll paste it up here at the top of projectile
‫CP And now you'll see that this static class function returns a U class pointer and that new class will
‫represent the new damage type C++ class.
‫Now, since we're not creating a blueprint based on you damage type and setting some extra data, we
‫don't really need a subclass of variable.
‫So in this case we can use static class and this will return a U class that represents this type.
‫And we can store this in a variable if we like, and I'll call this damage type class.
‫And this is what we can pass in as the final parameter to apply damage.
‫So we now have all of the information we need to pass into the apply damage function.
‫But before we do so, I'd like to place a couple of checks to make sure it's appropriate that we call
‫this function.
‫So I'll make an if statement here.
‫First, I want to make sure that other actor is not null.
‫So I'm going to place other actor here.
‫I'm going to place an and here so I can check to make sure other actor is not equal to this actor.
‫We don't want to cause damage to ourselves if we are the projectile now I'm going to place another end
‫and make sure that other actor is not equal to my owner.
‫It wouldn't be good if the projectile is causing damage to its owner.
‫And now if we get inside this if statement, then we know that it's appropriate to call apply damage
‫so we can do so.
‫And that's going to be your challenge.
‫So in our new if statement in the on hit function call the you game play statics apply damage function.
‫This means you'll need to include the correct header for gameplay statics and you know which input parameters
‫to pass in.
‫So pause the video and add the function call to apply damage in the on hit function now.
‫Okay.
‫So I'm here in projectile CP and I'm going to include the header file for gameplay statics and we can
‫see from the Applied Damage Documentation page that the include is kismet slash gameplay statics.
‫So I'm going to paste that in there and now I'm ready to call apply damage.
‫So I'm going to call you gameplay statics apply damage.
‫Now as soon as I type that opening parentheses, I get the pop up reminding me of the input parameters
‫I need.
‫And the first one is the damaged actor and that's going to be other actor.
‫So we're going to type other actor next.
‫We need the damage amount and we added this damage float in projectile FX, which we set to 50.
‫So I'm going to pass damage end next.
‫We need the instigator and we have my owner instigator.
‫So I'm going to pass in my owner instigator.
‫Next is the damage causer.
‫And of course, the projectile itself is the damage causer.
‫So we're going to pass in this.
‫And finally we need the subclass of for you damage type which we know a U class pointer will satisfy
‫that and that's why we have our damage type class.
‫So let's pass in damage type class.
‫And with that we're now calling apply damage.
‫So when we call this, we will generate the damage event and the on take any damage delegate will broadcast
‫in response to this, which means in our health component damage taken will be called.
‫So we just need to do something here in damage taken.
‫Well, it would make sense to take this damage and subtract that amount from the health.
‫Before we do that, though, I'd like to make sure that damage is not less than or equal to zero.
‫F It makes sense to make these checks before documenting damage, just to make sure that we don't apply
‫a value that doesn't make any sense, like zero or a negative value.
‫So if that's the case, we'll simply return.
‫And of course, if you'd like to be slick and do what I did in projectile at CP, we can place the return
‫right there.
‫Now, if we make it past this line, damage is a positive value so we can take health and use minus
‫equals damage.
‫And just to make sure that this is working, why don't we place a euy log here?
‫So Yui log log, temp warning text and we can simply print the value of health with percent F and health
‫and with that we can compile.
‫Now with a successful compile, we'll hop back into the editor and with our output log open, let's
‫hit play.
‫Now let's see if we can get hit by a projectile.
‫And there we go.
‫Our health is now down to 50 and if we get hit again, we got quite a few hit events because we were
‫hitting up against the projectile many times very quickly.
‫But we see that our health is documenting properly.
‫So we do need to make sure we implement the correct behavior upon death when health reaches zero.
‫But we also need to make sure that we don't get this hit event spammed multiple times.
‫Now we know that the projectile should be destroyed upon hitting something, so the best way to prevent
‫spamming the hit event is to destroy the projectile.
‫So that's the last thing we'll do in this video.
‫So back in projectile just after applied damage, what we can do is have the projectile destroy itself
‫and that couldn't be easier.
‫We simply call the destroy function.
‫So with one more compile back here in the editor, we can go ahead and get hit by a projectile and look
‫at that.
‫The projectile is gone.
‫So it does its damage and then it disappears.
‫And of course we can test out hitting the towers as well by blasting them with projectiles and making
‫sure that those hit events are triggering.
‫And as you can see, I can spam this with a whole bunch of projectiles and we'll see that the health
‫value for this poor tower here is getting very, very negative.
‫So in summary, we called the apply damage function and this resulted in a broadcast for the on take
‫any damage delegate.
‫We documented the health in the health component and we destroyed the projectile.
‫So we've now taken care of damage.
‫We have not yet taken care of death.
‫So that will be one of the next things we'll cover in a future video.
‫I'll see you soon.