Hello guys.
Welcome to this section.
In this one we're going to develop enemies.
And I think now development will go much faster because now we know a lot of things.
We learned how to work with timers coroutines.
We know how to move rigidbody with velocity, how to flip the character, all of that things.
So now I'm going to show you how to do stuff.
But things that I explained before I'm not going to, you know, tap on them as much as it was before.
Yeah.
So get ready for development.
Let's go.
We're going to go to Graphics Enemies.
And here we have a bunch of enemies.
We're not going to develop all of them, but we're going to develop a lot.
And I want to start with simple I want to start with a mushroom enemy because it's quite simple.
It just walks left and right and you can hit the enemy.
That's it.
We also need to keep in mind that we're going to develop not one enemy, but a bunch of them, and they're
going to have similar functionality.
Because of that, we better prepare some sort of inheritance that can be used by multiple enemies.
As example, we have this mushroom that will run left and right with this animation over here.
Also, we're going to have an enemy like um.
Let's say rhino horns are going to run left and right, and we could type movement for both of them
in two different scripts, but also we could make one movement function and then just use it on Rhino
and on the mushroom getting me here.
So we're going to develop a mushroom first.
But we're going to do that.
And we're going to keep in mind that we're going to need some of the script by other enemies.
All right.
As always, I offer you to start with simple.
Let's set up controller and animations.
I'm going to go to animations over here.
Let's make a new folder for uh.
Actually we don't need a folder for now.
We can develop things here.
Then we can arrange them into a folder.
Let's do animator controller.
This is going to be enemy mushroom.
We type it together like so and we mushroom AC.
Then we're going to do.
Sorry.
We need to go to graphics.
Enemies.
Let's find mushroom.
Let's take the, uh, idle sprite place.
It here is going to be enemy.
Mushroom.
We're going to give it a layer of, uh.
Enemy just like that.
So now it's going to be visible.
Oh, we need to.
Yeah.
Let's take the sprites and make pixel per unit 16.
Great.
So now we have a mushroom enemy.
We also want to give it a layer of the enemy.
This is important.
We're going to use it later on.
So I'm going to do add layer.
And over here we're going to do enemy.
And since now we're using a couple of different layers.
Let's select the player and give him layer of a player.
Like so.
So this one gonna have player and now this object only for the enemy.
We're going to do enemy.
Great.
Now what do we need for this enemy animator controller?
So we're going to drag it on the enemy like so.
We also want to have a bunch of animations and let's prepare animations.
Now when I do create assets animations.
And over here I'm going to do Enemy mushroom and it's going to be idle.
Let's go to graphics.
Enemies.
Mushroom idol.
The sample array is going to be 20.
Then we're going to need a new clip.
Enemy mushroom.
Uh.
Move.
You're going to have this run animation.
Can I place them here?
Sample rate 20.
Let me make it a bit smaller and I'm going to stretch the window.
So this is the run animation.
And also we're going to have a hit animation.
So we're going to do enemy.
Mushroom.
Let's just call it hit.
Enemy mushroom hit.
Can I take these sprites and place them here?
Sample rate 20.
Nice.
Now let's go to animator of this one.
And for the movement and idle I think I'm going to use the blend tree would be the easiest one right.
Uh because we're going to use velocity rigid body velocity for this enemy.
So let's make a blend tree and name it as move idle.
And that's what we did for the player.
Oh I hate this bug.
This happens all the time.
Move idle.
Uh, I need to restart unity so I can rename this blend tree.
Just give me a minute.
Okay, let's try again.
Idle move.
Good.
Now inside we're going to have two motions one two and let's do three.
Automate threshold and check is going to be mushroom I cannot see anything.
Mushroom move.
Mushroom idol and.
Mushroom move.
I'm going to extend it like so.
So you can see the names you're going to have minus one zero one.
Now if you open preview over here.
And click play.
Oh.
What's up?
Why it's not available.
Yeah.
We need to select it again okay.
So he's moving on the zero.
He's standing.
Then he's moving again.
Cool.
Very cool.
Now let's rename this to x velocity.
And this is the parameter we're going to control on the mushroom.
Now let's go to the base layer.
Take this enemy mushroom hit.
This should be a default.
Then we're going to transfer to enemy mushroom with a trigger.
Trigger hit just like that.
Why not?
Trigger.
Hit exit time and check transition duration zero.
And I suppose we're going to destroy the object or make him fall after we hit the enemy.
This is how it's going to be on a preview of these assets.
You actually can see how enemies are dying.
Let me just quickly find it over here.
You can see when we jump in on the enemy, they sort of fallen off the level.
They do a bit of a rotation, they lose in Collider and they just fall in.
So probably that's what we can do.
Let's see.
Maybe we'll take a different approach because we already know how to make objects fall off the level.
Right.
The falling platform does that.
We just disable colliders and it falls off the level.
So it's not really different from what we've seen just now.
Okay.
So now we need a mushroom script.
An anime script.
Let's go to scripts and I'm going to make C sharp script.
Enemy.
Then I'm going to make C sharp script.
Enemy mushroom.
Here we have enemy mushroom.
Why am I doing it like that?
Well, we're going to put enemy mushroom on the enemy mushroom, and we're going to do the common thing
on the enemy script.
And enemy mushroom will inherit from the enemy.
Let me show you the example.
Let's do inheritance from the enemy.
And we know that most of the enemies are going to have a movement speed.
Right?
I'm going to close all by this and I'm going to find enemy script.
So if most of the enemies have movement speed, then we don't need to make movement speed variable on
each new enemy.
We can do it only once by making it here.
Let's make serialize field.
Uh, protected float.
Move speed.
Now let's save this.
Let's go back to unity.
And we can see that move speed is there for the enemy mushroom.
So now further on when we create new enemy and we need some bunch of parameters that are common between
different enemies, we can easily just make it on the enemy script and use it by others.
Let's go ahead and keep development of the enemy mushroom through the enemy script.
We know that other enemies, not only enemy mushroom, going to have an animator.
So let's do protected animator anim, and probably most of them going to have rigid body.
So let's do protected rigid body RB.
And then we're going to open our wake that we can override because later on we might need to override
our wake.
So I'm going to do protected virtual void awake.
This will allow me to override the method on the enemy mushroom.
As example we can go to enemy mushroom.
And here we can just type override awake.
And this will be a new awake that has functionality of the enemies awake.
Cool.
Now let's go to enemy again.
And over here we're going to do Anim Getcomponent of the animator and RB Getcomponent of Rigidbody.
Very nice.
Now let's say we want to move the enemy.
We could make one script that other enemies would use for the movement, but we are not sure yet how
other enemy is going to act.
If we're going to need to use script on those enemies as well.
That's why for now, I'm going to do handle movement on the enemy mushroom only I'm going to do private,
uh, void handle movement.
And in the handle movement we're going to do RB velocity.
And as you can see it is available to this script because we have it as protected on the enemy over
here.
So velocity equals to new vector two.
And here we have move speed.
And then we're going to do rb velocity dot y.
It also would be nice to know facing direction.
So we can define where enemy should move left or right.
So let's go to enemy over here.
And let's make a protected int facing direction.
And if you remember our mushroom is facing to the left as well as most of the enemies.
So I'm going to make it minus one by default.
Let's save this then on the enemy mushroom we can do multiply by facing direction.
Now we need an update.
Update.
Handle movement.
Cool.
Now let's go.
Uh, actually, we need to update the animations as well.
Would be nice.
So I'm going to do anim set float of x velocity to the RB velocity dot x.
Very nice.
Let's go back to unity.
This enemy needs to have a collider so we can give it different colliders.
Let's try.
Let's try Box Collider for now.
And we're going to just.
Decrease it to the size of this maybe is going to be a body collider.
We're going to use it to detect collision around the mushroom.
So he will not fall through the ground or he will not pass by walls.
And we also need a rigid body on this one.
So I'm going to do rigid body 2D.
Let's do interpolate collision detection.
Continuous.
Now we can go to play mode.
He's going to stand there.
In the idle.
Oh, what is that?
Variable of a waypoint have not been assigned.
Over here.
We need to remove none.
Okay, so now mushroom stands there.
I can give him movespeed of two and he's moving to the left.
A very funny guy.
I like it.
So he walks like that and then falls down.
What do we need now is to detect the ground in front of the mushroom.
And then if there is no ground in front of him like so, then he'll be like, okay, I need to go to
another side and he's going to flip.
So if that's what we need, then we need collision detection on the mushroom.
And we need a flip method just like we had on the player.
Also, I think that lots of enemies are going to need a collision detection probably.
So I'm going to make a header over here.
Header.
Basic collision.
Let's do serialize field.
Protected.
Float and it's going to be, uh, ground check distance.
And now it's going to be 1.1.
So let's do it as a default value.
Then we need serialize field protected float wall check distance.
Uh let's do 0.7 F by default.
But we can always adjust.
We're also going to need a layer.
So protected layer mask what is ground.
And we cannot check the ground under the mushroom.
We need to make ground check in front of him.
Because of that we're going to have serialized field protected transform.
Uh, ground check.
Just like that.
And I think that's good for now.
Now let's go ahead and make a method.
And I feel a little bit lazy.
So I'm going to go to the player script.
All the way down.
We have this handle collision.
We have our flip methods.
So we're going to take them.
Let's take these three copy it.
Go to enemy face them in.
Also we need this handle collision method.
Let's copy this.
Go to enemy and paste it over here.
Now we need to fix this bunch of errors and it's going to be good.
We have a boolean that we need to create.
Let's go and make protected bool facing right.
And it's going to be false by default because we know mushroom is facing left.
Now for these booleans over here we need.
Private and let's do protected protected bull is wall detected.
And also I want to have protected bull is ground detected.
We can go down.
And over here we're going to type is ground detected.
Nice.
Now for the ground check.
Instead of transform, we're going to use ground check position.
Very good.
Also, we need to change it here for the gizmos ground check position.
Ground check position.
Cool.
So now we have collision check and gizmos check on the enemy.
This is the handle flip method, which will act a bit differently according to the enemy we have.
Let me quickly explain.
If a mushroom is moving to the left, then probably we have to just adjust, you know, like set, handle,
flip according to the velocity of the rigid body on the x.
But there is such enemy as a, uh, bat.
As example.
Yeah.
Graphics enemies bet.
And this enemy will fly towards the player when it detects the player.
And here we're not going to have our base velocity.
We're probably going to use move towards, just like we did with the trap.
So for that we cannot use our base velocity, but we can use position of the player to flip the enemy
to know where he needs to face.
So as you can see, it can be different for different enemies.
Because of that, I'm going to pass a variable over here, float x value and we're going to use x value.
Here.
So now this method is flexible can be used with any x we have.
Cool.
We have a lot.
Um.
I'm going to go to enemy mushroom.
I'm going to call handle collision over here.
Oh, it's not available.
Okay, let's go to enemy.
Make this as protected virtual void.
Gizmo is going to work like that, I think.
So we don't need it.
And the flip can be as protected virtual void and better make it, uh, for the flip as well.
Nice nice nice nice.
So so far nothing new.
We had this functionality on the player.
We know how it works and just on the enemies script, so it can be used by many enemies and how it can
be used by many enemies.
I'm going to show you on the enemy mushroom.
So now we can type here handle collision.
And now in the update we can check if no is ground detected means we do not have anything in front of
the mushroom, and it's time to flip the mushroom so he can walk to another side.
Let's do flip over here.
Now I'm going to save it.
Go back to unity.
Over here.
We need to make an empty transform for the mushroom.
Let's do create empty ground.
Check.
And I'm going to assign it over here.
And also we need to choose what is ground.
Nice.
Now the ground check is far enough.
It's okay.
So 1.1 was good for the wall check.
Yeah, point nine will be okay.
Now, if I'm not wrong and I'm pretty sure I'm right, we need to hit the play button.
Mushroom will walk up to here, and then he'll decide to flip back because there is no ground in front
of him.
We only need to take this ground check and move it forward like so.
Just so we're doing check in front of him.
Let's go.
And mushroom is there.
And then he's like haha and walks back.
Perfect.
Now we want to flip the mushroom when he's facing the wall.
Let's go back to the script.
And over here we're going to do or is well detected.
Nice.
Now you're going to flip, uh, when he faces the wall as well.
Then next thing I want to do is to give him a bit of the idle time.
I want him to walk up to the wall or ledge and wait for a while.
Let me quickly check the flip with the wall.
Yeah.
Good.
So to add the idle time, we're going to do something that we did before.
We're going to use time dot delta time and a timer.
Let me quickly explain how it's going to work.
And I think we might need this idle time on other enemies.
So I'm going to go ahead here and make serialized field private or sorry, let's do protected float
idle time.
And.
And let's do protected float, idle timer.
And it's going to be very easy to make a mistake like that.
Let's do, uh, let's do idle timer and idle duration.
Although I like idle time better, we need to be sure we don't make mistake in the future.
Okay.
Let me maybe do serialize field so we can see how it's working.
Okay.
And I'm going to just.
Let's do protected virtual update.
Avoid.
Sorry.
Void update.
What's up man?
Yeah.
Okay.
Update.
And.
On the enemy mushroom.
Instead of doing private void, we can do override update.
Protected override okay, so now this is overriding the update we have here.
But because we did not type base it's not going to work.
We just need to type base update.
Now it's going to have functionality of the base update from the enemy.
And in the base update we can do idle timer minus equals time dot delta time.
So we're going to decrease the value all the time.
Let's save this.
Let's go back to uh unity.
And I'm going to show you what we're going to do.
So you can see idle timer is decreasing.
Once we set value to positive let's say duration will be two.
And we're going to give here two.
This is the time you're going to stand on the ground.
We're not going to walk.
And then once it's less than zero then we can walk again.
That's the goal.
How are we going to achieve this.
Let's go to enemy mushroom and we can override the flip method.
Override flip.
And once we flip we're going to do idle timer equals to idle duration.
So every time we flip the character we're also going to uh set idle timer to idle duration.
If you would like you can just open curly brackets and do it here.
That would work as well.
Probably makes more sense.
And then we need to stop movement.
If idle timer is, uh, less than zero, we can do that simply by going to handle movement and type.
If idle timer is less than zero, then return.
Uh, so every time we flip, we're going to set idle time and mushroom going to stand and wait.
Let's give it idle duration of 1.5.
And let's see this.
You're gonna walk there.
Come on, man, why?
He's not working.
Did I make a mistake?
I think I did make a mistake.
Yeah.
If idle time are bigger than zero, then we return.
So if we still have idle time, we cannot walk.
Yes, this is how it should be.
I'm sorry.
This is how it should be.
Let's go.
And he works there and then he's like flipping and waiting for a while, then walks back.
Also, I've seen a bit of a slide.
I didn't really like that.
Uh, let me make his speed faster.
And he's like, well, that's not what we need.
Uh, let's go to enemy mushroom.
And I think.
We can do RB velocity equals to new vector or just vector zero vector zero.
So we're going to stop his velocity once he is leaping.
Yeah that would be a bit better.
Also, let's apply this only if ground is detected.
And that would remove Jitterin when he's falling off the ground.
Let's go back.
Let's say he moves faster and then he is like stopping.
Okay.
Very good.
Nice.
I'm going to give it smooth speed of, uh, two because I like how it worked.
Let me check something.
I want to see if he's in the air.
What's he going to do?
For any reason he could be in the air.
He's flipping endlessly.
Okay.
How could we stop this?
Well, just to be sure, let's do this.
We're gonna go to enemy and rename this to Ground forward detected or ground in front.
Um, is in front detected.
And then we're going to make one more check for the ground that it's going to be two different checks.
Private ball is grounded.
Then we're going to go back to the handle.
Collision and do is grounded equals to physics.
2D raycast.
And this one can be done from a transform position vector two dot down.
Uh, ground check distance as well, I think.
What is ground?
Nice.
And then we're going to need the gizmos.
So I'm going to just duplicate this line of code.
Change it to a transform position.
So we basically add in one more collision check.
And if character is not grounded, he will not be able to flip.
Yeah.
This is what I want to do.
So everything works the same over here.
Except that over here.
How?
Maybe even here I can do.
Wait.
Let's do if.
He is grounded equals to false, then return.
Yeah.
And then we do need it over here.
But now we're going to check how it's working.
Then I'm going to take a look.
If we clean this up and we're going to move to the next video, and I know it took a bit longer than
it like we wish it would take, but we did set up for other enemies.
So it's good.
Now he's walking.
They're leaping, going back.
If I take him and pull him into the air, he's going to just fall.
Cool.
This is what we need.
All right?
I like it.
Now.
If you would like, you could make him like.
You would make.
You could make a possibility of a trampoline bounce in the enemies.
But that would take another ten minutes.
And I want to spend time on other enemies.
Maybe we can do this with a polish, but if you want to do it yourself, you basically make a method
for the enemy mushroom, same as we did for the player.
Like.
This one.
Push method.
Where is the push?
Push.
So you take this functionality, give it to the enemy mushroom.
Then on a trampoline you detect if.
Player or enemy walked into the trampoline and then just call the method and bounce.
The mushroom would be fun I'm sure.
Anyway, this is a great job!
Thank you so much for paying attention.
Oh, let me hide this timer.
We don't need serialize field.
Now we know how it works.
And on enemy mushroom.
Give me a second.
I'll see if we can clean this up.
Okay.
We don't need a wake.
And I think we can we can remove this from here, extract it as a extract method and they'll turn around.
That's what I wanted to call and I'll do if.
Uh.
He's grounded.
Poles then return.
Or maybe let's just do if is grounded.
Then handle turnaround.
Okay?
Yeah, this is a bit cleaner, I like it.
This should be for the, like, handle animations.
Could we do that?
What do you think?
Well, let's keep it like that for now.
It's good.
I'll see you in the next video.