WEBVTT

00:06.940 --> 00:07.940
Welcome back.

00:07.960 --> 00:14.890
Now, in the last video, we added a play montage and weight ability task where we're playing an attack

00:14.890 --> 00:16.900
montage for the Spear Goblin.

00:16.930 --> 00:22.120
Now in the Spear goblin attack montage, we added motion warping.

00:22.120 --> 00:25.510
We added a motion warping notify State.

00:25.540 --> 00:32.650
Now, of course, this is only going to work if this attack spear animation is using root motion.

00:32.650 --> 00:37.810
So we can just make sure that that attack spear animation is using that.

00:37.930 --> 00:45.550
If I search for attack spear and go to it and scroll down, we'll see that enable root motion is checked.

00:45.580 --> 00:48.460
That's very important for motion warping to work.

00:48.640 --> 00:55.720
Now the problem though, is that we want to rotate to face something and that something is going to

00:55.720 --> 00:59.020
be a combat target as the enemy comes at us.

00:59.050 --> 01:01.480
The combat target should be aura, right?

01:01.480 --> 01:05.260
So the enemy needs to know what it's trying to attack.

01:05.290 --> 01:11.900
Otherwise, motion warping is not going to know where to rotate the enemy so that it faces the combat

01:11.900 --> 01:12.260
target.

01:12.260 --> 01:20.120
So it needs a variable for a combat target, as sometimes we'll see that the enemy doesn't exactly face

01:20.120 --> 01:22.940
the right direction every single time, like right there.

01:22.940 --> 01:26.370
So we're going to add a combat target variable to the enemy.

01:26.390 --> 01:30.020
I'm going to close out of the editor and open my enemy.

01:30.050 --> 01:33.170
So I'm going to close all tabs here and open Aura Enemy.

01:33.830 --> 01:37.850
And we're going to add a public variable called Combat Target.

01:37.850 --> 01:42.620
And that way we can access it from within things like our abilities and such.

01:42.650 --> 01:49.010
This will be a T object pointer and it's going to be just an a actor pointer and we're going to call

01:49.010 --> 01:50.510
this combat target.

01:51.020 --> 01:53.080
I want it to be blueprint read, right?

01:53.090 --> 01:59.480
So I'm going to give it a new property with Blueprint, read, write, and I'm going to give it the

01:59.480 --> 02:00.530
category.

02:02.370 --> 02:04.500
Of combat like the others.

02:05.710 --> 02:08.760
And combat target needs to be set.

02:08.770 --> 02:15.010
So we need a way to easily set the combat target and a way to easily get the combat target.

02:15.010 --> 02:18.850
And I don't want too many classes dependent on ora enemy.

02:18.850 --> 02:26.320
I don't want them to be dependent on any concrete class, but I'd rather be dependent on an abstraction

02:26.320 --> 02:27.790
such as our interface.

02:27.790 --> 02:35.800
So what I'd like is to go into my enemy interface and add some functions that allow us to set and get

02:35.800 --> 02:37.120
the combat target.

02:37.120 --> 02:39.970
And I'd like these to be blueprint callable functions.

02:41.320 --> 02:47.230
Now I want to implement functionality in Blueprint for these, but I also want to be able to call them

02:47.230 --> 02:48.190
from Blueprint.

02:48.250 --> 02:50.440
Essentially, I want the best of both worlds.

02:50.470 --> 02:56.350
Now, when it comes to interfaces, the way to achieve both of those is to make a blueprint Native event.

02:56.380 --> 03:03.970
So I'm going to make a getter and setter for combat Target, and it'll be a Blueprint Native event and

03:03.970 --> 03:09.940
we'll override the implementation version of Blueprint Native Event in our enemy class.

03:09.970 --> 03:12.340
So we're going to make a void function blueprint.

03:12.370 --> 03:15.160
Native events are not marked virtual.

03:15.190 --> 03:21.130
They auto generate an implementation version that's virtual that we can override.

03:21.130 --> 03:25.330
And we're going to call this first one set combat target.

03:25.690 --> 03:33.760
This will take an a actor pointer called in Combat Target and this will be a new function.

03:34.360 --> 03:38.800
I'd like it to be Blueprint, callable and Blueprint Native event.

03:39.160 --> 03:43.400
Now I also want a getter that returns an A actor pointer.

03:43.400 --> 03:45.320
So a actor pointer.

03:45.320 --> 03:47.840
It's going to be called get combat Target.

03:49.490 --> 03:57.020
We'll make it const and we'll give it a new function and make it blueprint, callable and blueprint

03:57.050 --> 03:57.920
native event.

03:58.160 --> 04:05.180
So now we have these two functions and we can override the version that blueprint Native event generates

04:05.180 --> 04:06.290
automatically for us.

04:06.290 --> 04:08.360
That's the implementation version.

04:08.360 --> 04:10.210
That one is virtual.

04:10.220 --> 04:16.310
We're going to override that in our enemy right here in the combat interface section, we're going to

04:16.310 --> 04:24.110
say virtual void set combat target implementation writer is smart enough to see that.

04:24.320 --> 04:30.230
Now we also have virtual a actor get combat target implementation.

04:30.230 --> 04:32.120
I'm going to override both of these.

04:32.150 --> 04:33.380
Highlight them both.

04:33.380 --> 04:37.130
Click the hammer and generate the function definitions.

04:37.130 --> 04:39.050
And these are going to be simple.

04:39.050 --> 04:41.600
The setter is going to set our combat target.

04:41.600 --> 04:46.280
So we're going to say combat target equals in combat target.

04:46.700 --> 04:50.150
And the getter is also going to be simple.

04:50.150 --> 04:53.150
It's going to return combat target.

04:53.540 --> 05:00.320
Now that we have this blueprint, callable blueprint, native event for each of these, we can call

05:00.320 --> 05:01.550
these from Blueprint.

05:01.580 --> 05:08.690
We could also add our own additional functionality in Blueprint by implementing the Blueprint Native

05:08.690 --> 05:10.550
event if we wanted to do that.

05:10.550 --> 05:14.210
So Blueprint Native events are quite versatile.

05:14.210 --> 05:22.160
So now all we need to do is launch the engine and go in and set that combat target when we need to.

05:22.190 --> 05:24.170
So I'm going to run in debug mode.

05:25.520 --> 05:25.910
All right.

05:25.910 --> 05:27.290
So back in the editor.

05:27.480 --> 05:35.840
I've opened up my classes that I had open and we're already handling the warp target on our motion warping

05:35.840 --> 05:37.070
component.

05:37.160 --> 05:44.330
All we really need to do is call update facing target, which is why we need that combat target.

05:44.330 --> 05:48.860
And I'd like to access that combat target here from melee attack.

05:48.860 --> 05:53.150
But before we access it, we need to make sure that it's set in the first place.

05:53.180 --> 05:56.930
Now, what are we going to use to set that combat target?

05:56.960 --> 06:03.620
Well, I'd like to go to my AI folder and go to my tasks and go to Beat Attack.

06:03.650 --> 06:10.340
Now, if we're going to try to activate an ability to attack, this would probably be a good place to

06:10.340 --> 06:17.180
set that combat target so that once that attack is activated, we can access that combat target from

06:17.180 --> 06:18.530
within that ability.

06:18.620 --> 06:23.560
Now we can access blackboard keys from within behaviour tree tasks.

06:23.570 --> 06:26.550
We have to create a blackboard key selector, right?

06:26.550 --> 06:36.720
So if I add a variable here and call this combat target selector and I change this from bool to blackboard

06:36.720 --> 06:38.070
key selector.

06:39.420 --> 06:42.750
And check the icon, make sure that it's open.

06:42.780 --> 06:48.810
Then we can associate this with one of our blackboard keys by going into our behavior tree.

06:48.840 --> 06:57.810
So I behavior tree open our behavior tree and in our attack task we can select that.

06:57.810 --> 07:04.510
And now we have a combat target selector and we can associate this with our target to follow.

07:04.530 --> 07:10.620
So I'm going to do that both in my attack here and in my attack here.

07:10.740 --> 07:13.800
I'm going to set this to target to follow.

07:13.800 --> 07:18.480
And while I'm at it, this one here is for the ranged attack.

07:18.480 --> 07:24.570
I'm going to change the node name to just ranged attack and I'm going to take this attack and change

07:24.570 --> 07:27.270
the node name to melee attack.

07:27.930 --> 07:33.510
That way we know which one is which, even though they're both executing the same exact behavior tree

07:33.510 --> 07:34.830
task anyway.

07:34.860 --> 07:42.790
Now our behavior tree task has a combat target selector, and if that key has a valid actor set, then

07:42.790 --> 07:46.030
we can set the combat target in BT attack.

07:46.240 --> 07:54.010
What we can do is we can take our combat target selector and drag off of it and get blackboard value

07:54.130 --> 07:55.420
as actor.

07:56.270 --> 08:02.600
And if we have a valid actor here, well, we can set the combat target on the controlled pawn.

08:02.630 --> 08:03.980
Let's make some room here.

08:03.980 --> 08:05.990
I'm going to drag these out.

08:06.020 --> 08:09.130
We want to do all this before activating the ability.

08:09.140 --> 08:13.160
So I'll even add a reroute node here, Give myself some room.

08:13.400 --> 08:20.930
And after getting the blackboard value as actor, I'm going to check is valid for that blackboard value.

08:22.740 --> 08:28.380
And if it is valid, if we have a valid combat target, we can try activate abilities.

08:28.380 --> 08:30.040
So I'll hook that up there.

08:30.060 --> 08:34.370
But if it's not valid, what's the point of trying to activate an ability?

08:34.380 --> 08:39.090
We should just finish execute without activating an ability so is not valid.

08:39.130 --> 08:40.260
Can go down here.

08:40.260 --> 08:41.940
I'm going to add a reroute node.

08:43.170 --> 08:44.740
And drag it over here.

08:44.760 --> 08:48.300
Add another reroute node and hook it up to finish.

08:48.300 --> 08:49.080
Execute.

08:49.840 --> 08:51.010
I'll select them both and hit.

08:51.010 --> 08:52.480
Q So they're level.

08:52.810 --> 08:53.410
Okay.

08:53.410 --> 09:00.290
So after this, we know we have a valid blackboard value on our combat target selector.

09:00.310 --> 09:06.790
We can then access our controlled pawn and call its interface function to set the combat target.

09:06.790 --> 09:13.750
And I'm going to execute set combat target if I search for it, even if I don't drag off of the controlled

09:13.750 --> 09:17.260
pawn, we have our set combat target.

09:17.290 --> 09:22.030
It says this does nothing if the target does not implement the required interface.

09:22.030 --> 09:27.790
So we have this function in C plus plus we actually have a static execute function.

09:27.790 --> 09:33.670
And what we do is we pass in the thing that we know implements the interface that's going to be our

09:33.670 --> 09:35.080
controlled pawn here.

09:35.230 --> 09:42.250
And then we pass in any input parameters such as the combat target we're going to pass in this value

09:42.250 --> 09:44.710
that we got from the combat target selector.

09:45.100 --> 09:50.420
Now from there, we've set the combat target and then we can activate the ability.

09:50.540 --> 09:52.220
So that's what we're going to do.

09:52.310 --> 09:55.250
So this is a little bit messy with the wires.

09:55.250 --> 10:00.380
So what I'm going to do is double click on the wire here and hook that up right there.

10:01.490 --> 10:04.850
So that way we don't have too many wires there.

10:05.000 --> 10:08.630
And I'm going to take this node and bring it down here.

10:11.010 --> 10:16.680
Just give ourselves a little bit less overlap between these nodes here.

10:16.680 --> 10:21.480
And I'll go ahead and take this extra wire and just bring it up here.

10:21.480 --> 10:29.220
So just trying to make this as neat as I possibly can, it's just one of the weaknesses of blueprint

10:29.220 --> 10:33.150
is that you can have this kind of thing with your wires.

10:33.180 --> 10:38.550
And again, there are some plugins that help you such as electronic nodes and dark nodes.

10:38.640 --> 10:41.910
Now this task is setting the combat target.

10:41.910 --> 10:48.240
That's great because now we have a combat target that we can access from within our melee attack.

10:48.390 --> 10:57.120
So what we can do here is we can get the Avatar actor from the get avatar actor from the actor info,

10:57.120 --> 11:03.090
and we can take this avatar actor and we can call our interface function, get combat target.

11:03.120 --> 11:07.500
Now, get combat target here requires an object reference.

11:09.040 --> 11:11.710
And it returns a combat target.

11:11.710 --> 11:16.250
So as soon as we activate the ability, we now have a combat target.

11:16.270 --> 11:21.670
It should be set to aura and we can use that to update the warp target.

11:21.700 --> 11:26.140
Now, just to make sure it's working, I'm going to take that return value.

11:26.140 --> 11:30.310
I'm going to call get object name and I'm going to print a string.

11:30.790 --> 11:37.300
I just want to see by the time we get to this point, if that combat target is set.

11:37.300 --> 11:39.220
So I'm not even playing the montage.

11:39.250 --> 11:40.900
I'm just going to print the string.

11:41.740 --> 11:42.970
So saving all.

11:42.970 --> 11:49.720
I'm going to press play and I'm going to see if this spear goblin has its combat target set and its

11:49.750 --> 11:51.040
BP or a character.

11:51.040 --> 11:53.020
So I know that it's correct.

11:53.020 --> 11:55.360
So I'm going to remove that print string.

11:55.360 --> 12:01.750
And now that we have the combat target, we can update that warp target for our enemy.

12:01.780 --> 12:07.780
Now, that means we're going to want to call an interface function that's not a blueprint native event.

12:07.780 --> 12:10.450
So we don't have a fancy static function to call for it.

12:10.450 --> 12:19.560
But what we can do is we can get our avatar actor from actor info and we can cast to our combat interface.

12:19.570 --> 12:24.060
Remember, we can cast to the combat interface because we made this a blueprint type.

12:24.070 --> 12:30.910
And if we cast to the combat interface, then we can call that function on it for updating the facing

12:30.940 --> 12:31.450
target.

12:31.450 --> 12:38.590
If I type facing target, here's update facing target and we can get that combat target and get the

12:38.590 --> 12:40.180
actor location from it.

12:41.490 --> 12:46.440
So we'll pass that in, update the facing target and then play the montage.

12:46.440 --> 12:53.150
So then we should see our enemies motion warping towards aura every time.

12:53.160 --> 12:55.410
So now what we can do.

12:56.700 --> 13:02.760
Is we can save all and we can play and we can test this out and make sure the enemy turns and faces

13:02.790 --> 13:04.560
aura every single time.

13:04.770 --> 13:11.550
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

13:11.550 --> 13:21.840
by going into the attack animation montage and extending this motion warping window so that it's longer.

13:21.840 --> 13:24.660
We should see the warping happen slower.

13:24.660 --> 13:29.070
So it's not going to look right, but at least it'll tell us that it's being set.

13:29.070 --> 13:31.020
That warp target is being set.

13:31.020 --> 13:31.770
So there we go.

13:31.770 --> 13:39.900
We see that it's attacking and slowly warping towards that warp target as soon as it was set.

13:43.520 --> 13:47.110
See how it slowly rotates towards aura.

13:47.120 --> 13:48.830
So we know that it's working.

13:48.830 --> 13:55.850
So I'm going to go ahead and put this back to just before that thrust because we want to be facing the

13:55.850 --> 13:57.950
correct direction by this point.

13:57.950 --> 14:06.890
So right about there and we know that the enemy is going to face the correct direction, at least where

14:06.920 --> 14:11.600
Aura was at the time of updating that warp target.

14:11.600 --> 14:17.750
And she has some a little bit of time to run away during that attack animation.

14:17.750 --> 14:20.000
So that's perfectly fine.

14:20.330 --> 14:27.320
Now, if you really wanted the enemy's combat target to be updated continuously, there are ways to

14:27.320 --> 14:28.460
make that happen.

14:28.460 --> 14:36.980
For instance, we could run a timer or a timeline that updates the warp target every single frame while

14:36.980 --> 14:38.570
that timeline is running.

14:38.570 --> 14:44.700
So if Aura is running around, the enemy would follow aura rotation wise.

14:44.700 --> 14:50.160
So, you know, there are ways to make this even more reactive.

14:50.190 --> 14:52.140
If you feel so inclined.

14:52.170 --> 14:57.660
Take it upon yourself to update the warp target during the attack.

14:57.660 --> 14:59.490
Every frame if you'd like to do that.

14:59.490 --> 15:01.410
But for this I think we're fine.

15:01.410 --> 15:05.070
We have basic enemy attack montages playing.

15:05.070 --> 15:06.210
It looks good.

15:06.240 --> 15:10.530
We're not causing any damage or anything, so that's the next thing to do.

15:10.620 --> 15:12.450
But this is a great start.

15:12.450 --> 15:16.500
So excellent job and I'll see you in the next video.
