Welcome back.
Now, in the last video, we added a play montage and weight ability task where we're playing an attack
montage for the Spear Goblin.
Now in the Spear goblin attack montage, we added motion warping.
We added a motion warping notify State.
Now, of course, this is only going to work if this attack spear animation is using root motion.
So we can just make sure that that attack spear animation is using that.
If I search for attack spear and go to it and scroll down, we'll see that enable root motion is checked.
That's very important for motion warping to work.
Now the problem though, is that we want to rotate to face something and that something is going to
be a combat target as the enemy comes at us.
The combat target should be aura, right?
So the enemy needs to know what it's trying to attack.
Otherwise, motion warping is not going to know where to rotate the enemy so that it faces the combat
target.
So it needs a variable for a combat target, as sometimes we'll see that the enemy doesn't exactly face
the right direction every single time, like right there.
So we're going to add a combat target variable to the enemy.
I'm going to close out of the editor and open my enemy.
So I'm going to close all tabs here and open Aura Enemy.
And we're going to add a public variable called Combat Target.
And that way we can access it from within things like our abilities and such.
This will be a T object pointer and it's going to be just an a actor pointer and we're going to call
this combat target.
I want it to be blueprint read, right?
So I'm going to give it a new property with Blueprint, read, write, and I'm going to give it the
category.
Of combat like the others.
And combat target needs to be set.
So we need a way to easily set the combat target and a way to easily get the combat target.
And I don't want too many classes dependent on ora enemy.
I don't want them to be dependent on any concrete class, but I'd rather be dependent on an abstraction
such as our interface.
So what I'd like is to go into my enemy interface and add some functions that allow us to set and get
the combat target.
And I'd like these to be blueprint callable functions.
Now I want to implement functionality in Blueprint for these, but I also want to be able to call them
from Blueprint.
Essentially, I want the best of both worlds.
Now, when it comes to interfaces, the way to achieve both of those is to make a blueprint Native event.
So I'm going to make a getter and setter for combat Target, and it'll be a Blueprint Native event and
we'll override the implementation version of Blueprint Native Event in our enemy class.
So we're going to make a void function blueprint.
Native events are not marked virtual.
They auto generate an implementation version that's virtual that we can override.
And we're going to call this first one set combat target.
This will take an a actor pointer called in Combat Target and this will be a new function.
I'd like it to be Blueprint, callable and Blueprint Native event.
Now I also want a getter that returns an A actor pointer.
So a actor pointer.
It's going to be called get combat Target.
We'll make it const and we'll give it a new function and make it blueprint, callable and blueprint
native event.
So now we have these two functions and we can override the version that blueprint Native event generates
automatically for us.
That's the implementation version.
That one is virtual.
We're going to override that in our enemy right here in the combat interface section, we're going to
say virtual void set combat target implementation writer is smart enough to see that.
Now we also have virtual a actor get combat target implementation.
I'm going to override both of these.
Highlight them both.
Click the hammer and generate the function definitions.
And these are going to be simple.
The setter is going to set our combat target.
So we're going to say combat target equals in combat target.
And the getter is also going to be simple.
It's going to return combat target.
Now that we have this blueprint, callable blueprint, native event for each of these, we can call
these from Blueprint.
We could also add our own additional functionality in Blueprint by implementing the Blueprint Native
event if we wanted to do that.
So Blueprint Native events are quite versatile.
So now all we need to do is launch the engine and go in and set that combat target when we need to.
So I'm going to run in debug mode.
All right.
So back in the editor.
I've opened up my classes that I had open and we're already handling the warp target on our motion warping
component.
All we really need to do is call update facing target, which is why we need that combat target.
And I'd like to access that combat target here from melee attack.
But before we access it, we need to make sure that it's set in the first place.
Now, what are we going to use to set that combat target?
Well, I'd like to go to my AI folder and go to my tasks and go to Beat Attack.
Now, if we're going to try to activate an ability to attack, this would probably be a good place to
set that combat target so that once that attack is activated, we can access that combat target from
within that ability.
Now we can access blackboard keys from within behaviour tree tasks.
We have to create a blackboard key selector, right?
So if I add a variable here and call this combat target selector and I change this from bool to blackboard
key selector.
And check the icon, make sure that it's open.
Then we can associate this with one of our blackboard keys by going into our behavior tree.
So I behavior tree open our behavior tree and in our attack task we can select that.
And now we have a combat target selector and we can associate this with our target to follow.
So I'm going to do that both in my attack here and in my attack here.
I'm going to set this to target to follow.
And while I'm at it, this one here is for the ranged attack.
I'm going to change the node name to just ranged attack and I'm going to take this attack and change
the node name to melee attack.
That way we know which one is which, even though they're both executing the same exact behavior tree
task anyway.
Now our behavior tree task has a combat target selector, and if that key has a valid actor set, then
we can set the combat target in BT attack.
What we can do is we can take our combat target selector and drag off of it and get blackboard value
as actor.
And if we have a valid actor here, well, we can set the combat target on the controlled pawn.
Let's make some room here.
I'm going to drag these out.
We want to do all this before activating the ability.
So I'll even add a reroute node here, Give myself some room.
And after getting the blackboard value as actor, I'm going to check is valid for that blackboard value.
And if it is valid, if we have a valid combat target, we can try activate abilities.
So I'll hook that up there.
But if it's not valid, what's the point of trying to activate an ability?
We should just finish execute without activating an ability so is not valid.
Can go down here.
I'm going to add a reroute node.
And drag it over here.
Add another reroute node and hook it up to finish.
Execute.
I'll select them both and hit.
Q So they're level.
Okay.
So after this, we know we have a valid blackboard value on our combat target selector.
We can then access our controlled pawn and call its interface function to set the combat target.
And I'm going to execute set combat target if I search for it, even if I don't drag off of the controlled
pawn, we have our set combat target.
It says this does nothing if the target does not implement the required interface.
So we have this function in C plus plus we actually have a static execute function.
And what we do is we pass in the thing that we know implements the interface that's going to be our
controlled pawn here.
And then we pass in any input parameters such as the combat target we're going to pass in this value
that we got from the combat target selector.
Now from there, we've set the combat target and then we can activate the ability.
So that's what we're going to do.
So this is a little bit messy with the wires.
So what I'm going to do is double click on the wire here and hook that up right there.
So that way we don't have too many wires there.
And I'm going to take this node and bring it down here.
Just give ourselves a little bit less overlap between these nodes here.
And I'll go ahead and take this extra wire and just bring it up here.
So just trying to make this as neat as I possibly can, it's just one of the weaknesses of blueprint
is that you can have this kind of thing with your wires.
And again, there are some plugins that help you such as electronic nodes and dark nodes.
Now this task is setting the combat target.
That's great because now we have a combat target that we can access from within our melee attack.
So what we can do here is we can get the Avatar actor from the get avatar actor from the actor info,
and we can take this avatar actor and we can call our interface function, get combat target.
Now, get combat target here requires an object reference.
And it returns a combat target.
So as soon as we activate the ability, we now have a combat target.
It should be set to aura and we can use that to update the warp target.
Now, just to make sure it's working, I'm going to take that return value.
I'm going to call get object name and I'm going to print a string.
I just want to see by the time we get to this point, if that combat target is set.
So I'm not even playing the montage.
I'm just going to print the string.
So saving all.
I'm going to press play and I'm going to see if this spear goblin has its combat target set and its
BP or a character.
So I know that it's correct.
So I'm going to remove that print string.
And now that we have the combat target, we can update that warp target for our enemy.
Now, that means we're going to want to call an interface function that's not a blueprint native event.
So we don't have a fancy static function to call for it.
But what we can do is we can get our avatar actor from actor info and we can cast to our combat interface.
Remember, we can cast to the combat interface because we made this a blueprint type.
And if we cast to the combat interface, then we can call that function on it for updating the facing
target.
If I type facing target, here's update facing target and we can get that combat target and get the
actor location from it.
So we'll pass that in, update the facing target and then play the montage.
So then we should see our enemies motion warping towards aura every time.
So now what we can do.
Is we can save all and we can play and we can test this out and make sure the enemy turns and faces
aura every single time.
So it's a little hard to test to see if it's working or not, but we can make sure that it's working
by going into the attack animation montage and extending this motion warping window so that it's longer.
We should see the warping happen slower.
So it's not going to look right, but at least it'll tell us that it's being set.
That warp target is being set.
So there we go.
We see that it's attacking and slowly warping towards that warp target as soon as it was set.
See how it slowly rotates towards aura.
So we know that it's working.
So I'm going to go ahead and put this back to just before that thrust because we want to be facing the
correct direction by this point.
So right about there and we know that the enemy is going to face the correct direction, at least where
Aura was at the time of updating that warp target.
And she has some a little bit of time to run away during that attack animation.
So that's perfectly fine.
Now, if you really wanted the enemy's combat target to be updated continuously, there are ways to
make that happen.
For instance, we could run a timer or a timeline that updates the warp target every single frame while
that timeline is running.
So if Aura is running around, the enemy would follow aura rotation wise.
So, you know, there are ways to make this even more reactive.
If you feel so inclined.
Take it upon yourself to update the warp target during the attack.
Every frame if you'd like to do that.
But for this I think we're fine.
We have basic enemy attack montages playing.
It looks good.
We're not causing any damage or anything, so that's the next thing to do.
But this is a great start.
So excellent job and I'll see you in the next video.