Full transcript
Outcome of This Part
0:05Welcome back everyone to part 18 of our
0:08smart enemy AI series. And in this part
0:10we're going to focus on a very important
0:12change, and that's creating a new attack
0:15system. And what I mean by that is we're
0:17going to take all of our existing
0:19attacks and move them into a shared
0:22place so that any of the attacks that we
0:23have, the mage, melee, range attacks,
0:26can be used by any enemy type. And this
0:28is especially important for the boss
0:30fight cuz we want the boss to be able to
0:32use any of the attacks that we've
0:33already have, the barrage attack, the
0:35magic spell, the jump attack, and so on.
0:39Uh now I'm first going to demonstrate
0:40this by adding a new attack type and I'm
0:42going to share it between both the mage
0:44and melee enemies. And the only
0:46difference will be the montage itself.
0:48So that when we start to build the boss
0:50fight, we just have to have a list of
0:52animations, but the attack functionality
0:54itself uh is already there because we've
0:56already implemented it for previous
0:58enemies.
0:59And now this is very important for
1:00anyone building a combat system. So make
1:02sure to stick around till the end, watch
1:05all of the uh issues that I will run
1:07into and how I fix them. And uh
1:09hopefully this will put us in a very
1:11good place to start uh implementing the
1:13boss enemy type. So, now let's get
1:16started.
Reviewing The Current Attack System
1:17All right, so the first thing uh I want
1:19to do is create this new ground smash
1:21attack uh that will be shared between
1:24both the melee and the mage enemy.
1:26Uh but before we start creating shared
1:28attacks, let's actually look at the
1:30attacks that we have now.
1:32Uh for the mage enemy for example.
1:35Um well, an attack is basically called
1:37the parent attack, play a montage, do
1:40something on notify, and take damage. Uh
1:44this attack is also the same. Uh and if
1:46you look at the melee enemy,
1:49um pretty much the same structure. So we
1:52keep repeating the structure, play
1:53montage, do something on notify, and uh
1:56do uh damage.
1:58Um so we're going to create a common
2:00attack structure that we're going to
2:02keep repeating in our BPC attacks
2:05component.
2:07Um
2:08So let's uh open this up. If you don't
2:10remember where it is, uh I think it was
2:13in the uh attacks folder and BPC
2:16attacks. And here we only have a fire
2:20bullet and magic spell.
2:22Uh and these, if you recall, this is
2:23what we actually do on uh notify. So in
2:26the mage enemy here, we call magic spell
2:29when uh the montage shoot says fire,
2:32when there's a notify called fire.
Creating The New Attack Structure
2:35Um but now we want to create all of our
2:37attacks. We're going to move them into
2:38this BPC attacks. But I'll first show
2:41you how we create a new attack from
2:43scratch here.
2:45Um before doing that, we want to have a
2:47new struct. So I'm going to go over
2:49here, right click, and search for
2:51structure.
2:53Structure.
2:56And I'm going to call this the um
3:00attack info struct. So S_attack_info.
3:03And this structure is going to contain
3:05all of the information that we need for
3:07an attack. And if you recall here, we
3:09need the attack target, which montage to
3:12play, and how much damage to do or
3:15what's the damage info. So we're going
3:17to add these three things into our
3:19struct.
3:20So opening up our structure here,
3:23um first thing we want to have is the
3:26attack target.
3:28And this is going to be of type
3:31actor
3:33object reference.
3:34Then we want to have the montage to
3:37play, and this is going to be of type
3:41um anim montage, also object reference.
3:44And finally, we want to have the damage
3:47info. And this is going to be of type
3:50S_damage_info.
3:52This is another struct that we created
3:54uh before in our um damage system
3:56tutorial.
3:58So right now we have this single
3:59variable called attack info that
4:01contains these three other variables.
4:03So how do we use it?
4:06So let me go back here to my uh BPC
4:08attacks, and I'm going to move all of
4:10these to the side for now.
New Ground Smash Attack
4:12And I'm going to create a new event.
4:14Okay, I'm going to call it the ground
4:17smash
4:19um
4:19attack or just ground smash, that's
4:21fine.
4:23Um
4:24and I'm going to give it as inputs the
4:27attack info.
4:30And it's of type S_attack_info.
4:35So
4:36the first thing you want to do here is
4:38copy and paste sort of this structure
4:41that we have here.
4:42Um but make sure that we're not making
4:44any assumptions about the type of enemy,
4:47is it a mage, is it a melee enemy, and
4:49so on. So um
4:52the parent attack will be the same, the
4:54montage will use that variable, and so
4:56on.
4:57So let's first get the owner. So since
5:00I'm inside an actor component,
5:03um I can get owner. I don't have a
5:05reference to self. This is uh how to get
5:07that. And we're going to call attack.
5:10And this is going to be the default
5:11attack that we have.
5:14And most importantly is that we're going
5:16to remove this default attack from um
5:19our mage enemy and our melee enemy. So
5:21actually I can delete it now and I can
5:23delete it now.
5:25The reason for doing that is because we
5:27want uh to call the base attack here. So
5:31we want this attack to refer to what we
5:32have in our base enemy. Uh which does uh
5:37let me show you.
5:38So enemies, base.
5:41Our default attack just sets attacking
5:44to true. So this is common for all of
5:46our um enemy types. And this is
5:49basically what we're doing here.
5:52So first we uh do this, uh but we need
5:54the attack target. So pull off this and
5:57say break and pass the attack target
6:00after breaking.
6:01Then we want to play a montage.
6:03So I can go over here and say play
6:06montage and pass in the montage we want
6:09to play.
6:10Great. Now I need a mesh that we're
6:13going to play the montage in. And
6:14remember again, we are inside an actor
6:16component, not inside the uh actual uh
6:19enemy uh pawn. So to get the mesh, I'm
6:22going to get the owner. Well, there are
6:23two ways. I can get the owner and say
6:25get component by class
6:28and search for skeletal mesh.
6:32Then this will give me a skeletal mesh I
6:33can pass. But this assumes that I know
6:36that the owner has a skeletal mesh. In
6:38this case, I know because the owner is
6:39either the
6:41enemy or the player, so I know they have
6:42a skeletal mesh.
6:44Uh but if you don't want to do this,
6:45another way is to just cast
6:48to a character
6:52um because the character also has a mesh
6:54by default and say get the mesh variable
6:57from that character.
6:59Um I'm going to use the cast method
7:01because then I can do something if this
7:03cast fails for any reason. If you put
7:05this BPC attacks on an actor that's not
7:08a character, then this will fail.
7:10Uh for my case it won't, but yeah, I'm
7:12going to keep it as a cast.
7:15Um
7:16and uh next thing we want to do is uh
7:20play the uh switch on this notify,
7:22right? Let me move these a bit more.
7:26So now I'm going to on attack uh sorry,
7:29on notify begin, say switch. Oh sorry,
7:32um on this notify name, say switch.
7:35And unplug this, make sure it's on
7:37notify begin.
7:39Remove the default pin and I'm going to
7:41add a new one called um I don't know,
7:43smash. So this is the ground smash
7:45attack that I showed you in the intro of
7:47the video. And it's going to have a
7:49notify called smash.
7:51Um now what smash does is just do damage
7:54in an area. Right?
7:57Um but right now we don't have this uh
7:59function that does damage in an area
8:00here, but we do have it in our melee
8:03enemy.
8:04So if you recall in the spin attack, we
8:06would just do um an AOE slash,
8:10uh which does damage in an area because
8:13it spawns the AOE damage base uh given a
8:16certain radius, and so on. Right? So I'm
8:19going to copy this function.
8:22And I'm going to move it to the BPC
8:24attacks. And I'm going to move it here
8:26with the fire bullet and the magic spell
8:28because they're all these are what
8:29happen on notify. And I'm going to call
8:31all of these, so I can actually comment
8:33here. I'm going to call all of these the
8:35attack notifies.
8:39So this is what happens in a notify for
8:41each attack.
8:44So let's paste our
8:47AOE slash, but I'm going to rename it to
8:49just
8:50AOE damage instead of slash.
8:53And I'm also going to make this radius a
8:55variable, so just by pulling this pin
8:57here.
8:59And the damage info as well. We're going
9:02to delete that and we're going to make a
9:03damage info also a variable.
9:06Just like this.
9:09Um
9:10All right, so now I can go here and to
9:13my smash, I can just call AOE damage
9:17and pass in my attack target here from
9:21the attack info, pass in the damage from
9:23the damage info, and radius um
9:27Now radius, I'm going to make it a
9:29variable on this ground smash attack.
9:32Why is that? For example, if the melee
9:34enemy is using this and wants to do uh
9:37200 radius smash attack, and it's
9:39configurable, but if the mage enemy
9:41wants a bigger one, then they can do a
9:42300 or 400 radius attack. So that way
9:45you can configure it based on who's
9:46using this function. And that makes it a
9:48bit more scalable.
9:51All right, and um
9:53on interrupt and on complete, just like
9:56we do here, um
9:57on the interrupted and complete, we call
9:59attack end. And we also need to define
10:01whether it's interruptible or not. Let's
10:04do the attack end first cuz that's
10:06easier. We just get our owner and call
10:10attack end. We don't have to cast
10:12because this is a interface function.
10:15And we're going to do this on both
10:16completed and interrupted. And make sure
10:19the attack target is passed here.
10:23Uh
10:24I'm going to clean up this spaghetti
10:26code a bit.
10:33All right, much better.
10:35Um
10:36now for the interrupt. Now the
10:38interrupts, we just set is interruptible
10:40true or false based on the damage system
10:43actor component we have here.
10:45But inside the BPC attacks, we don't
10:47have access to the damage system
10:50actor component.
10:52So what we need to do is actually modify
10:54the way we set this is interruptible or
10:56not.
10:58Um so instead of just setting a
11:00variable, we're going to make this a
11:01function on the damageable interface.
11:04So we're going to go to our content
11:06folder, damage system, and open up the
11:08BPI damageable.
11:10And we have a lot of functions here
11:12related to damage. So get health, max
11:15health, take damage, and so on. I'm just
11:16going to add another one and call it set
11:19is interruptible.
11:23And it just takes a value as a boolean.
11:27And we need to implement this in both
11:29our player and enemy. That's very
11:32simple. So go over to the BP
11:35enemy base.
11:37Open up interfaces and you'll see
11:40uh
11:42Did I compile? I did not compile. Okay,
11:44now that I compiled, I should see set is
11:46interruptible. Great.
11:49We're just going to double click it and
11:52we are going to get our BPC damage
11:55system and we're going to set the is
11:58interruptible variable. Make sure it's
12:00the variable.
12:03And this is the value we're going to
12:04pass.
12:06All right. Now we can do the same for
12:08our player.
12:10Get our interface,
12:13set is interruptible.
12:16And just paste this as well.
12:21Great.
12:23Now all of the attacks that we're using
12:25that we're creating here can be used by
12:26both the player and the enemy. And
12:28that's why it's going to be a much
12:30welcome refactoring.
12:32Um so now that it's an interface
12:34function, I can say for this ground
12:37smash
12:38I'm missing something here.
12:40I need to modify this.
12:43I'll get back to it but let me finish my
12:44sentence first. So for the is
12:47interruptible, I want the attack this
12:50ground smash attack
12:52not to be interrupted for example. So if
12:54you want that, then I can just pull off
12:56the get owner and say set is
12:58interruptible
13:00to false as soon as we play the montage.
13:04And once the montage is over,
13:07set is interruptible
13:09back to true.
13:12And that's pretty much
13:14um how we had it here as well. So for
13:17some attacks,
13:19we set is interruptible to false and as
13:21soon as we're done, we set it to true.
13:22So I'm basically doing the same thing
13:24but just calling the interface function.
13:28Uh back here to fix our errors, we have
13:31some errors here.
13:35Uh we don't have an get actor location.
13:37So we need to first get our owner
13:42and get actor location of that.
13:45And then for this take damage,
13:53we don't have a self here the damage
13:55causer. So damage causer is also our get
13:59owner. The person who owns this actor
14:02component is the one doing the damage.
14:05Great.
14:07And let me also just
14:12move this a bit here. Okay.
14:16Oh and also self, we don't have a self
14:17here. Instigator is get owner.
14:21Oh this is a pawn so
14:25cast to
14:27a pawn or default pawn. I'll just pawn.
14:31And you can right click and say convert
14:33to pure cast since we're sure that this
14:35owner is always a pawn.
14:37Or you can just not pass an instigator.
14:39That's also fine.
14:42All right.
14:45So now we have this
14:47ground smash attack that doesn't make
14:50any assumptions on what montage to play,
14:52what type of mesh it's using, is it a
14:54melee, is it a ranged,
14:56what's the damage, what's the radius.
14:58These are all now configurable.
15:01Um
Using The New Attack System
15:02So it's time to actually show you how we
15:05are going to use these attacks. So let's
15:08go over to our BP enemy mage here.
15:11I'm going to leave these two attacks for
15:13now. We're going to move all the attacks
15:15later on.
15:16But for now, I'm going to just keep
15:20all of this.
15:22And
15:23uh but ba ba
15:29Let's create a new event here for our
15:31mage enemy and call it the ground smash
15:35attack.
15:37Um and just like the other attacks as
15:38well,
15:39this takes an attack target. So this
15:42doesn't change. This is the same
15:45as we've always done.
15:48Uh but the main difference here is that
15:50we're not implementing the attack
15:52function here. What we'll do is just get
15:55our BPC attacks and call ground smash.
16:00Now it's going to expect us to pass some
16:01things. So let's do that.
16:03Um the attack info, we can pull off of
16:07it and say make and it will give you
16:08this make attack info.
16:11Um attack target, we'll pass this one.
16:13The montage, we're going to create in a
16:15second so we're going to leave empty for
16:16now. And the damage info, we can also
16:19pull off of damage info and say make.
16:23And then decide whatever damage you
16:24want. Let's say this does
16:2625 damage and explosion la la la.
16:30And the radius, let's say it's something
16:32like 300.
16:35Great. So this is basically how we call
16:37the attack now.
16:38And I can copy everything here exactly
16:41the same and put it in my melee enemy.
16:49So here in my melee enemy, this should
16:51just be attacks by the way.
16:54Um everything is going to be the same.
16:55The only difference of course is going
16:58to be the montage that we play.
Mage Ground Smash Montage
17:01So let's go ahead and create the montage
17:04first for our mage enemy.
17:07So let's open up our content browser and
17:09in our characters, mage animations,
17:14Let me show you the This is the
17:16animation I'll be using, mage ground
17:18smash. And again, I just got this from
17:20Mixamo. I'll leave the link and the name
17:22for it down in the description. Uh but
17:24we want to create a montage out of this.
17:27So
17:28right click,
17:30create, and create anim montage. And
17:32we're going to call this the montage
17:35um mage ground smash.
17:40Open it up.
17:42And we want to do a few things.
17:44First, let's add a couple of notifies
17:47here. So I'm going to add a new notify
17:48track.
17:50Um and I'm going to add some effects. So
17:54play particle effect here.
17:56Uh this What was it called? Gideon
17:58hands. Yeah.
18:00I'm going to play this in the right
18:02hand.
18:04And I am going to
18:08copy it and paste it here.
18:12And I'm going to play this one in the
18:14left hand.
18:16All right. And it looks like this.
18:19So she just has these hands glowing.
18:23All right. And now we want to
18:26at this point for example or boom as
18:29soon as we hit the ground here,
18:31uh we want two notifies as well. One is
18:34montage notify
18:36and call it smash because this is what
18:38we're listening to in our attack.
18:41Uh which let me remind you here we wait
18:43for a notify called smash.
18:46So here right here is when the damage
18:47occurs. And let's also add a effect.
18:52Um I had one also from the Gideon asset
18:55pack.
18:57Uh impact. Ah yeah. So this one, meteor
18:59impact.
19:00And it looks like this. Boom. Wait, let
19:03the shaders compile first.
19:07And boom. Yeah. So it looks just like
19:11that.
19:12Now let's also add some sounds. So let
19:14me also add a new notify track here. And
19:18the very beginning, I'm going to
19:20add a notify play sound.
19:23And again, I got a free sound online and
19:27this one is called I call it ground
19:30smash cast. Sounds like this.
19:37And on the explosion, I also have
19:40another sound. So
19:42play sound and this one
19:45What was it called? Ground smash
19:47explode.
19:50All right. So putting the whole thing
19:52together now looks like this.
19:59Very nice.
20:00So, now if I go back to my mage enemy,
20:03all I have to do is play this ground
20:05smash montage.
20:08Great.
20:09Now, let's do the uh same for um our
20:14melee enemy.
Melee Ground Smash Montage
20:15All right. So, for our um melee enemy,
20:18go to the animations melee folder
20:21and uh
20:23I have it somewhere here. Yeah, sword
20:25ground smash.
20:27And it looks like this.
20:29Also got from Mixamo and retargeted to
20:31the unreal um mannequin and made a small
20:35change to the hands.
20:36Um but now we want to create a montage
20:40out of it and we're going to modify it a
20:41bit more.
20:43So, ground smash, right click, create
20:46anim montage and call this one
20:50uh montage
20:52um melee
20:54ground smash.
20:58Uh all right. So, I want the um
21:01well, I first want it to start later.
21:04So, right now there's uh he just lifts
21:06his sword up in the air. I don't want
21:08that. So, I'm going to start it at like
21:111.5.
21:14Yeah. So, it starts when the sword is
21:16already in the air, but I want it to
21:18have like a slow-mo time for windup and
21:20then hits fast.
21:22So, from let's say 1.5 till two, let's
21:27play play that very slowly at an 0.5
21:29rate.
21:31And then we're going to add another one
21:34from
21:35two till 2.5 and play that pretty
21:38quickly at a double rate.
21:41And then add it a third time and this is
21:44just going to be from 2.5 till the end
21:46and play that at normal rate.
21:49So, it looks like this.
21:51Boom. So, holds up the sword in the air
21:54for a while and then
21:57very suddenly just slams it down.
22:00Perfect.
22:01So, we want our smash notify also
22:06somewhere
22:07here.
22:09Yeah. So, right click, add notify
22:12montage notify and call it smash.
22:17And let's add a new notify track. Uh we
22:20also want
22:24Yeah, it's all right here. We also want
22:26an effect. So, play uh particle effects
22:29and I have this lightning effect that I
22:32got from the effects variety pack, which
22:34we've been using for a few things
22:35already.
22:38And looks like this, but we want to move
22:40it a bit to the front.
22:43Uh so, let's say move it on the Y axis
22:47like I don't know, 100.
22:51A bit more.
22:52170.
22:58Yeah, that's about That's good.
23:00And uh
23:03do we need anything else? So, boom.
23:07No.
23:09I think that looks good.
23:11Uh I don't have sounds for this one.
23:13Actually, we can play the same uh sound
23:15that we have.
23:17So, add notify track.
23:20Uh let's play the
23:23same ground smash sound, this one.
23:29Yeah, why not?
23:35Yeah, uh looks good.
Testing Our New Attacks
23:37So, in our melee enemy, we just select
23:39this montage again, the melee ground
23:42smash and here we go. We have our
23:44attack. So, now we have one common
23:47attack implementation
23:49shared between the melee enemy
23:52and the mage enemy.
23:55And let's see what it looks like because
23:56we haven't tested anything so far.
23:58Um so, I'm just going to make the basic
24:03attack for the mage um call the ground
24:08smash attack here
24:11instead of doing all these other things.
24:14And pass in the attack target.
24:17So, let's take a look at our mage.
24:27Nice. Oof.
24:29Works beautifully.
24:33And I'm dead. Excellent.
24:36So, now let's look uh see what it looks
24:39Oh, let me actually revert this.
24:42And let's see what it looks like for the
24:44melee enemy. Um so, I'm also going to
24:47have the short-range attack just do the
24:50ground smash attack.
24:53Pass in the attack target.
24:57Uh enemies
25:00melee enemy, let's put him here
25:04and get rid of this one.
25:06All right. So, attack me. Boom. Nice.
25:12Very cool.
Moving All The Melee Attacks to BPC_Attacks
25:13Now, it's time to move all of the other
25:15attacks uh to be the same
25:19uh using the same structure. So, all the
25:21attacks will be in the BPC attacks and
25:23they'll be shared between all of the
25:24enemy types. So, as long as the enemy
25:27has a montage that includes the notify,
25:31then they can do this attack. So, we're
25:33basically creating uh what I like to
25:34call a montage uh driven attack system.
25:38Um let me close some of this.
25:41Uh and yeah, let's close all of this and
25:44let's start with our melee enemy
25:46cuz this is the interesting one.
25:48And also let's not forget to undo
25:52this.
25:54Whoa.
25:56Let's just delete it. Okay.
25:59Um all right. So,
26:01let's start with our short-range attack.
26:04Um
26:05it's going to look very similar to the
26:08other one. So, I'm just going to copy it
26:10and we'll make some changes.
26:13Um so, I'm going to go over here to my
26:15BPC attacks and paste. It's going to
26:19tell me there's a function called sphere
26:20trace damage that doesn't exist. What do
26:22you want to do with it? I'm just going
26:23to say do nothing.
26:24Uh and we're just going to delete this
26:26for now.
26:28All right. And I'm not going to call
26:29this short-range attack. I'm going to
26:31make it more specific. So, I'm going to
26:32call it primary melee attack.
26:37Um you can call it anything. Um for me,
26:39I mean, I just primary melee attack.
26:42And uh we're going to follow the same
26:44rules that we used here. So,
26:48um we don't have an attack target.
26:53Instead, we have
26:56an attack info struct
27:00of type attack info.
27:03And this is where we get our target
27:06from.
27:10All right.
27:11Um and the montage we're going to get
27:13from here.
27:14The mesh uh we don't have a mesh. So, we
27:17need to get it like we did above here
27:19also. Get the owner, call attack and
27:21cast.
27:24And
27:26it's going to replace this attack call.
27:28This is going to be attack target and
27:31character get the mesh.
27:35Just like that.
27:38Let me move this a bit down here so it's
27:40not in the way.
27:44And instead of set interruptible on the
27:46BPC damage system, we just get owner and
27:49call set is
27:52interruptible as an interface function.
27:56So, here interruptible is false.
28:01And
28:04once we're done,
28:06we call
28:08Oh, sorry. Yeah. Here after the attack
28:10ends,
28:12we call interruptible to true. Make sure
28:15this is off of the get owner.
28:20All right.
28:22Um now the slash. So, over here, slash
28:26does the sphere trace damage. So, I'm
28:28going to copy this sphere trace damage
28:30function
28:32and I'm going to move it here to my
28:35attack notifies.
28:38So, just paste it here.
28:42And um a few things we're going to have
28:45to change. Uh this one damage all
28:47non-team members off the BPC attacks.
28:49This is already already in BPC attacks.
28:51I can remove it and this is just going
28:52to be off of self.
28:55Uh we don't have an self actor location.
28:58So, this has to be get owner
29:02and actor location.
29:04Uh and a few other things. This damage
29:06info, I'm going to make it into a
29:08variable. So, delete that and take this
29:10pin, drag it here. So, now it's a
29:12parameter.
29:13And the radius as well, also a
29:15parameter.
29:16Uh sorry, this not radius, this radius.
29:20And this one we're going to call it uh
29:22length. So, the length of the sphere
29:24trace. So, again, this sphere trace
29:27damage can be used by any uh enemy type
29:30and they define what's how much damage,
29:32what's the radius, what's the length and
29:33so on.
29:35Uh and this get actor forward vector is
29:39also
29:41uh get owner. Whoops.
29:46And get actor forward vector.
29:51And there's something still wrong. Oh,
29:53attack target here. The target is also
29:56get owner.
29:58Also not going to let me do that. I have
29:59to call it again. So, attack
30:02end
30:04and just replace it with this one.
30:13There we go.
30:16Compile. Now, it's all correct. And on
30:20slash, call the slash What was it
30:23called? Sphere trace damage.
30:27Now, the damage info we have from the
30:29attack info struct.
30:35And the radius
30:37uh we're going to make it a variable of
30:40the primary melee attack and the length
30:42as well. So, now you can define these uh
30:45when uh you call the attack function.
30:50And let's just clean this up a bit.
30:55All right, very nice.
30:57And let's use it. This one will only
30:59going to be used by the melee enemy, but
31:00you can use by whichever melee enemy you
31:02want.
31:05So, we actually don't need the sphere
31:06trace damage anymore.
31:08We're going to delete that.
31:11And this whole short range attack will
31:13become uh much simpler. Let's just
31:15remember which notify we play. We play
31:17this notify.
31:19So, I can actually delete all of this
31:21now.
31:23And just call off of BPC attacks our
31:28primary melee attack.
31:31Uh the length Oh, I don't remember what
31:33the length and radius were. Let me just
31:35revert them back.
31:37The length was 200 and the radius was
31:3920. Okay, now I know.
31:43Undo again.
31:45So, length was 200, radius was 20.
31:51And attack info, we say make attack
31:54info. Here's our attack target.
31:57Here's our montage and damage info was
32:01this one.
32:03Uh again, I just copied and pasted it.
32:04You can pull off and say make damage
32:06info.
32:09Great. So, this is now
32:11Ooh, I'm still
32:13Yeah, I'll go This is still calling
32:14sphere trace and we deleted it.
32:17We'll fix that. And this one's calling
32:19sphere trace and deleted it. We'll fix
32:21that as well.
32:23Uh so, let's see what uh this looks like
32:26now. So, it should still do the same.
32:29Uh whoa.
32:33Short range attack.
32:40Let's see. Why didn't attack? Oh, there
32:44we go. Okay. So, it still does the short
32:46range attack as expected. Look at that.
32:50And
32:52attack me. No, not this one.
32:57Yeah, okay. Working as expected.
33:00Um now, the long range attack. Uh by the
33:03way, I'm going to be moving all of these
33:04attacks, so you can skip forward to the
33:06interesting part, but the interesting
33:07part will be uh the spinning attack
33:10because this one does a lot more. It has
33:12a chase, it has the spin mesh, and these
33:14we're going to remove completely. And
33:16I'm also going to be adding them in the
33:17behavior tree at the end. Um so, make
33:20sure to stick around for that, but if
33:22you're not interested in these specific
33:23attacks or you have your own, you don't
33:25have to you can skip forward till the
33:26part where I actually um face some
33:29interesting challenges.
33:31But for now, I'm just copying and
33:32pasting.
33:33So, long range attack, copy, BPC
33:36attacks, paste. It's going to ask me
33:39what to do with the jump to attack
33:41target. Again, I'm going to say do
33:42nothing now, but we're going to copy it
33:44later on.
33:47Uh and oh, one one important thing is
33:49that right now we're doing this uh
33:51attack and cast to character um in every
33:54single attack. So, I'm going to make
33:56this into a
33:58um a shared function. Let me show you
34:00first.
34:02Um so, we're going to delete this.
34:05Um hm.
34:07Move this a bit. So, instead of calling
34:09these
34:11every time, I'm going to create a
34:12function. I'm going to call it
34:14um
34:15attack
34:17base.
34:21And it's going to do these things for
34:23me.
34:25So, the attack base will just take the
34:26attack target as input. It's going to
34:29do all of this and then
34:33return
34:35the mesh
34:37because we need the mesh to play the
34:39montage.
34:41So, now instead of doing all of this, I
34:44can just call
34:48attack base
34:51give it the attack target and I already
34:53have my mesh. Yay.
34:56Much cleaner.
34:58Let's do it here as well.
35:01Delete these bad boys.
35:05Attack base, attack target, and mesh.
35:10Boom.
35:12Okay.
35:13So, we're going to do the same here.
35:19Paste this.
35:21Attack target, mesh.
35:26Oh, sorry. This shouldn't be attack
35:27target. Again, I forgot. This should be
35:29attack info.
35:31S {underscore} attack info.
35:36Break it.
35:40And this was the attack target.
35:46So, let's actually move this a bit down.
35:53And this is the montage and this is also
35:56the target.
36:01All right.
36:03And again, the interruptibles
36:06are off of the get owner.
36:11Set is interruptible
36:14to false
36:16over here.
36:18But once we're done, set it to true
36:21again.
36:24Always make sure this is off of the get
36:25owner as the target.
36:29All right. And
36:32oh.
36:34Okay. So, a few things now. We don't
36:36have this jump to attack. We're going to
36:38create it.
36:40And this one is complaining that the
36:41target is not set. This should be Oh, I
36:44have to always do this
36:47from scratch for some reason.
36:49So, I have to call attack end
36:54and replace it with this one.
36:57And I'm calling attack end off of get
36:59owner.
37:02All right. So, now we need to say what
37:04happens on slash and what happens on
37:05jump. Luckily, on slash, we already have
37:08this sphere trace damage we used above
37:09here. So, I'm just going to do the same
37:11exact one.
37:14Um radius 20, length 200. Nothing's
37:18going to be different here. And boom,
37:21here's my damage info.
37:27All right.
37:30And now on jump, uh all we want is
37:33actually Well, what happens on jump here
37:36is this jump to attack target.
37:39So, I am going to copy all of this and
37:42modify it a bit, but let's add it here
37:45to our attack notifies.
37:49It's going to ask me what to do with the
37:51calculate future uh actor location. I'm
37:54going to say create matching function.
37:57So, then it creates the function for me.
37:59Let me just open it up and make sure
38:02Okay. So, it just creates the function,
38:04but doesn't copy the implementation. So,
38:06that's not what I want. So, I'm going to
38:07delete this.
38:09Go over here. You can copy and paste
38:11functions just by copying them and going
38:13over here and pasting them. And that's
38:15as simple as that.
38:17Uh-huh.
38:24All right. So, now we have our function.
38:28Uh we need to make some changes because
38:30here get actor location will be get
38:33owner
38:35and then get its actor location.
38:37And compile. Yeah, there's still a few
38:41things.
38:42Uh okay. So,
38:46there's the stop movement immediately on
38:49the character movement component that we
38:50don't have.
38:53And also bind on land delegate All of
38:56these require a character basically. So,
39:00I need to get my owner
39:03and I need to cast it to a character
39:07and right click.
39:09Uh I I did right click and convert to
39:11pure cast.
39:12And then I can off the character do all
39:15of this stuff.
39:25All right.
39:27And launch character also needs a
39:29character. So, launch character needs a
39:31character, this bind needs a character,
39:33this unbind, and this stop movement.
39:37Compile and now everything is happy.
39:42All right.
39:44So, what's left is for us to call our
39:47jump to attack target
39:51and pass in the attack target.
39:55Great.
40:00And in our melee enemy, we don't need
40:03Let me just uh
40:04Yeah, we don't need any of this anymore.
40:08Well, let's keep the function name.
40:09Sorry. So, we're going to create just
40:11delete this.
40:13Oh, the jump to attack target, we don't
40:15need it at all.
40:16And here, we are going to delete all of
40:19this. We just need our long-range
40:22attack.
40:23Pull off of BPC attacks, call long-range
40:27attack.
40:29Well, actually, did I rename it? I
40:30should probably rename it. So, this is
40:32primary melee attack and whoa, my cat is
40:35in the way.
40:38Uh and this is
40:40um
40:41Let's call it long-range melee attack.
40:45Uh I mean, anyone can use it. It doesn't
40:46have to be a melee, but um it has a
40:48slash and a jump. Oh, come on.
40:51So, I'm going to make it for the melee.
40:56Uh okay, you can you can sit here.
41:01So,
41:02now we want to make
41:06our
41:07attack info.
41:09Um the montage will be our What was it
41:12called? Jump. Yeah, this one.
41:15And our attack target is our attack
41:18target and the damage uh let's just copy
41:21the damage from this one.
41:28All right.
41:35Okay, sorry.
41:38Looks good.
41:40So, let's test this out again. Make sure
41:42it's working correctly.
41:43Is he going to jump? And boom, yes,
41:46working nicely.
Modifying The Melee Spinning Attack
41:50Um now, the spinning attack is an
41:52interesting one um because um
41:56there's a spin mesh and a chase target.
41:59Now, if you recall, I said all of these
42:01attacks can be used by um any
42:05uh character um and even the player as
42:08well. So, I don't want the chase
42:11functionality to be tied to the attack
42:13because maybe you as a player um you
42:15want to do the spin attack and then you
42:17move it yourself. You don't want the
42:19your player character to be moving on
42:21its own.
42:22Right, Chloe?
42:24Yeah.
42:26Um so, what I did actually here, I've
42:29already done that.
42:32Which is I made the spin part of the
42:36animation.
42:37So, now the animation itself has the
42:39spin. I no longer need to call spin
42:41mesh. Um now, we just need to handle the
42:44move or the chase on its own.
42:47So,
42:49let's copy this
42:51and make some changes.
42:55Spinning attack over here, paste. So,
42:59now it tells me there's a spin mesh,
43:00chase, and stop spinning. All of these,
43:02what to do with them? I'm just going to
43:04say do nothing.
43:06Um now, spin mesh, we don't even need to
43:08spin and we don't need to chase at all.
43:11And AOE slash, we already have this one.
43:14Uh and it's called AOE damage this time.
43:19And here's our whoa, attack target
43:23and radius
43:25um
43:27I think it was 300. I don't remember.
43:31Um we still have it here, right?
43:34Yeah, AOE slash.
43:37The radius, yeah, the radius was 300.
43:39Okay.
43:41Um and damage info, again, this is not
43:45attack target.
43:47This is attack info
43:50of type attack info.
43:56Break.
43:58And we get our attack target from here.
44:07Um this is a bit of a mess.
44:12And damage info, we get it from here.
44:17Montage, we get it from here.
44:19And this is not parent attack. This is
44:21the attack base.
44:25Which takes our attack target and gives
44:27us our mesh back.
44:30Then we can delete this mesh.
44:34And attack end, again, we need to well,
44:36end is interruptible. We don't need stop
44:38spinning because spin is part of the
44:40montage now.
44:44So, I'm going to get owner
44:48and say
44:49uh attack end.
44:51I'm going to replace this one.
44:54And just plug in
44:56whoop.
44:58Plug in all these things.
45:02And put it in this place. And also, is
45:04interruptible, set
45:07whoops, set is interruptible
45:10to false. So, as soon as the attack
45:12starts, can't be interrupted. And once
45:15the attack is over,
45:17set is interruptible to true again.
45:25Okay.
45:28Um spin, we don't need it. So, I'm going
45:31to go over here and delete spin.
45:33And slash. Uh this is So, we have an AOE
45:37slash and a regular slash. So, a slash
45:39is what happens in the beginning and
45:40then the AOE slash. So, this one I'm
45:43just going to call sphere.
45:46Trace on damage.
45:52Uh why isn't this Okay. So, sphere trace
45:55on damage. Here's our damage info.
46:02And radius, 20, length, 200.
46:09All right. And here's our spinning
46:12attack. Let's test it out. We didn't We
46:14didn't change it here.
46:16So, now actually, all of this, spinning
46:18mesh, stop spinning, chase target, AOE
46:21slash, we can get rid of all of it.
46:24Delete.
46:26Delete all of this. Gone.
46:29And now the spinning attack.
46:33Delete. And we just get our BPC attacks.
46:39Call spinning attack. Again, let me
46:42rename it to spinning
46:46melee attack. Doesn't really matter.
46:50And our attack info pull and say make.
46:55This is our attack target.
46:57Our montage is the spinning attack
47:00montage and the damage
47:04I forgot. Let's just put I don't know,
47:0710 or
47:08whatever. Yeah, 10 doesn't matter.
47:11And say it's melee damage.
47:15Great.
47:17Let's test it out. So, I should get a
47:19long-range attack and a spinning attack.
47:24Nice. So, it works, but uh he is not
47:27chasing me.
47:28Um that's because, of course, we removed
47:30the chase functionality.
47:32Uh what I'm going to do instead is add
47:33the chase functionality as part of the
47:36uh behavior tree. And let me show you
47:38how I'm going to do that.
47:40So, opening up our
47:43uh
47:44Where is it? Enemies, AI. Our
47:50enemy behavior tree, our melee behavior
47:52tree.
47:53And here, in this short uh sorry, where
47:56is it? In this uh spinning attack. I
47:58should probably rename this to spinning
48:01attack.
48:03So, in this spinning attack, instead of
48:04just doing
48:06um
48:07this Yeah, spin on its own.
48:09Um here's what I'm going to do. I'm
48:11going to do a sequence of actions.
48:14So, I'm going to replace this with a
48:16sequence.
48:19And I'm going to call this the spinning
48:22attack sequence.
48:25And this is what's going to have the
48:26cool down actually. So, the cool down
48:27will be on the whole sequence.
Doing Tasks In Parallel In The BT
48:30Um and what I want is to spin and chase.
48:33So, I want the chase to be part of the
48:35behavior tree.
48:36Um but I want to do both the spin attack
48:38and the chase in parallel. So, both at
48:40the same time. You're attacking and
48:42you're spinning. So, to do something in
48:44parallel,
48:45um I'm going to use the parallel node.
48:49So, there is a node called simple
48:50parallel here.
48:52Uh that takes a main task and um a
48:56background task. And the node itself
49:00finishes when the main task finishes.
49:02So, the spinning attack will be the main
49:05node.
49:06And the
49:08um
49:08background task will be a move to.
49:13Move to the attack target.
49:16And this, as long as this is playing,
49:18this will keep repeating. So, it's going
49:20to keep moving until
49:22uh the first attack ends. And I'm going
49:24to change the acceptable radius to 15 or
49:26I don't know, maybe
49:28uh
49:29even 50. So, you don't have to move
49:31really close. You can just move a bit
49:32further away.
49:34I'm actually going to make it 100.
49:36Sorry. Okay.
49:37Um
49:38Yeah, so let's see what this looks like
49:40now.
49:40So, do the long range
49:43and do the spin. Is it going to chase
49:46me? Yes, and he's chasing me.
49:49Perfect. But one thing I noticed is that
49:51he chases me right away, not at the
49:53right time. So, watch this.
49:55Yeah, so he's already chasing me before
49:58the the spinning is already begun. So,
50:01it looks a bit weird. Um
50:04I mean, you can leave it if you don't
50:05mind.
50:06Uh but I didn't like this uh
50:09Let me show you again.
50:11This sliding effect in the beginning.
50:13So, I can add a wait. So, I can make
50:15this into a sequence.
50:19And add a wait.
50:22And the wait will depend on actually how
50:25long it takes to reach the spin part.
50:28So, where is our spin?
50:33Right here. Yeah, right here, maybe. So,
50:351.2 seconds. So, I'm going to wait for
50:391.2 seconds.
50:42Now,
50:45he's going to
50:46wait 1.2 seconds and then start chasing
50:49me. Perfect.
50:51All right, and that's how we move the
50:54um
50:55the actual chasing part to the behavior
50:57tree and keep the spinning attack um
51:01agnostic of the chase. So, the spinning
51:02attack isn't related to the chase.
51:04They're both separate functionalities
51:05that we can choose to use together or
51:08not. So, now our melee attacks have now
51:11completely moved to the BPC uh attacks
51:14and this is pretty much all of it. So,
51:17it is much much more compact now
51:21in the actual
51:23um
51:25enemy class.
Moving All The Mage Attacks to BPC_Attacks
51:30Nice. Okay. So, now what we have to do
51:31is actually do the same for our
51:35um
51:35ma- mage enemy. But luckily, the mage
51:38enemy doesn't have a lot of attacks.
51:40So, let's look at our mage enemy.
51:43Mage enemy only has two attacks. So,
51:45this basic and barrage attack and they
51:48are pretty simple to move. So, let's do
51:50it really quick. So, I'm just going to
51:52copy all of this BPC attacks.
51:56Um let's actually uh let's
52:00comment all of these.
52:04Um yeah, let's leave them for now. Okay.
52:06So, I'm going to go over here, paste and
52:09this we're going to rename to
52:11um I don't know, something like
52:15um basic mage spell.
52:20And instead of attack targets, again,
52:22it's attack info
52:27of type attack info.
52:30We break it. This is where we get our
52:35uh attack targets.
52:37Now, our montage and here we don't have
52:40this. Oh, did we delete the uh
52:43We have to very important to delete
52:47Oh, I think we deleted it. The base
52:49attack. So, this uh so that the parent
52:51attack um
52:53uh sorry, so that this base attack is
52:56always calling the uh
52:58uh the one from the base enemy. But
53:00yeah, I think we deleted it cuz I don't
53:02see it here. Yeah.
53:05Okay, scratch that. So, here we call
53:08attack base.
53:11Pass in the attack targets and we get
53:14our mesh.
53:18Um
53:21And attack end as well. We need to call
53:23it on get owner.
53:28Can't do that. Get owner.
53:33What am I doing? I already have the
53:34owner. Uh attack end, I mean.
53:38And on completed and on interrupted. And
53:41here's our attack target.
53:46Um
53:48And we don't have an interrupt because
53:50the enemy is always interruptible during
53:52this time. And here we don't need BPC
53:55attacks. We're already in BPC attacks.
53:57So, this is a reference to self.
54:00And here the mesh, again,
54:02um
54:03should be the mesh that we get from this
54:05one.
54:11And the damage info is this variable.
54:19Um
54:22Yep.
54:26Anything else?
54:30No, I think that is it.
54:32And yeah, this magic spell we already
54:34have. So, no need to change anything
54:36here.
54:39Um Now, let's move the other one.
54:44Oh, actually let's
54:47update this
54:49to call
54:52BPC attacks
54:54basic mage spell.
54:58Make
55:00and make
55:03This was 20.
55:05Projectile.
55:07This was
55:10Wait, which one was it? Fireball. Yeah.
55:13And here's our attack targets.
55:18Are we missing anything?
55:22Nope, I don't think so.
55:28Now for the barrage, again, copy all of
55:31this lovely stuff. Go over here and
55:35paste it.
55:38Um First things first, replace this with
55:42attack info.
55:44S underscore attack info.
55:49Break it.
55:50There's our Oh, not this one.
55:53We want our base attack base. There's
55:56our attack target.
55:58There's our mesh.
56:04And there's our attack target as well.
56:08This one is off of
56:10get owner,
56:12attack end.
56:15On completed, on interrupted. Here's
56:18your target.
56:22Uh and
56:25is interruptible
56:27is true
56:31at this point. So, set is interruptible
56:38to Oh, sorry. Not at attack end.
56:43Oh, actually yes. This is at attack end.
56:47So, when the attack is over,
56:50uh the enemy is interruptible again.
56:52But here we have they are not
56:54interruptible when when they actually
56:56start the spell. But before, so before
56:58this notify begins, they are
57:00interruptible. So, that's why it's put
57:02here.
57:04So, I'm going to do this.
57:06Set is interruptible at this point to
57:10false.
57:12And do it off of get owner as well.
57:15So, as soon as fire is called, they are
57:19no longer interruptible.
57:20And this will delete magic spell as
57:22well.
57:24Mesh we get from here.
57:29Uh get actor location is off of owner.
57:34So, we start from our own actor
57:36location.
57:38And we get the attack target's actor
57:41location. Right? That's what we were
57:43doing.
57:45Yes, this is the attack target and this
57:46is our self.
57:49And everything else. Oh, and this damage
57:51info, of course, is this variable here.
58:00Uh-huh.
58:03Anything else? Compile. Nope, no
58:06complaints. Nice. Oh, montage. Don't
58:09forget that one.
58:11Uh
58:13And I think that is it for the mage
58:16enemy.
58:18Let's test this bad boy out. Let's get
58:21our mage.
58:24Boom.
58:28Okay. So, teleport. Basic attack. Boom,
58:32working. Teleport.
58:35And
58:37basic attack again.
58:39All right, and now the barrage. Woo.
58:42Woo. Oh. Yes, very nice.
58:46Everything's working as expected.
58:49Oh, actually did I
58:52Did I didn't. No.
58:54Um we're still doing the old barrage.
58:56So, I I still think it's going to work,
58:57but yeah, we need to make sure we are
59:02calling the one from the BPC attacks.
59:05So,
59:07let's call it the barrage magic. And
59:11since we called all of magic spells, not
59:13attacks, let's call this one spell as
59:14well.
59:18Barrage magic spell. Make our attack
59:22info. Make our damage info.
59:26This one, I don't know, let's say 15
59:28projectile. Here's our attack target.
59:31And the montage was the barrage montage.
59:38Okay.
59:41Now we're done.
59:43And we deleted all the attack helpers,
59:46so that's cool.
59:50Let's test it out again.
59:52Teleport, basic attack,
59:56teleport,
59:58and
1:00:01teleport,
1:00:02barrage.
1:00:05Woah, very nice. And it's working.
1:00:08Awesome.
Adding Ground Smash Attacks To BT
1:00:09Now the final thing we need to do to
1:00:11round off this tutorial is to actually
1:00:13add our ground smash attack to our
1:00:15behavior tree, because right now the
1:00:17melee enemy and the mage enemy don't do
1:00:19the ground smash attack yet.
1:00:22So, let me start by the mage enemy.
1:00:25And as always, you still need to add the
1:00:27attack in your attack enums. So, I'm
1:00:29going to add one here and call it ground
1:00:32smash attack.
1:00:36All right.
1:00:37But we're going to do something a bit
1:00:39different and actually smart this time.
1:00:43But let me show you what I mean.
1:00:45So, in our enemies AI, in our behavior
1:00:48tree for the mage,
1:00:51right now it's just based on cool down.
1:00:52So, if the barrage attack is not on cool
1:00:54down, it does that. If the basic attack
1:00:56is not on cool down, it does that.
1:00:57Otherwise, it goes into the evade.
1:01:00But for the ground smash, I want it to
1:01:02only do it if the player is within a
1:01:04certain distance from the mage. So, if
1:01:07the mage enemy is evading,
1:01:09I want it to stop evading if the player
1:01:12enemy gets too close and then do the
1:01:14ground smash attack.
1:01:15So, to do that, I'm going to move all of
1:01:17this a bit here.
1:01:21And I'm going to make a new node here,
1:01:23and it's going to be a
1:01:26sequence called the ground smash
1:01:31sequence.
1:01:33All right.
1:01:34And what it's going to do is first check
1:01:37if
1:01:39we need a decorator
1:01:40that checks
1:01:42for a blackboard value. And if you
1:01:44recall, we have a blackboard value
1:01:46called distance to attack target. So, if
1:01:48this distance to attack target is
1:01:51less than or equal to
1:01:54250, cuz yeah, let's say 200.
1:01:59Then I want you to
1:02:01abort
1:02:03lower priority.
1:02:05So, abort to the evade task and then do
1:02:08the
1:02:09um
1:02:11attack. So, default
1:02:14mage attack.
1:02:16And this is your attack target. Tokens
1:02:19needed one.
1:02:20Teleport location, interesting one.
1:02:22We're going to talk about this in a
1:02:23second, because this one doesn't have a
1:02:24teleport.
1:02:26And the attack name will be ground smash
1:02:28attack.
1:02:30Um and after you're done with the
1:02:32attack, I want you to do the things you
1:02:34usually do. So,
1:02:36these lovely tasks.
1:02:39So, wait.
1:02:43Run EQS and teleport away.
1:02:48Actually, don't need to do that. It's
1:02:49going to do it automatically. So, we
1:02:50actually only need to do this.
1:02:53Yeah.
1:02:54Um but here's the interesting thing. Now
1:02:56all of the attacks, so this is our mage
1:03:00attack,
1:03:01um
1:03:03where we always teleport. So, we first
1:03:06do the attack start and then we
1:03:07teleport. So, I'm not going to want to
1:03:10teleport in the ground smash attack. I
1:03:12want this to be optional. So, I'm going
1:03:14to add a variable here called should
1:03:16teleport.
1:03:18And it's going to default to true. Make
1:03:21sure to click the I icon, cuz I want to
1:03:23edit it from the behavior tree.
1:03:25Um and I'm going to do a
1:03:30a branch right here.
1:03:34Right here.
1:03:37On should teleport. So, if should
1:03:39teleport is true, then continue what
1:03:42you're doing. If should teleport is
1:03:44false, then go right to the attack. So,
1:03:48ignore the teleport, the bind, the
1:03:50unbind. We don't need any of that. Go
1:03:53directly to the attack.
1:03:56So, just a simple condition so that we
1:03:58don't always have to teleport before any
1:04:00attack.
1:04:02And now the attack, we just need to go
1:04:04over here in the ground smash attack and
1:04:07call
1:04:08uh ground
1:04:12smash attack. Make sure to call the one
1:04:14off of the
1:04:16uh mage, not off the BPC attacks,
1:04:18because we don't want to do that.
1:04:20We want the mage one.
1:04:24Ground smash attack.
1:04:29Excellents. And the attack target is
1:04:32this guy.
1:04:37Um
1:04:39Yep.
1:04:41Oh, and one very important thing. So,
1:04:43right now we don't have anything that
1:04:44updates this
1:04:46distance to attack target key. We have
1:04:48it in the melee enemy
1:04:51as a
1:04:53service. So, we need to copy this
1:04:54service and put it on our mage tree as
1:04:57well.
1:04:59So, let's put it
1:05:01um
1:05:03I don't know, in the combat state or in
1:05:05the can see target.
1:05:08Doesn't really matter. Let's put it in
1:05:09the combat state.
1:05:12Okay.
1:05:14Uh yeah, let's see how this looks like.
1:05:16So,
1:05:17if I get close during an evade, woah,
1:05:20something happened. Oh, I forgot should
1:05:23teleport should be false here and should
1:05:26be true here and true here. Yeah.
1:05:29Okay.
1:05:30So, again, if I go to the
1:05:34Um
1:05:36Something's wrong
1:05:38with the ground smash attack. Oh, this
1:05:43isn't connected.
1:05:45That would do it.
1:05:49That was a
1:05:51quick easy fix. All right, let's try it
1:05:53again.
1:05:54Go close and boom, do the smash and then
1:05:58teleport away. Perfect. So, again, if
1:06:01during the
1:06:03evade, I get woah.
1:06:08Oh, okay. So, enemy has to be evading
1:06:12and if they're evading and I get too
1:06:13close, they're going to do the boom,
1:06:16ground smash.
1:06:18Very nice.
1:06:19All right, let's also add a quick cool
1:06:22down on this one as well. So, cool down,
1:06:25let's say so you can't do it more than
1:06:27every 2 seconds or something.
1:06:29Um
1:06:32Yeah, all right. Oh, and also we can
1:06:34name this decorator. So, if player
1:06:38too close, something like that.
1:06:41All right, now let's add to our melee
1:06:43enemy the other attack as well.
1:06:45So, in our melee, we also need to go to
1:06:48our melee attacks enum
1:06:51and add a decorator, call it Sorry, add
1:06:54a value, call it ground smash attack as
1:06:57well.
1:06:59And let's close up this, close this.
1:07:02And let's do it
1:07:05um
1:07:06less priority than the spinning attack,
1:07:10but higher priority than the long range.
1:07:12So, I'm going to copy this, paste it
1:07:15here.
1:07:18And
1:07:20let's also give it a cool down of I
1:07:23don't know, 4 seconds.
1:07:25Make sure to change the attack name to
1:07:27ground smash attack. And this one as
1:07:29well. Ground smash attack.
1:07:33And also let's have a distance check.
1:07:35So, if the distance is less than or
1:07:38equal to
1:07:40200 as well. Cuz we want to also do it
1:07:43only if we're close.
1:07:47And actually, that should be it. This
1:07:48one should be a simple one.
1:07:51So, let's go over here and add our melee
1:07:55enemy.
1:07:57And let's test it out.
1:07:59So,
1:08:00do this attack
1:08:02and spinning is the highest priority, so
1:08:04it's going to do the spin. Don't kill
1:08:06me. Oh, [ __ ] it killed me.
1:08:08Okay, this one I This time I won't get
1:08:10killed.
1:08:12Okay. And spinning attack, highest
1:08:15priority.
1:08:17Oh, he's not going to get me. He's not
1:08:18going to get me. All right.
1:08:21And now he should do the smash. Do it.
1:08:23No, spin is Okay, let's
1:08:25decrease the cool down a bit just to see
1:08:27it.
1:08:28Cool down 1 second. Okay, and let's
1:08:30increase the cool down of the spin to
1:08:32like seven.
1:08:34Okay.
1:08:35So, do the jump and smet Oh, nope.
1:08:41Something happened.
1:08:42Oh, sorry. My bad. We forgot to add it
1:08:46here. So, we have to call it, of course,
1:08:49ground smash attack
1:08:53and pass in our attack target.
1:08:57Uh
1:08:58This is in our melee attack task, by the
1:09:01way.
1:09:02Okay, now it should work. Jump and
1:09:07woop, boom.
1:09:08Very nice.
1:09:12But he's not doing anything afterwards.
1:09:16Because
1:09:18we didn't connect this.
1:09:20Oh, did we make the same mistake in the
1:09:22melee in the Sorry, in the mage? I hope
1:09:23we didn't.
1:09:26Uh
1:09:29Where is our mage?
1:09:32Oh, we don't have Oh, of course, cuz
1:09:33this is a separate function. We have a
1:09:35separate function for it.
1:09:36In the mage. So, let's make sure we
1:09:39didn't make the same mistake, and boom!
1:09:43And it should go back to attacking now.
1:09:45Great.
1:09:48All right, and that's pretty much it.
Next Up In Part 19
1:09:51As always, thank you all for watching.
1:09:53Uh this one was a pretty long one and
1:09:55had a lot of um mainly technical
1:09:57changes, uh but I think now we have a
1:09:59pretty powerful uh attack system
1:10:01uh that is more flexible and can be used
1:10:03for multiple enemy types. And again, the
1:10:05main goal of doing this is for our boss
1:10:08fight. So, now the boss fight can reuse
1:10:11any of the um attacks that we've already
1:10:14implemented for our melee enemy, our
1:10:16mage enemy. And I'm just remembering now
1:10:18I forgot to move the one attack in the
1:10:20ranged enemy, but that's fine. Um you
1:10:23know the process now, and it's a simple
1:10:24as copying and pasting and making sure
1:10:26that you're changing self for owner.
1:10:29Um now, I'm not sure if the next
1:10:31tutorial will be the boss fights. I
1:10:33still have some planning to do, but um
1:10:35if I realize that we are now at the
1:10:38point where we're ready for the boss
1:10:39fights, then that actually might be the
1:10:41next tutorial, which I'm really excited
1:10:43for.
1:10:44Uh but no promises yet. I still have
1:10:46some planning to do. So, I'll uh see you
1:10:49in the next one.