Full transcript
Intro
0:00that's the boss he doesn't look so
0:07tough welcome back everyone and it's
0:09finally time to learn how to make our
0:11boss fight we're going to be learning a
0:13lot in these next couple of videos so
0:15here's a quick overview we will learn
0:18what makes a good boss fight we will be
0:20combining a variety of different attacks
0:23that we've learned so far such as melee
0:25combos shooting projectiles AOE attacks
0:28but we will learn how to make them
0:30unique to the boss and more challenging
0:32and we will be using our damage system
0:34to its fullest capabilities most
0:37importantly we will be applying
0:39everything that we've learned so far in
0:41the last 19 parts to make sure that you
0:43have a good grasp of all the different
0:45AI tools and techniques that we've been
0:47using in this series so let's get
0:50[Music]
0:55started all right so before we start
What makes a good boss fight?
0:58building the boss fight we need to First
0:59first design the encounter which means
1:02we need to know what makes a good boss
1:04fight so I will now give you five rules
1:07that a lot of games follow in order to
1:09make sure that they're designing a good
1:11boss fight and I will keep referring
1:14back to these rules during
1:15implementation so you can actually see
1:17how we're going to apply them in
1:19practice all right rule number one is
1:22the setting so boss fights are usually
1:25played out in a controlled environment
1:28so uh I prepared here this little
1:30circular Arena and I also made the fog
1:34color red for more dramatic effect uh
1:36and I will show you how the arena will
1:39become part of the encounter itself when
1:41we start building it so rule number two
1:44is predictable but challenging so boss
1:47attack patterns should be predictable
1:49the player should be able to know what
1:50the boss is about to do uh you can do
1:53that through visual effects uh certain
1:55sound cues flashy animations it's very
1:58important the player knows what's coming
2:00but that doesn't mean you should make it
2:02easy it should still be challenging so
2:04even though the player knows an attack
2:06is coming it should still be hard to
2:08avoid or hard to block third rule is
2:11testing the players current skills so
2:14the boss encounter should test abilities
2:16and skills the player has already
2:18learned so far so if the player has been
2:20dodging and blocking attack so far don't
2:23suddenly introduce a new attack that
2:25they have to jump over if they haven't
2:27encountered that before uh un unless you
2:30intentionally aim to introduce this new
2:32mechanic at that part of the game but
2:34otherwise keep it to skills that the
2:36player already knows but again more
2:38challenging fourth rule is how the boss
2:40reacts to the player so the boss is
2:42obviously stronger than all the other
2:44enemies so maybe they don't get
2:45staggered as easily or they don't do a
2:47hit animation on every player attack
2:50it's just important to give the player
2:52visual feedback that your attacks have
2:54weight but this enemy is stronger so
2:57that when the enemy finally does get
2:58staggered or does do do a hit animation
3:00a player knows oh this attack had an
3:02effect had a stronger impact than my
3:04regular attacks and finally the fifth
3:07rule is the difficulty of the encounter
3:10so the boss fight should start
3:12relatively easy or manageable so that
3:14the player can get used to the attack
3:16patterns of the boss but as the fight
3:19progresses the attack patterns and the
3:21fight itself should become more
3:23difficult to test what the player has
3:25learned from the start of the fight till
3:27the end of it and of course the ending
3:28should be the most challenging part all
3:31right now with these five rules in mind
3:33let's start building our encounter and
3:35see how we're going to apply them I want
3:37to quickly announce that I'm offering a
3:39new tier on my patreon for anyone who
3:41wants to have a one to1 hourong call
3:44with me every month to ask questions
3:46about game development software
3:48engineering or really anything else that
3:50you want and just head over to my
3:52patreon and check out the new Apprentice
3:54here thank you all right so once you
Creating the boss enemy & setting defaults
3:57have your boss Arena ready uh first
4:00thing we want to do is uh create our uh
4:03boss enemy type so we're going to go to
4:06our enemies folder rightclick on our
4:08base enemy and create a child we're
4:11going to call this the BP enemy
4:15boss uh let's create a new folder call
4:18it boss enemy and let's put this guy in
4:23there all right so open up our boss
4:27and as soon as it opens uh we want to
4:30change two things so we want to make the
4:33boss um look different and make uh the
4:36boss bigger so the first thing is for
4:39looking different uh we're going to
4:40change the uh material of the mesh so I
4:44already have this um where did I put it
4:48actually is it here in my materials
4:52folder yeah so I already have this uh
4:55the same material as the Manny uses but
4:57I just made it red so I'm going to use
4:59that
5:00so then our boss is all red and the
5:04second thing is I'm going to make the
5:05mesh bigger so I'm going to make him
5:07like
5:091.25 uh and after we do that we should
5:12also make the capsule itself
5:14bigger
5:16uh something like 140 and maybe here
5:2244 maybe more 45 something like
5:27that and make make sure that the
5:33mesh lines up right at the bottom of the
5:39capsule all right then he is definitely
5:42too big this mesh sorry this capsule so
5:46let's decrease the size again 120 I
5:48think 120 is
5:50good uh we're going to have to go back
5:54and adjust this a little bit
5:58yep
6:00all right yeah I think this is uh
6:01looking pretty
6:03good and if we put our boss in the
6:07world uh he will look something like
6:12this and relative to the player the boss
6:16is bigger very
6:19nice all right now next thing we want to
6:21do is uh set the uh default values for
6:24the
6:25boss so uh let's start by well actually
6:28click here on the class defaults and
6:31let's set the animations so we have this
6:33hitch reaction montage and we also have
6:35the Stagger Montage so stagger I'm going
6:37to use the regular stagger that we use
6:39for our other enemies uh which as a
6:41reminder just uh looks like this and has
6:46root motion so the enemy falls back a
6:48bit and for the hit reaction I have a
6:51specific um hit reaction for the
6:54boss uh which is this
6:58animation um um now this is called
7:00Montage axe hit reaction uh because I'm
7:03going to give the boss uh an axe uh as
7:06their main
7:07weapon uh so and we're going to see that
7:10in a
7:11bit um all right so other defaults so if
7:14we open our interfaces uh our movement
7:18speeds so our movement speed here we
7:20want to override it also so uh we get uh
7:24what we want to do is get our character
7:25movement component uh set walk
7:32speed all
7:37right and also return that
7:40value and that is going to be based off
7:43of a
7:46select uh what values did we have for
7:48the melee enemy so
7:52melee oh I think we we keep the base
7:54ones so the base
7:57had set movements
8:01speed uh 100 300
8:04500 yeah I think we can
8:09do
8:10100 um 200 and 350 so it's going to be
8:15bit slower the boss is bigger uh but
8:17we're not going to rely purely on the
8:20movement for the boss and you'll also
8:21see that in a
8:23bit and finally the health so I also
8:26want to override the health and I'm
8:27going to do that in the construction
8:28script so we get our damage system and
8:31we say set max health and let's set it
8:35to something like um I don't know
8:38700 uh where the rest of the enemies are
8:41100 uh and then set Health as well so
8:44we're setting health and Max Health to
8:47the same
8:48value um and of course you can decide to
8:51make this a variable if you want to
8:53promote it to a variable and then you
8:55can make it Instant editable by clicking
8:56on the I icon uh next to the variable
8:59and then you can edit it per instance of
9:01an enemy if you
9:02want uh but for us uh we're just going
9:05to keep it static
9:07here all right so um next thing I want
Creating/Equip the axe weapon
9:10to show you the weapon that we're going
9:12to give the boss so over here in our
9:16content folder weapons I already have
9:18the mesh um so I modeled this um nice
9:22Golden Axe and I just tried to follow
9:24the golden style that we've been using
9:26for our other weapons but yeah I just
9:27made a very quick model
9:30um and of course the animations the
9:32meshes and everything will be uh
9:33available to download on my
9:36patreon uh all right so in our axe
9:39actually back here in our base weapon uh
9:42we right click and create a child call
9:44it BP weapon
9:48ax and we change the mesh to use our
9:54ax um I'm not going to change anything
9:58else for the weapon
10:00uh but let's go back to our boss and
10:02actually wield the
10:04weapon uh this is not our boss and this
10:07is our boss all right so um if you
10:10recall in our BPI enemy AI we have uh
10:14equip weapon and also where is unequip
10:19weapon unequip weapon double click okay
10:23so I'm going to implement these two
10:24functions so for equipping a weapon I'm
10:27not going to have an animation for
10:28equipping the we weapon I'm just going
10:29to have the boss spawn with the weapon
10:31equipped
10:32already um so uh first thing we want to
10:35do is spawn actor from class choose our
10:39axe
10:42weapon uh spawn transform um can just be
10:45default so I'm going to split uh that
10:48way it just adds default
10:51values uh and then we are going to get
10:53our weapon variable where is weapon I
10:57could just search for set set weapon
11:01actor to this and then we want to attach
11:05actor to component we're going to attach
11:07our weapon to our
11:10mesh as always so the mesh is our parent
11:13and the socket name I think it's handore
11:16rcore X socket uh I'm going to double
11:20check that so over here search I already
11:23created this axe socket um but the same
11:26that we've done for the other sockets as
11:28well for The Sword and the rifle it's
11:30the same thing so yeah it's hand R ax
11:33socket let me copy it to make sure I
11:36have no
11:37typos and paste it
11:40here then I will snap everything to
11:44Target so it takes the location rotation
11:47and scale up our
11:48Target all right then at the end what we
11:51usually do is we just call um on weapon
11:55equipped uh but since we're not doing an
11:57animation all of this is synchronous so
11:59all of these will happen um uh
12:01synchronously so we want to give time
12:03for if someone is binding to this on
12:06weapon call and our on weapon equipped
12:08after calling equip weapon uh so we're
12:10just going to do a
12:12delay until next sck this just ensures
12:15that if you call equip weapon and then
12:18check for um uh this uh event being
12:21fired then you have time uh for the bind
12:24to actually
12:27happen all right and we're do the same
12:29for the unequip uh we're just going to
12:32uh get our weapon actor and we are going
12:37to destroy the
12:41actor
12:43um me do anything
12:46else no I think that's it and then also
12:49delay until next tick and call
12:54on weapon
12:57unequipped
13:00all right looking
13:03good so um well let me show it to you
13:07first if on begin play I just call equip
13:10weapon and we won't be doing it from
13:12here this is just for testing we'll
13:13actually be doing it from our Behavior
13:14tree as we always do uh but just to show
13:18you um if I play
13:21now there's our boss and his nice axe
13:25weapon
13:27Perfect all right all
13:29righty now let's remove
13:32this um next thing is animations so
Axe movement/idle animations
13:37Locomotion animations so let me show you
13:39real quick we're going to be using a lot
13:41of ax animations that I already prepared
13:43here uh but we're going to be going over
13:46uh every one of them so you'll see what
13:47we're actually going to be
13:49using so the first thing we're going to
13:51look at is the um axe Locomotion so this
13:55is again a strafe axe locomotion similar
13:59to our sword strafe Locomotion as well
14:02uh so let's see how we can switch
14:04between these different ones so opening
14:07up our ABP
14:10Manny um it's already on The Locomotion
14:13so if you go over here to Locomotion and
14:16walk run you'll see that we only have
14:19this sword strafe so I want to um check
14:23what weapon uh the actor is currently
14:26wielding and based on that change the um
14:29strafe animation so first we need to get
14:32a reference to this variable this weapon
14:34variable so in our event graph I'm going
14:37to go here add a
14:39pin well let's first get our owning
14:43actor um cast to BP enemy
14:48base and then plug that in
14:54here all right and then first thing we
14:57want to check is uh well we want to get
14:59the weapon so get the weapon actor and
15:02we want to get its class so I just want
15:04the class of the weapon so go over here
15:07to get class and then we're going to
15:09rightclick promote this to a variable
15:10and call it weapon class so based on
15:14what weapon the uh enemy is equipping
15:17we're going to use a different uh
15:19Locomotion
15:21animation uh so back here in oh sorry
15:24back here in our walk run
15:27States uh we're going to do a blend
15:31poses by
15:33bu So based on a certain variable we're
15:36going to check so we're going to get our
15:38weapon class and check if this is equal
15:43to uh
15:45our what was it called BP sword yeah so
15:49if it is equal to our sword this is true
15:53then we will use the sword strafe uh
15:57animation right and if it is false we
16:00want to still check if it's the ax or
16:02not I just don't want to assume false is
16:04always ax so I'm going to copy
16:06this and then if it is false we want to
16:11check again so copy this also and check
16:15now is it um an
16:19Axe and if it is true then I'm going to
16:22get my axe blend space
16:25here and plug it into the true and
16:27direction ground speed will be the same
16:30direction ground
16:32speed all right um and on false this
16:35means that you're wielding a weapon
16:36that's not a sword or an axe we don't
16:39have an animation for this now so our
16:41default should be the one that comes
16:42with um uh unreal mannequin which is
16:47this mm walk
16:49run
16:51yep let's just move all this down a bit
16:55okay so this will be our default and
17:00this will be our ground
17:01speed all right that is correct so now
17:06in our
17:08idle uh we are going to delete
17:12this paste what we copied here so these
17:16two
17:19conditions and check um if it is a sword
17:23then plug in the
17:25sword um if it is not a sword then get
17:29our axe
17:32idle make sure to click that it is
17:34looping and then it will be our Axe and
17:37on false it will be our regular uh male
17:44Idol all right now if we look at the
17:47enemy he is still not oh he's not
17:51wielding the sword
17:52yet um because we removed this let me
17:55add it back so you can see equip
17:59weapon come on equip weapon yeah so now
18:04there you go he's doing the ax Idol
18:07stance
18:09nice and I'm just going to remove this
18:11again okay oh sorry and one thing I just
18:15realized that I forgot to do or I uh did
18:17incorrectly was uh we didn't set the
18:20variable for is wielding sword so we
18:22have this sorry is wielding weapon
18:24variable so we need to uh set it
18:27somewhere here here uh is wielding
18:30weapon to true and then over
18:35here to
18:38false because we use this condition in
18:40our Behavior tree to know if we need to
18:42wield a weapon or
18:44not um all right so now next thing I
Boss health bar in the player HUD
18:48want to do is uh this is a boss right
18:51and they shouldn't have this tiny health
18:53bar on top of their head boss fights
18:56usually have the large
18:59uh like um uh boss health bar on the
19:01player HUD and this is uh also ties back
19:04to rule number one of the setting so the
19:06entire boss setting should feel that it
19:09is uh impactful that it is dramatic it's
19:11a boss so we're going to add a nice
19:14little U health bar in the player Hut
19:19itself so to do that we are going to
19:23open our widgets folder and let's create
19:26a new um widget here so widget blueprint
19:32of type user widget and we're going to
19:35call it w uncore boss health
19:40bar okay so first thing is we always
19:44need a canvas panel then we need some
19:48text maybe if you want to add like the
19:49name of the boss so text and I'm going
19:54to Anchor It top Center here this is
19:57zero this is zero
20:00uh size to content and this is
20:050.5 all right and then I am going to get
20:09a progress bar also Pop It In Here Also
20:13anchor it the same reset this to zero
20:16this to
20:17zero and um also this 0.5 but then I'm
20:22also going to push it up on the y a bit
20:25maybe like 50 or
20:27something
20:29yeah that looks
20:31good um actually no this shouldn't be
20:34anchored here this should be anchored
20:35like this so it takes up the full
20:38width oh sorry this is 50 this is zero
20:42all right so then the offset on the left
20:45on right on are zero so it takes up the
20:47full width and positioned 50 on the Y
20:50just to give some space here between the
20:52name uh which we can just call like boss
20:55fight or something you can make this if
20:56you have multiple bosses of course of
20:58course this can be a variable and it
20:59will be the name of the boss um so we
21:02can make it is variable and say uh boss
21:06name right and this also is variable and
21:10call it just progress bar or something
21:12it's
21:13fine I also want it to look a bit
21:15different than the uh player uh progress
21:18bar so I'm going to have it uh the fill
21:21typ sorry the uh bar Style no not the
21:24bar style what was it
21:26the um
21:30well first the the color so if we make
21:32it uh percentage 0.5 here let's have it
21:37sort of
21:38reddish yeah something like that dark
21:42red a
21:45bit um and I want it to be um rounded
21:51I'm going to search for rounded yeah so
21:53draw as rounded box here so this is the
21:57back
21:58background and draw as the fill also as
22:03rounded box so now you see the edges are
22:06rounded for both the fill and the uh
22:11background all right um yeah and this
22:15should um yeah the scale here doesn't
22:17matter just making sure that it scales
22:19as I scale the
22:22widget um one last thing this uh texts I
22:26want to change it to to be let's get our
22:31font uh to be a bit bigger let's say
22:3532 yeah that's good then this I will
22:39push it up just 70
22:42yeah all right so now that we have this
22:45um previously how we set the health was
22:49um using oh let me show you so we have
22:52in our damage system here damage system
22:55we have this health bar right so this is
22:57the widget and and the way we set the
22:58health is that we have um on the
23:02progress bar itself we have this
23:04percentage uh value bound to a function
23:07called get percent and this function
23:09gets our damageable actor which is
23:11passed in here as a reference and then
23:13we get the max Health at the current
23:15health and then calculate the percentage
23:17now um a lot of people complained that
23:19this way was causing some problems
23:21specifically I think an unreal 5.3
23:24passing the actor as a reference so I
23:25will show you a different way of uh um
23:28calculating the health of a widget as
23:30well so um over here um we have this
23:37value
23:39percent yeah this value here percent I'm
23:42not going to bind to it instead I'm just
23:44going to go over to my graph and I'm
23:47going to create a function so add
23:50function here I'm going to call it
23:51update
23:52Health
23:55percentage and I'm going to also add two
23:58variables here so I'm going to add a Max
24:01Health which is a
24:04float and I'm going to add a current
24:08health uh and make sure to um well you
24:11can also add just a percentage uh and
24:14calculate that and pass it in or you can
24:15add Max health and current health and
24:17calculate it here it doesn't really
24:18matter uh so I'm going to get this
24:20current
24:21health I'm going to divide it by the max
24:26health
24:28uh and that gives me a
24:30percentage and then I'm going to get my
24:32progress bar which is a variable so if
24:34you clicked is variable you'll have
24:36access to it
24:37here and I'm going to set
24:43percent and I'm going to pass in this
24:47value so now anytime I call um update
24:52Health oh sorry I added these on uh
24:55variables uh to the widget these should
24:58be variables of the function sorry not
24:59the widget so delete them uh this should
25:03be variables on the function
25:06itself um max
25:10Health
25:15float and
25:17current
25:19health so current health divided by Max
25:22health and you can switch the order if
25:25you want them to look better yeah
25:28all right so uh now anytime I call this
25:30function and I give a current health and
25:32a Max Health uh we will change the value
25:34of the progress
25:36bar um so in the boss when we first
25:40spawn the boss let's stop using the old
25:43health bar so I'm going to get the
25:44health bar here and I'm going to say set
25:48widgets and I'm going to keep the widget
25:50empty so this just pretty much deletes
25:53the widget that's inside here and then
25:56I'm going to create a new widget
25:59um actually no I'm not going to I'm not
26:01going to do it here and I'll tell you
26:03why just in a second let's first
26:05actually get the um health bar to appear
26:09in our player HUD because right now of
26:11course if I play um there's uh nothing
26:13here right so if I go to my uh what's it
26:17called it's actually in this folder yeah
26:19this player HUD
26:21here what I can do is I can reserve
26:23space or put a container in my player
26:26HUD uh that I can inject elements into
26:29at runtime because of course you want to
26:31add this health bar when the fight
26:33starts and remove it when the fight ends
26:35and so on so what I can do here is I can
26:37search for vertical box and I'm just
26:40going to add it here Anchor It To The
26:43Top Center reset these
26:47values um and the size here is going to
26:50be relatively important so um this is
26:53scaled to Let's actually scale it to um
26:579 1920 by 1080 just as a
27:01preview and then the size of this let's
27:03do this at 0.5 so it's aligned to the
27:06center and the position y let's give
27:09some Breathing Room of 50 so here how
27:12much did we give here we gave 50 yeah so
27:13we get 50 and then the size on the X um
27:17I will make it half of the screen so if
27:20the screen is
27:221920 um then I'm going to divide that by
27:24two and by the way you can do quick math
27:26functions here and will calculate them
27:28for you yeah so it will be
27:31960 um and now you can add stuff in this
27:35vertical box so I'm going to make it a
27:37variable and I'm going to call it top
27:39vertical box and you can keep adding
27:42elements and vertical box just Stacks
27:44elements on top of each other vertically
27:47um so just as a preview if I take this
27:49and pop it in here then you can see uh
27:52the boss fight and the health bar
27:56appeared
27:58and if we play here and we scale our
28:02screen then this widget scales as well
28:05with the screen so it's nice way of
28:07doing it but I think it's a bit too big
28:09this this health bar isn't it uh so
28:12maybe let's scale this uh down a bit
28:15this
28:16size uh maybe
28:1930 25 is 25 good yeah 25 is all
28:25right okay and I think also text here is
28:28a bit big let's make it
28:3228 yeah that's
28:35better all right um and of course you
28:38can change the value of this if you feel
28:39it's too small you want it to be bigger
28:41you can make this vertical box I don't
28:42know something like uh 1,100 something
28:45like that yeah now uh I will delete this
28:48because we're adding it here manually we
28:50want to add it when the fight starts
28:53right so um when the fight
28:58starts we want to where is our health
29:02bar uh sorry where's our boss so our
29:05boss here will create the widgets but
29:08the AI controller will add the widget to
29:11the player HUD so the pawn is
29:14responsible for creating the widget
29:16element because the pawn knows about
29:18their health their current health and so
29:19on but the AI controller is the one that
29:21knows when the fight begins right
29:23because we have our uh AI controller
29:26here uh that handle sense damage handle
29:29sense sight sets state to uh attacking
29:33and so on so the AI controller is
29:35responsible for what happens when the
29:37fight begins so that means that if you
29:39want the HUD to be added sorry the
29:42widget to be added to the HUD when the
29:43fight begins then the AI controller is
29:45responsible for that so let's first
29:48create this widget so we're going to
29:51create
29:53widget um boss health bar and we're
29:57going to promote it to a variable and
29:58call it um boss health bar widget ref or
30:04something and then very important is we
30:06want to set the initial values of our
30:09health bar so first call update Health
30:13percentage uh with our health and Max
30:15Health which are stored in the damage
30:17system so get a damage
30:19system uh get
30:22health get Max
30:25Health you can just call the variables
30:27not the
30:28functions
30:30uhhuh and then plop them in here you can
30:33of course call the functions as well
30:34that you have on your interface but this
30:35is just cleaner and easier since we
30:38already have access to
30:40this all right so now that we have this
30:42widget uh in our AI controller when the
30:46fight starts we want
30:48to um add this widget to the players HUD
30:51if we're attacking a player now of
30:54course I can do it here in this set
30:55State as attacking and in the end do do
30:57it but this is only relevant for the
30:59boss and this AI controller all of the
31:01enemies use so since uh this is a base
31:06AI controller uh we can inherit from it
31:09and create a child uh and this is again
31:12a very good use of
31:13inheritance uh so I can just right click
31:16on this and create a child blueprint and
31:18call it AIC enemy
31:21boss and if you open it up it won't have
31:24anything but it does have everything
31:26that is already in the base AI
31:28controller um so now if I want to do
31:31something on set State as attacking I
31:34can go over here to functions oh sorry
31:37don't create a new function uh go to
31:39override and search for set State as
31:42attacking now if you override it you'll
31:44see that it automatically calls the
31:46parent which means do whatever the
31:48parent is doing which is the base AI
31:50controller and then after that we'll do
31:52something else so we'll
31:55check um are we we attacking so if this
31:59attack Target is equal to our
32:03player is this attack Target equal to
32:06our oh sorry branch is equal to our
32:11player on true then we get the health
32:14bar of our boss so our boss again um we
32:18don't have a reference to it yet so we
32:20need to call get controlled pawn and
32:24then cast that pawn to a boss and we'll
32:27be applying this AI controller only to
32:29the boss so we know that this will
32:31always succeed uh and then we get our
32:34health bar widget ref so our boss health
32:37bar widget ref and then we want to add
32:40it to the
32:41players uh HUD right and we already
32:44checked that this attack Target is equal
32:46to a player so again what we can do is
32:49get this attack Target and cast to BP
32:53player Actually I don't even need to
32:55check if this is equal to player I can
32:56just C cast to player right away that is
33:00actually
33:01easier so cast to player if the cast
33:03succeeds then get the boss and then um
33:07get a reference to the HUD so get player
33:10HUD ref this is a variable that we have
33:12stored on the
33:14player um and this HUD now if you recall
33:18we added the vertical box to it and it's
33:20just called top vertical box and it is a
33:22variable so we can get it so we can say
33:24get top vertical box
33:29and this top vertical box has a function
33:33called uh ADD child was it add child to
33:38Vertical
33:42box and this ADD child to Vertical box
33:44takes a widget as a
33:48reference great um one slight
33:52optimization we can do is uh right now
33:55this is going to be called on every set
33:57state is attacking U oh we need to pass
33:59this target um but if we add it once we
34:03don't need to keep calling it again
34:05because maybe something happens the
34:07state doesn't go back to attacking so we
34:09can do this once so we can say do this
34:13only
34:15once all right but there's a problem now
34:18if uh we do it once and the turns out
34:21that the attack Target is not the player
34:23if for any reason you have the boss
34:24attacking someone that's not the player
34:27uh then you want to reset this new once
34:30so you can just plug the cast failed
34:32here to
34:34reset and just to make it a bit clean
34:36just do a reroute node
34:40and yeah to make it visually
34:43clear
34:46okay all right so now as soon as the
34:48boss starts attacking um it will uh add
34:52the uh health bar to the player HUD but
34:55we need to of course assign this AI
34:57controller so go over here to class
34:59default search for AI controller and
35:02change this from enemy base to enemy
35:05boss oh no enemy boss
35:08yeah all right so right now there's
35:12nothing in the player HUD okay and I can
35:14show you by starting here behind the
35:17boss nothing in the HUD now if the boss
35:20sees me boom they set state to attacking
35:24and the HUD appears great and now of
35:27course the boss isn't doing anything yet
35:29because they don't have a behavior tree
35:33so let's start um adding some Behavior
35:35to our boss now right now if I just
35:38search for Behavior tree if I just give
35:41him the melee Behavior tree uh if I do
35:43that um he's already going to start
35:45doing some things so he's going to start
35:48moving uh and he equipped the weapon
35:50because that's also part of the behavior
35:52tree and now he's um strafing around me
35:55uh but he doesn't have an attack so he's
35:57not going to attack he's just going to
35:58stay forever but he does a hit reaction
36:00because we added that hit reaction
36:04Montage um so all that is pretty good oh
36:07one very important thing I forgot you
36:09see now the health of the boss isn't
36:11changing uh even though he's getting
36:13attacked uh this is the part that's also
36:15really important relating to the health
36:17bar we only call update Health
36:19percentage once um on uh when we create
36:23the widget we also want to call it every
36:25time the boss gets damaged D so we go
36:28over here to our take damage
36:30function uh we can just also go for
36:33override search for take
36:35damage uh it's the same as double
36:37clicking this and we're going to add a
36:40call to the parent so do whatever the
36:42parent does in the take damage function
36:45return everything they return but
36:47additionally call update Health
36:49percentage I just copied this from our
36:52begin
36:54play all right well I have an error
36:59here oh I should be calling this on our
37:04boss health bar widget not ourself yeah
37:09okay compile so now if I attack the boss
37:12yeah now the widget is
37:14updating great so this is another way to
37:17uh update the uh widget's Health uh and
37:20it's a bit more performance because now
37:21we only update it when we take damage
37:24whereas with the um binded approach it
37:28just uh calls on tick to see if a value
37:31has changed so this is a bit more better
37:33for
37:34performance all right so now we see that
37:36the boss using the M melee Behavior tree
37:39has some functionality but let's create
37:41our boss Behavior tree and let's uh
37:45close up some of these
37:47things all right so going to our AI
Creating boss behavior tree
37:51folder Behavior trees I'm just going to
37:53copy the melee Behavior tree to start
37:55with that and call it enemy
38:00boss all right and I'm going to
38:04delete pretty much everything here we
38:07don't want strafing all the possible
38:08attacks are going to be
38:11different
38:15um possible
38:17attacks yeah we're going to add that in
38:19a bit so is wielding swords yeah we
38:23probably want to we should probably
38:24rename this to is wielding weapon cuz
38:26it's checks for weapon not
38:29sword well why can't I
38:33delete is wielding
38:36weapon uh so we're going to keep this so
38:39we check if is wielding weapon we focus
38:41the Target and equip a weapon um and
38:45then once the attacking state starts uh
38:48we just want to have a sequence
38:52called attack ready where we
38:57set the movement speed to
39:01sprinting and
39:04focus the attack
39:08Target all right and then we're going to
39:10check all the other things uh later but
39:12first let's see here so we want the
39:15Frozen State uh we don't want the
39:17investigating State and we don't want
39:19the seeking state so we're going to
39:21delete these but we'll keep the passive
39:25um so the boss doesn't investigate and
39:27doesn't seek that means that we have to
39:28make sure that the boss doesn't ever go
39:31into these uh States and that's also
39:33another reason why uh it's good to
39:36override the AI controller so if we go
39:38to our boss AI controller uh what we can
39:41do here is go to our functions and say
39:44uh
39:46handle uh what was it handle lost sight
39:49so I can override this function handle
39:51lost site and delete the parent so I'm
39:56not doing doing anything on handle lost
39:57site we can comment here say
40:01override to do
40:03nothing so this means that if you lose
40:06sight H don't do anything previously of
40:08course if you lose sight um you go to
40:10the um uh seeking state so if the handle
40:14lost sight here H you check did you lose
40:16sight of your attack Target then wait a
40:18bit and go to the um seeking state so
40:21we're not going to do that so now let's
First melee combo attack
40:24actually start adding some attacks to
40:26our boss to have them move around and
40:28attack us um so if I go over here to my
40:32animations folder axe um I already have
40:36uh a montage uh ready to use this
40:38Montage axe combo one uh now we've
40:41created so many attacks throughout this
40:44series so I don't have to bore you by
40:46creating another Montage but I'm going
40:47to explain it really quickly uh it's
40:49just this axe combo animation that I got
40:51from mixo and retargeted to the uh u5
40:55skeleton and and I play this Trail
40:58effect from the Infinity Blade asset uh
41:00but I modified it to be red cuz the boss
41:03is red so their Trail effect should be r
41:05as well and we have this ax swing
41:09sound and we have a slash uh notify
41:13Montage uh sorry Montage notify so this
41:17combo is just two hits one and two great
41:22so let's see how we can use it so over
41:24here in our uh BP
41:27enemy um let's comment this call it
41:31equip SL
41:35unequip
41:37weapon and let's comment this and call
41:40it
41:41health bar all right so now let's create
41:45a new attack so custom event I'm going
41:48to call this um
41:50combo attack combo
41:54one okay
41:56um and I call it combo one because we're
41:58going to have two different combo
42:00attacks and as always the attack takes a
42:04attack
42:06Target which is a um
42:12actor and if you recall again just a
42:14quick recap um
42:17our uh not here our melee enemy or
42:23really any enemy uh we use our bpc
42:25attack system and we have a whole bunch
42:27of attacks already created for us so we
42:29just have to call the bpc attacks get
42:32the attack that we want to do and pass
42:34in the attack info and damage so we're
42:36going to be doing that for most of the
42:37boss attacks but we're also going to be
42:39creating new attacks to make it bit more
42:42interesting um so get our bpc attacks
42:46and we're just going to call primary
42:48melee attack and again just to refresher
42:51primary melee attack has one Montage
42:54notify uh which is is slash that's why I
42:57have slash here in this uh
43:01Montage um right so back
43:05here uh we want to get uh sorry make
43:10attack
43:11info pass in the attack Target and the
43:14Montage will be our combo
43:16one uh radius uh let's say a bit bigger
43:20because of the axe has a larger radius
43:22let's say 40 and length a bit further
43:24away let's say something like 250 or 300
43:28something like that and then damage info
43:31also make and say it does 20 damage of
43:34type
43:36melee for now let's say it can be
43:38blocked and can be
43:41parried um shouldn't damage Invincible
43:43shouldn't Force interrupt and damage
43:45response now the player responds to any
43:47damage but yeah let's do it hit reaction
43:49for
43:51now all
43:54right so as as always if we want to call
43:57this from our Behavior tree uh we need
43:59to create an enum of attacks and then
44:02create a task in the behavior tree that
44:04calls one of the attacks from this enum
44:06um so search for
44:10enumeration enum come
44:13on and we're going to call it eore boss
44:19attacks and for now let's just add one
44:22call it combo one we're going to add a
44:25lot more
44:27so if we want to do this attack in our
44:29uh boss uh Behavior
44:32tree um we first need to create a task
44:35for it so new task blueprint base in our
44:39tasks
44:41folder
44:43um yeah I'm going to call it BTT boss
44:48attack all right so as always event
44:51receive execute
44:53AI um and what we're going to do is just
44:56get our Pawn cast it to boss because we
45:01know this is only going to be called for
45:03the boss and based on the attack name
45:06that we pass into to this attack we want
45:08to to choose one of the attacks again
45:10same as we did for the melee and Mage
45:11enemies so we're going to add a variable
45:13called attack
45:15name and it's going to be of Type
45:20e boss attacks where is it e melee
45:24attacks no what did we call it
45:27eboss attacks
45:30yeah and make sure to click the I icon
45:33that way you can pass in this variable
45:35from the um Behavior tree and we also
45:38need our attack Target
45:41key which is of type Blackboard key
45:46selector and again also click the IE
45:49icon So based on this name so we can do
45:52a switch on this name and based on what
45:56happens of course we now only have one
45:58but we're going to have a lot in the
45:59future so I'm going to move this to a
46:01separate function like we did for the
46:02Mage and call it attack based on name
46:07and it just takes our boss ref so we
46:11don't have to cast again here uh we can
46:13just get a reference to our
46:16boss which is of type BP enemy
46:20boss and then we get our attack
46:23name do a switch
46:27and based on the name we're going to
46:29call combo one if it's combo one and the
46:33attack Target we're going to get our key
46:36get value as actor as always get
46:39Blackboard value as actor and pass it in
46:43here all right so now but we're still in
46:46the uh task so we're going to go over
46:49here and call attack based on name pass
46:51in our boss and once we're done we want
46:55to bind on the event that attack is
46:57ended so assign on attack end again as a
47:01reminder this is an event that we call
47:04when the attack montage is finished so
47:06that we know we can call Finish execute
47:11and success true and this is what exits
47:13the behavior tree task again very
47:15important that success is
47:18true all right again this is I could
47:21have copied and pasted one of the Mage
47:23and enemy attacks and the only
47:24difference is the cast
47:26um but I wanted to do it again in case
47:28someone hasn't been
47:29following and now if I go over here to
47:32possible attacks I can just do boss
47:35attack attack name combo one attack
47:38target attack
47:40Target so let's see if he's going to
47:42attack me
47:44now and he is oh we did not he's still
47:47strafing we didn't assign the boss
47:49Behavior tree to the boss enemy so click
47:52on self or on class default search for
47:55Behavior tree and assign the boss
47:59Behavior tree all
48:02right yep now he's attacking and I think
48:05the yeah the range is all right yeah I
48:10think it's a bit too far he's attacking
48:12me even when I'm too far so I can block
48:16it and I can Parry
48:19it
48:21perfect um so I'm just going to decrease
48:23the length a bit maybe to to to 20 or
48:29something all right so now we have our
48:32first uh attack all right so one very
48:35important thing to note is the reason
48:37why this attack is uh uh this whole
48:40combo is one montage is to tie it back
48:43to rule number two it's predictable but
48:46challenging so whenever the boss does
48:49this attack I know that there's going to
48:50be a second one to follow so I can time
48:53my block uh to uh to the second attack
48:57so this is a predictable pattern that I
49:00know is always going to
49:01happen um but uh now there's one thing I
Prevent interrupts from behavior tree
49:05want to show you is that while the boss
49:06is doing this
49:08attack uh let me just move this
49:10way I can interrupt
49:13them see
49:15that so this is because this primary
49:18melee attack isn't doesn't set um the
49:22state to not interruptable and like some
49:25other attacks do now I don't want to I
49:28want this attack not to be interruptible
49:30but I don't want to modify the attack
49:32itself because maybe some for some
49:33enemies it's interruptible for some it's
49:35not so I want actually uh this is
49:38interruptible to be part of the behavior
49:40tree so I want the behavior tree to
49:42decide that when I start doing this
49:43attack I'm not interruptible and for
49:46most of the boss attacks the boss won't
49:48be interruptible during his attacks so
49:51let's create a task that does that and
49:53it's going to be a very simple task um
49:57so we just go to blueprint base again um
50:00and this task anyone can use it's not
50:02just a boss attack um it's just sorry
50:05not just a boss task so we're going to
50:06call it BTT set is
50:11interruptable all right and then event
50:14receive execute
50:17AI we're going to get the pawn and we're
50:20going to just say set is interruptable
50:22and again this is a function we already
50:24have in our BP damageable
50:27interface um and then we say finish
50:31execute very simple task uh we just need
50:34to pass in the value so this value is
50:36going to be a variable so right click
50:38promote the variable and yeah we can
50:40just call it value make sure to click
50:42the I icon
50:44again um so now back in my behavior tree
50:49what I can do is uh let's create a
50:52sequence here call it um combo
50:57one
50:59sequence and what the sequence looks
51:01like is first um focus so we're going to
51:06focus the attack
51:08Target then we're going to set is
51:11interruptible to false so I can't be
51:14interrupted so regardless of what this
51:16attack does I'm not
51:19interruptible and then do the attack
51:21once I'm done set is interruptible back
51:24to true so now I can be interrupted
51:27again and I don't know maybe just wait
51:31for a second stand still usually what
51:34happens in boss fights is that um after
51:37an attack is over this is your chance to
51:38attack so this weight time the more the
51:41longer it is the easier the fight will
51:43be the the shorter it is the harder the
51:46fight will be so maybe as the fight
51:48progresses you change this weight value
51:51um and this again ties to the last rule
51:53about difficulty as the fight progresses
51:56the uh it should be more challenging so
51:58you're giving the player less time to
52:02attack um all right so now if we play
52:04the boss focuses me and I can't
Stagger boss only on some parries
52:07interrupt him let's try interrupting
52:10him nope he continued his attack again
52:14let me show you again didn't get
52:16interrupted great but I can still parry
52:19and interrupt him right because parrying
52:23staggers um the enemy all the time so we
52:27have in our BP
52:31player uh in our Parry yeah here we have
52:37once we Parry uh we get our attack
52:39Target and we say should force interrupt
52:42so even if they're not interruptable
52:43this is part of the damage system this
52:45should force interrupt will make them
52:47get interrupted uh and this is perfect
52:50for regular enemies but again uh tying
52:53it back to the rule about um that the
52:56boss enemy should be stronger and the
52:58boss enemy reacts differently to the
53:00player we want to change this a bit so
53:03maybe we don't stagger the boss all the
53:05time maybe they get staggered um at a
53:09certain percentage so maybe 50% of the
53:11time 20% of the time whatever usually
53:13what most games do is they have a
53:15stagger meter for strong enemies so you
53:18have to block or you have to Parry them
53:19multiple times for them to be staggered
53:21and every time you parry this meter
53:23decreases I'm not going to implement a
53:25meter instead I'm just going to do it
53:27based on random chance so maybe 50% of
53:30the time they get staggered and 50% of
53:31the time they don't so how do we do that
53:34quite simple actually here in this
53:37should force interrupt I'm going to have
53:39it true 50% of the time and false the
53:42other 50% of the time and why am I doing
53:45should force interrupt um instead of
53:47stagger because the boss is not
53:51interruptible so when we Parry the boss
53:53we force interrupt and that's why they
53:55get staggered but if we didn't say Force
53:59interrupt but we still
54:01Parry see I'm parrying but the boss
54:04isn't getting
54:06interrupted and this is good because we
54:09you don't want to change the player the
54:11the behavior the player is used to the
54:13player knows they pared so we should
54:15still give them the visual feedback that
54:17their Parry was successful but the boss
54:19is the one that reacted differently to
54:21it so that's why this should force
54:23interrupt is what we're going to change
54:25so how do we do it based on chance quite
54:27easy actually I'm going to create a
54:28function
54:29here um in our player and call it
54:33[Music]
54:34um yeah
54:36just
54:38random
54:41chance uh and we're going to add a
54:43variable called the
54:46percentage or percent and that's going
54:48to be a float and we can even um um yeah
54:52limit it to be um this is a value
54:54between 0 0 and one this float
54:57value um so we're going to check we're
55:00going to get a random float in range
55:04this function generates a random float
55:06between 0o and one and we're going to
55:09check is our
55:12percentage uh greater than or
55:16equal this random
55:18float and if true we're just going to
55:24return
55:27oh return this value and we're just
55:29going to call it yeah return value is
55:31fine so again we generate a random
55:33number between zero and one and if the
55:36number that we are passing here is
55:38greater than that a random number then
55:40return true so for
55:42example back here oh and I can also
55:46click on this uh function and say pure
55:49that means it doesn't need an execution
55:50pin so if I call this function here you
55:53see it doesn't need an execution pin
55:55like this so I pass in a 5% chance and
56:01pl plug it in here so this means that
56:04I'm going to generate a random number
56:05and if this number is less than uh 0.5
56:09then don't force interrupt if it's more
56:11than 0.5 do Force interrupt and since
56:14it's a random number U between zero and
56:16one then it's a 50% chance so let's see
56:19how this looks like in
56:21practice Parry nothing happened let's
56:24try again
56:27Parry nothing happened one more
56:31time staggered great so you see that
56:34sometimes it'll get staggered sometimes
56:35it won't and this is a great way to U
56:38make sure that the boss feel stronger
56:40they don't usually react the same way to
56:43uh attacks as the enemy as the other
56:45enemies do all right next thing we want
Moving block functionality to base enemy
56:47to do is giving the boss ability to
56:49block because again bosses should be
56:51powerful so we want to make sure that uh
56:54they're able to to block our attacks as
56:56well uh right now let me unplug this so
57:00right now if I attack the boss they just
57:02sit there and take damage they do a hit
57:05reaction every time they they really
57:07can't um can't do anything so I'm going
57:09to add a chance uh or add sorry a um uh
57:13the block that we have for the melee
57:15enemy I'm going to move it to our base
57:17enemy and have any um uh enemy be able
57:20to block if they have a block Montage so
57:24let's see how we can do
57:26that um if I go to our BP melee
57:31enemy yeah this is our block so we have
57:34this start block event we have um un
57:38unsuccessfully blocked what to do and
57:40and block and we have this uh try to
57:43block uh function which again based on a
57:46random
57:47float um and a block chance it will
57:50either call start block or do nothing so
57:52we're going to copy all of this to our
57:54base enemy so let's open our BP enemy
57:59base and let's start doing some
58:04modifications so let's first copy um
58:09yeah it doesn't really matter let's copy
58:11all of
58:12this to our enemy base put it somewhere
58:16here it's going to ask you what to do
58:19about functions that don't exist just
58:20say do
58:22nothing uh because they're about to
58:24exist soon
58:25um so end block here if you just refresh
58:27it um it's there um this block State we
58:32don't really use anymore we were using
58:34it before but we don't need it so I'm
58:35going to delete it delete
58:39it um and everything else that is grayed
58:43out you can just say um let me show
58:48you so for example this hold block timer
58:51I can just say right click and create
58:53the variable it will create the variable
58:55for it and blocking State again we don't
58:58need it
58:59here um we don't have these unblock
59:03ended uh
59:05and yeah so if I compile it's going to
59:07complain about yeah unblock ended so
59:11let's create that event
59:14dispatcher
59:16on block ended now if I
59:20compile everyone's happy so I should go
59:23back to the melee and delete delete all
59:25of
59:26this right now that the this is deleted
59:30from the melee if I go to the try to
59:32block function you see that this one now
59:33says Target is BP enemy base that means
59:36this is reading the start block from the
59:38enemy
59:40base now we want to copy this as well so
59:43take our Tri block you can just click
59:46here by the way
59:47copy go here and
59:51paste and then delete it from our melee
59:56enemy uh are you sure you want to delete
59:58it where is it being used actually
1:00:01before I delete it find references oh
1:00:03it's used in the take damage yes so I'm
1:00:05going to say yes I am sure I want to
1:00:07delete
1:00:09it and now it says it's taking Tri block
1:00:12from the enemy base so if I compile it's
1:00:16just going to say warning cuz I haven't
1:00:18compile this
1:00:19one oh and block chance this is what's
1:00:22the percentage uh that they can block so
1:00:25I'm going to also create variable for it
1:00:28compile now everyone's happy and let's
1:00:30say block chance defaults at
1:00:340.25 and this can be changed per enemy
1:00:36so maybe the boss has a higher one melee
1:00:38enemy has a lower one and so
1:00:40on um so back here in our melee if I
1:00:45compile now the warning is gone but
1:00:47there's one very important thing that we
1:00:49still need to do which is this Montage
1:00:52so now this always plays the sword block
1:00:55Montage but every enemy can block
1:00:57differently maybe the Mage enemy blocks
1:00:59with a magical Shield the and boss of
1:01:02course blocks with an axe and so on so
1:01:04then this Montage should be a variable
1:01:06as well so promote the variable and call
1:01:08it the block
1:01:12Montage great now our block function is
1:01:15successfully moved to our base enemy and
1:01:17configurable so if I go here to my melee
1:01:20enemy I have a block chance that I can
1:01:23change for this enemy specifically and
1:01:26over here I have the block Montage which
1:01:30well defaulted to um stored block
1:01:33reacts and I can go to my boss
1:01:38now um if you want you can also change
1:01:41the um block chance uh of your boss to
1:01:45be higher I'm going to keep it at
1:01:470.25 uh and the block montage I'm going
1:01:50to change it to ax was it react act yeah
1:01:55axe block
1:01:57react which looks like this just plays a
1:02:00sound and has a muzzle
1:02:02flash all right so let's start attacking
1:02:05our boss and see if he blocks oh wait we
1:02:07forgot one very important
1:02:09thing uh right now in our melee enemy we
1:02:13call this triy block on take damage we
1:02:16also want to move this call to the base
1:02:18enemy so this all I'm going to cut it
1:02:28and then these we don't really need
1:02:30anymore oh and my cat is in the
1:02:33way excuse
1:02:38me and we're going to move all of this
1:02:41um to the base so that actually means
1:02:44that the melee enemy doesn't need to
1:02:45override uh this function at all so I
1:02:48can just search for take damage and
1:02:51delete it and as soon as you delete it
1:02:53then it's the um base enemy take damage
1:02:56that will be called and there are also a
1:02:59few things that so you you see here
1:03:01these are the old uh variables the block
1:03:03chance the block timer so we need to
1:03:04also delete these and blocking State
1:03:07blocking timer yeah and then these ones
1:03:10we can't delete of course because
1:03:11they're from the base enemy and I'm now
1:03:13in the melee
1:03:15enemy all right so back in the base
1:03:17enemy in our take damage function let's
1:03:21add the things that we just copied from
1:03:23here
1:03:26which just checks um if the attack
1:03:29itself can be blocked if it's true try
1:03:31to block if it's false then proceed to
1:03:35do take damage without trying to
1:03:41block all right and that should do it
1:03:44now let's try to see if he
1:03:46blocks come on block me what did we set
1:03:49it at 25% yeah there we go okay so out
1:03:53of one out of four hits should be
1:03:56blocked sounds
1:03:58good perfect now before I end this I
1:04:02want to show you one thing that I added
1:04:04in the um player itself I'm not going to
1:04:09uh uh go over how I created it but I
1:04:12just want to show you that I added a uh
1:04:14Dodge or a vade that looks like
1:04:17this so if I press alt I can
1:04:21now um sort of do this uh quick tell
1:04:24tort to avoid attacks uh and the reason
1:04:27I did this is to make the fight a bit
1:04:29more Dynamic uh and if you want to see
1:04:32the code itself you can take a
1:04:34screenshot or pause the video and this
1:04:36is what it looks like um I'm not going
1:04:38to it's it's not very difficult it's
1:04:40just teleporting from one location to
1:04:41another um it's really quite basic and
1:04:44it's using an um effects from the Fang
1:04:48ma which is a paragon uh
1:04:51character um so again if you want to
1:04:53recreate yourself
1:04:54um you can just copy this code uh pause
1:04:57the video and um copy what you see on
1:04:59screen
1:05:01here uh but this is basically um all of
Next up in part 21
1:05:04it all right now that we've set up our
1:05:07boss and he can attack and block in the
1:05:09next part we will start adding the cool
1:05:11new flashy abilities and attacks which
1:05:14use the arena and much more uh and then
1:05:17finally we will put all of these attacks
1:05:19and abilities together to build the
1:05:21complete boss fight so I hope you
1:05:24enjoyed and I'll see you
1:05:26[Music]
1:05:40there