Hello guys.
Welcome to the next video.
So first of all I noticed something from the last video.
So let's go quickly and fix what I noticed.
Uh, we doing this thing with a collider because we have different colliders on different enemies,
possibly in the future, but I just realized that we can just make a variable of a collider 2D, and
it will assign collider it has on the object.
So let's quickly do here protected Collider 2D.
I'm going to call it CD.
Then in the awake I'm going to do CD equals to get component of a collider.
Should we name it as like coal?
All later we are a bit better.
And then over here we can do call enabled equals to false.
And thanks to this, we don't need to go to enemy mushroom and do override over die method.
And also we don't need this awake and this variable over here.
Very cool.
Now let's develop a new enemy.
So what we're going to make in this video is this chicken enemy.
We have a great reference.
We can see how does it work.
And it's basically going to run into direction of a player and then stop if it does not see the player
something like that.
Let's go to the unity and let's set up GameObject and animations first.
Uh, actually, before we do that, let's make a prefab out of a mushroom.
We're going to go to prefabs.
I think it's time to hide these traps inside of a folder.
So I'm going to make one.
Traps.
Let's take the traps.
Place them.
Place them into the folder.
Then let's make folder for VFX.
Let's take the particle and players effect.
Place it here.
Cool.
Now we can take the mushroom, make it as a prefab and I think we can move mushroom over here so it
does not bother us much.
Also, I want to change the level a bit.
So I'm going to remove fruits and I want to erase this piece of ground over here because I want to place
a.
Uh, Colin platform.
Like so, because I need a bit more space over here to jump over the enemies.
Okay, this is nice.
Now, maybe these spikes as well don't want to have it there.
Now let's make the enemy new one.
We're going to go to Graphics Enemies chicken.
Let's take this sprites over here and make sure we have pixel per unit 16.
Okay.
That's cool.
Now let's go ahead and make a game object.
This is going to be.
Enemy.
Let's do enemy.
Chicken.
We also need to change layer of the GameObject to the enemy.
Let's go ahead and add animator.
And we need animator controller so we could go ahead and make Animator controller a controller same
way as it was before.
And then I'm going to show you a nice trick to make your work faster.
First of all, let's make a folder for this.
So I'm going to do enemies.
And let's take these things over here.
Drag them to the enemies.
And over here I'm going to make a folder for the mushroom.
Mushroom I'm going to take animations drag them here.
Controller I'll keep outside for now.
Now let's make another one.
Animator controller.
Enemy chicken.
Take.
We can place it on the enemy and drag it here and now.
We can create animation same way as before.
Let's quickly do that.
All right.
We're going to do.
Uh, enemy chicken idol.
Then I go to graphics of the chicken.
Let's take idle sprites.
Place them here.
Sample rate 20.
Then we're going to need new clip enemy chicken.
Move.
This is the move animation over here.
Boom!
Sample rate 20 and enemy chicken hit.
Okay.
Sample rate 20.
Now, if you go to animator of the chicken, you probably notice that these animations are very similar
to the animations that we had on the mushroom, and it would be very nice to take set up of the mushroom
and just move it to the enemy chicken and somehow replace the animations.
But keep parameters, keep conditions, everything.
And there is a way to do that.
We can go to assets, animations, enemies and over here I'm going to delete this enemy chicken AC.
Let's just delete it and I'm going to make.
New Animator override controller.
Let's name it as Enemy Chicken AC.
And this controller will help you to basically use setup of a mushroom with new animations.
First you want to set up the base over here where it says none.
So we're going to take Enemy mushroom AC and drag it here.
Then we can see default animations.
It says original over here and if you want you can place override for each animation.
So for example we can place heat of the chicken idol of the chicken and move of the chicken.
Thanks to this, now we can select enemy chicken and drag this override controller over here to the
controller field.
POW!
And now chicken has same conditions as mushroom head.
Uh, but and same parameters that mushroom had.
But it's using its own animations.
You can just go here and change the name from enemy mushroom to enemy hit.
Oh, again, this bug.
Can you imagine?
I need to restart unity.
I'm going to do it quick.
So now enemy hit.
Yeah, it's a bit easier to understand now.
And it has same setup of the animations.
Very good.
Now let's set up.
The movement of the chicken.
We just need to have a rigid body on it.
Rigid body 2D.
Let's do interpolate collision detection continuous.
Then we need a box collider 2D.
And I just realized we don't need to adjust the size of the collider according to the damage area of
the enemy, because player does not collide with enemies layer, so you can keep it as it is.
This is good and we can add new empty object damage trigger that would have maybe a capsule collider.
It's very suitable for this enemy.
Let's open this and edit the size.
Yeah.
Like that.
It's okay, I think.
Should be fine.
Let's do is trigger and give it damage trigger.
Nice.
And we need empty object ground check that is going to be used later.
Now we need a script on this game object.
Let's go to scripts and let's make new C sharp script.
Enemy.
Chicken.
Okay.
Very cool anime chicken.
Now for the anime chicken.
It's supposed to behave in a very similar way that mushroom does.
And just to make sure it's working, I'm going to inherit from the enemy like so.
And I'm going to take entire script of the enemy mushroom.
And just paste it in here.
Let me save it and let's go back.
Let's go to play mode.
Oh, sorry.
We need to set up a bunch of things I forgot.
We need to place the script on the object.
We need to give it.
What is ground?
The ground check damage trigger.
And probably we need to increase wall check distance because collider for the chicken is bigger.
I think I can just.
Slightly reduce the size of a collider here.
Other than that.
This is good.
Yeah.
So now we just basically did the same setup as we did for mushroom, but much, much faster because
we have inheritance animator, override controller and so on.
And we can see chicken runs.
Oh, almost as it runs before like a mushroom.
What happened there?
Why she didn't stop.
And when she didn't flip.
Oh, because I know why.
Because I didn't take this brown check.
It did not place it in front of the chicken like so.
Okay.
Let me give it speed over five and test it again.
Very fast enemy.
Runs like a mushroom.
Nice.
Yay!
Now let's improve it.
Let's make it a bit different functionality from the mushroom.
As you've seen on the example.
On the reference, we have chicken stands there and not moving until it detects the player.
Once it's detecting the player, it runs into the player.
And that's what I want to set up in this video.
How can we set up the player?
Well we're going to need an additional, uh, collision.
And I'm going to make a header.
Chicken.
Uh, details.
And it's going to have sterilized field, private float, agro duration.
And we're going to need private float agro timer.
Nice.
We also need sterilized field.
Private.
Private bool player detected and we need serialize field.
Oh, I'm so sorry.
We need private float.
Um.
Detection range.
And we need serialize field.
Private float.
Uh.
Actually, we need layer mask.
Layer mask.
What is player?
Now I assume that what is player will be needed for other enemies as well for different reasons.
And also we're going to need a boolean that says if enemy can move or not.
So I'm going to remove it from here.
Going to go to enemy.
Let me find collision checks over here and I'm going to do.
Serialized field.
Private layer.
Mask.
Sorry.
Protected.
Layer mask.
What is player?
Because it's going to be used by many enemies, I'm sure.
And we need a boolean that would say if we can move.
So maybe under the move speed I'm going to do protected bool can move.
Uh, yeah.
Let's make it true by default.
Okay.
Yeah.
Nice.
So we have a boolean can move and we have what is player.
Now let's go back to enemy chicken.
Oh wait a second.
We want to use the gizmos on the chicken with a new gizmo line.
So let's go here and make it as protected virtual void.
Nice.
Now let's go back to enemy chicken.
One of the things I want to do is to override handle collision.
So I'm going to do override handle collision.
And in here we're going to do player detected equals to physics 2D raycast from a transform position
into vector two dot.
Dot right?
Multiply it by facing direction with a detection range.
And what is player layer.
And we need to override.
What is happening?
And we need to override Ondraw gizmos, override on draw gizmos.
And we need gizmo for this line.
For this raycast I'm going to go ahead pick definition and I want to take the third line which does
the wall check.
And instead of using wheelchair distance, I'm going to use detection range.
And I then need to type this again.
I have very similar line of code.
Nice.
So now this will detect the player if we want to.
And.
On the handle movement instead of idle timer we actually want to use can move boolean and if it's a
false then we return.
We do not move.
Super good.
Now when do we make can move true.
Well, in the update we can check if player detected then can move equals to true.
And also it would be a good idea to set timer of the aggression to a positive value once we detect the
player.
So I'm going to do aggro timer.
Equals to aggro duration.
And of course we need to reduce the timer.
So I'm going to do.
Uh, agro timer.
Minus equals times delta time.
All right.
Very good.
So half of the job done.
We have timer of the aggression that is decreasing all the time.
If player detected we say you can move and we enable aggro timer.
Then if aggro timer is less than zero means aggression has passed.
We did not detect player for a while.
And we're just going to do can move equals to false.
So if we did not detect player for a while, if we did not update aggro timer then we stop the movement.
Okay this is good.
Let's go and see what it does now.
Then we're going to improve the functionality on the enemy chicken.
We need to choose what is player, player and agro duration.
Let's set three seconds.
And detection range can be something like 15.
Cool.
I'm going to place this enemy over here, and I'm going to jump in front of her and see if she starts
running.
Uh, chicken stands.
Cool.
Hey.
Okay.
It runs to me.
Then it flips back because it did not see me and stops because aggression duration was over and she's
not aggressive anymore.
Very nice.
Um, I think it's a good idea to switch off the movement and aggression if it did not see the player,
and if it detected the ledge or the wall.
Let's go to enemy chicken.
And handle turnaround over here.
We're going to do this.
We're gonna flip and we're gonna say.
Can move.
And we're going to say can move equals to false.
Also, this chicken does not use idle timers, so I'm going to just remove it.
Okay, let's go ahead and see this.
Now.
How does it behave?
Stands.
They're gonna make me visible.
Okay?
She tries to catch me, sees the ledge, stops and turns around.
Now, if I go back.
And show myself again.
Going to be aggressive.
And we can kill it.
All we need to stop the cycle of the animation.
Cool.
Let's go to asset animation.
Enemies.
Chicken.
Hit loop time and check.
Now, the last thing we need to do is to make it turn into direction of a player.
If player jumps over the chicken.
That's a bit tricky to do.
Uh, let's go back to the script.
And actually, this method is supposed to work like that, but it does not work like that.
We need to adjust the method, I guess.
So over here we need to check x value and compare it not to zero but to the transform position transform
position dot x.
Over here as well.
Transform position dot x.
So now if we pass players position over here it's going to be like that.
Players position less than my x position means player is on the left.
And if I'm facing right I'm going to flip.
Players position is oh sorry.
This one should be.
Instead of zero transform.position.x.
Okay.
And in this side we're going to check player's position is.
Bigger on the X than my position means player is on the right side and I'm facing right?
No?
Then flip.
This is how it's going to work.
Uh, let's go to enemy chicken.
Maybe in the Handal movement.
We can do this.
I'm going to do a handle flip.
And over here we need to pass player's X position.
But we don't have reference to the player yet.
So let's go to enemy script.
This is pretty messy.
I would like to clean it up, but I don't want to spend time on this right now, so we're going to do
it in the end for now.
This is good.
Let's just do it like so.
Maybe.
Couple of spaces.
And here we're going to have serialized field.
Protected transform player.
Nice.
Now we're going to go to the.
Start method.
We cannot do it in their wake, because our wake of the game manager can be called after the wake of
the enemy, and if that's the case, then it will not work.
So let's do protected virtual void start.
And here we're going to do player equals to game manager dot instance dot player.
Dot transform.
Okay.
Also, we need to update this value, uh, when player dies.
But we're going to take care of that later on.
Actually, maybe let's take care of this right now I'm going to do private void update players.
Lazareff as a reference is going to do this.
If player equals to null, then player equals to game manager, dot instance, dot player dot transform.
And we're going to start invoke repeating which will repeat the method.
Name of.
Update players riff.
Let's do it immediately so we have no delay and repeat rate going to be every second.
Let's say we probably can do this better, but as of now this is just perfect.
So now we made a reference to the player.
Over here.
It will be assigned in the method over here.
And if we lose the players reference, if player dies and we respawn a new one, we're going to update
it every second.
Okay.
Let's go back to enemy chicken.
And let's do handle flip with a player position dot x.
Nice I'm going to save this.
Go back to unity.
Let's go to play mode.
A chicken.
Yeah, okay.
It turned back to me, but it was so easy to kill it.
I'm not sure if that's how it's supposed to be.
Yeah, I'm just killing it automatically, man.
How does it work differently on the reference anyway?
Functionality is there.
Works fine.
Just need to think how to make it more fun, because now it's sort of too easy.
And so fun.
She runs behind me, I like it.
Let me see the reference.
Looks the same to me.
Okay, maybe it's supposed to be like that.
Maybe it's supposed to be an easy enemy that runs behind you.
So who am I to judge?
The functionality feels pretty fun, and it was really interesting to make.
Um, we don't need to do really anything here.
And we could not use inheritance.
Really?
Because these methods haven't a bit different functionality from the enemy mushroom, right?
They are slightly different.
So it's okay to keep them like that private.
Maybe later on I'm gonna move this to the, like, some sort of animator.
But later on, as of now, this is good.
I don't think we need anything else for now.
I only would like to clean up this mess over here.
Give me a second.
I'll see what I can do.
Now we can just make a header.
Let's do header.
General.
Um, info.
Okay, I'm going to save it.
Go back to unity and we have a new enemy that is clean nice as some specific details.
This boolean can be hidden by the way.
Uh, layer detected.
Hello, guys.
I was just editing the video and I noticed what is the difference between reference and the result we
have.
And on the reference, we can see that chicken flips with a bit of a delay.
And that's what we're going to do now real quick.
It's not that difficult to do.
We need to make a private boolean can flip.
Let's make it equals to true by default.
Then we're going to go to this handle movement.
And over here we're going to pick definition of a handle flip.
And over here we can see I mean we can take this line of code that we use for comparing and the position
and x value.
We just need this line of code.
Now let's go here and paste this line.
Open curly brackets.
And for the x value we need position of the player.
So I'm going to do float.
X value equals to player transform position.
All right, dot x.
Good.
Now, inside of this, uh, curly brackets, we're going to check if can flip.
Then we're going to do can flip equals to false.
So this can be done only once.
And then we're going to invoke.
Name of.
Clip with a delay of maybe 0.3 F, something like that.
Now we need to override the flip.
Override flip because we want to make flip available again once we did the flip.
So we're going to do can flip equals to true.
All right.
And this is it.
We don't need anything else.
If you want, we can make it sort of cleaner by overriding, uh, handle flip method.
Then we could take these things over here.
Actually, just these things over here.
Remove the base and paste new functionality in.
Just like so.
And then over here we're going to just handle flip with a layer transform position dot x.
And we do need this.
Yeah.
This makes it sort of cleaner I guess because we overwritten the method.
Now it has different functionality.
And now we can go back to unity and check this.
I only want to take the chicken itself.
And I want to reduce the size of the collider.
So it's not so easy to kill the chicken because when player detecting the enemy he checks the collider.
It has.
In this case it's this box collider which is quite easy to detect.
So maybe we can take it and reduce the height of it to something like so.
Well, let's try, uh, maybe later we're going to fix it.
And also for the damage trigger, I'm going to replace it with a box collider.
Let me just take and copy a component from here and go to the image trigger.
Based component is new, I'm going to slightly reduce it on the Y.
Check is trigger.
Then I'm going to do override apply all and let's go ahead test it quickly and we can move on to next
video.
Yeah, now it's good works.
Same as on the reference.
And it's not so easy to kill.
You actually need to bump on the head.
Okay.