Hello guys.
Welcome to the video.
In this one we are going to make another cool enemy.
It's going to be a rhino.
From this reference over here.
It's pretty simple to make a very fun one I think.
So that's what we're going to do.
As you can see, the logic here should be very simple.
And we did basically we know all of the script to do this, like we did coding for the similar functionality
or even it was even more complex than this one.
So let's go ahead and set up the Rhino.
How are we going to do this?
First I want to make prefab for the chicken.
Then I want to remove the chicken.
And this time I actually want to be smart.
I don't want to waste time on setting up the entire game object.
So I'm going to take the enemy mushroom, duplicate it, bring it down over here.
Then I'm going to do prefab unpack completely.
Change this to enemy rhino, and we're going to remove enemy rhino script and other things we just need,
so we're not going to change them much.
Let's go to graphics enemies.
Uh, Rhino, we need to make sure these haven't pixel per unit 16.
Mine already do, so it's fine.
Then I'm going to open enemy Rhino, take one of the sprites and drag them to the sprite renderer over
here so it will change the look.
Nice.
Now let's change Collider as well.
We can just reset Collider over here.
It's quite big, so I'm going to reduce it to something like.
So yeah this should be good.
And then we need damage trigger which we also can adjust.
It's supposed to be wider than the regular collider.
Actually it can be the same size as the regular collider because enemy I mean player does not collide
with this collider over here on the enemy because we disable collision between enemy and players.
Only the size of this collider matters.
So yeah, we can just basically make it whatever we want to have here.
Just define the damage shape.
Nice.
And that is basically half job done for the enemy right now.
Let me bring it down here and let's go to animator enemies over here.
Going to make folder for the chicken.
Chicken.
Then let's make folder for the rhino.
So Rhino going to have a new animator controller because you have one more animation.
Not like other enemies that had three animations.
Let's do enemy Rhino.
How how it was.
I forgot how it was on other enemies.
Enemy okay, should it be enemy runner Rhino AC okay, let's drag it here to the enemy Rhino.
Now we can create a bunch of animations for this guy.
Let's create new clip animations enemies.
Right now this will be enemy Rhino idle.
Going to go to graphics of the Rhino.
It is over here.
Going to take idle sprites.
Drag them here.
Sample rate 20.
Pretty simple stuff to do.
Let's make new clip enemy Rhino move.
This one going to be for the run animation.
Sample rate 20.
Then we need enemy hit so we can kill him.
Let's take this.
Put them here.
Sample rate 20.
And we need one more enemy Rhino hit wall.
So when he hits the wall we're going to play different animation with this sprites.
Sample rate 20.
Now before I forgot let's go to animations of the Rhino select hit wall and the hit and uncheck Loop
time.
And also this should be enemy rhino hit.
Okay, so this not having a loop time, now we can set up the animator.
I think we can make a blend tree because that is the cleanest way I can think of.
Uh, let me do Blend Tree.
I'm gonna name it as Idle Move.
Nice.
Let's make it by default.
And let's go inside of this blend tree.
This should have x velocity.
And we need three motion fields.
One going to be Rhino move.
And I'm going to copy Rhino here so I can use it.
Then Rhino idle and Rhino move threshold minus one zero one.
And we know it's going to work.
So I'm not going to check it.
Let's go back now for the hit.
Supposed to be available from any state because now we have a bunch of animations, but heat wall should
be available only from Idle Move.
So I'm going to go here and set up the new condition actually boolean hit wall just like that.
It's going to be fine.
Let's transfer here if it's a true and check exit time transition duration zero.
Nice.
Now we're going to transfer back when heat wall is false.
Has exit time.
Uncheck transition duration zero.
And then this animation should be triggered from any state.
So I'm going to make a trigger heat.
And we're going to transfer from any state to enemy hit.
And over here we should have condition of heat transition duration zero.
And make sure to uncheck can transit to self over here.
This is important.
Now we don't need any other transitions over here I believe this is just fine because once we transfer
to enemy hit, he's going to die anyway.
All right.
Cool cool cool.
So we have animator.
We have everything, like almost everything ready.
And now we're going to need a script for Enemy Rhino.
I'm going to make a new C sharp script enemy Rhino.
And let's open this.
Now this one going to have a very simple functionality, but still we need to inherit from the enemy.
And actually, I think we can take the script from mushroom and chicken, place them here and then edit
the script to our needs.
First let's go to enemy chicken and take these two methods on draw Gizmos and handle collision because
we're going to need to detect the player.
Now we can see we need detection range and boolean player detected.
And here I want to show you a trick.
You can press alt enter and click Generate Variable over here.
Generate field.
Going to make a variable for us.
Same here.
It's a bit different from what we need.
We could use raycast here to do by the way.
But let's use boolean.
And this should be float.
And let's make them as serialized field over here so we can see it.
And we need a header.
Rhino.
Details.
Nice.
Now this is almost everything that we need.
And let's think about the logic here how it's going to work.
Rhino going to stand.
So from the start he cannot move.
Once he sees the player he is going to move into player's direction.
So we're going to make a method and it's going to be.
Private void handle charge.
And here we're going to manage the movement of the rhino.
Of course if we cannot move, we're going to return and it's going to be like that by default.
And if we can move, we're going to do our velocity equals to new vector two with a move speed multiplied
by facing direction.
And our velocity dot y over here.
And I want to make him able to move if we detect in the player.
So maybe in the handle collision over here we can do if player detected sorry player detected then make
can move equals to true.
Very nice.
Let's save this.
And this one.
As it is now supposed to work, we only need to do overwrite, update and update.
We need to do anim set float of the x velocity to the rb velocity dot x.
And also we need to do handle collision and then handle charge.
Sorry.
Handle charge.
Cool.
Let's save this.
Let's go back to unity.
And over here, we can just place Rhino to the side somewhere here.
Let's put the script on enemy rhino.
Now we need to assign ground check.
What is player?
What is ground and damage trigger?
Over here.
Let's move ground.
Check in front of the rhino.
Like so.
And I think we can increase wall check distance to something like this.
So we can see the raycast outside of the collider itself, and probably would be a good idea to increase
ground check distance as well, just in case.
So I'm going to do 1.2 here.
Nice.
So that's all what we need.
Now let's increase detection range here.
I'm going to make it as 15.
And if I'm not wrong.
Range should stand their weight.
And then when I jump in front of him, he'll run.
Let's see this okay.
He could run faster, by the way, but other than that, it's good.
Now, what we need is to make him flip.
If he is detecting the ledge because we don't want him to fall into the pit.
If you like that functionality, you can keep it.
But I'm going to show you how to stop it.
So here, I'm going to do this.
If no ground in front detected then we're going to do can move equals to false.
So he will stop moving.
Also we're going to do RB velocity equals to vector 2.0.
So just in case we're going to reset his velocity so he will not fall off.
And then we're going to flip him immediately.
So he'll be ready to charge again.
Yeah.
This looks very nice and clean I like it.
So now we're gonna save this.
Let's go back to unity.
And now I'm going to go to play mode.
Gonna, uh, you know, aggro him.
He's gonna run.
And once he'll run to the ledge, he'll stop.
Very cool.
So how job is done here?
But before we continue, I want to show you a bug.
We have a very interesting one.
Probably you should know about it.
So at the moment, we have no functionality on the enemy.
Rhino for the flip when he is detecting the wall.
Nothing like that.
I actually noticed this bug before, but I thought it's not that important.
But now it is standing in our way.
So I'm going to show you what it is.
I'm going to agro right now again.
And you'll see that when he reaches the wall, he's going to flip you.
So what just happened?
We don't have any wall World detected flip functionality.
Why did he flip if we have only functionality?
No ground in front detected.
So this setup generally means that Unity's Thelma Collider will create colliders only along the visible
boundaries of the tiles, and it will not cover the entire area.
And it may happen that somehow when enemies are facing this side like so, when he stands somewhere
close to the wall like so, there is no collider inside of this place.
And because of that, he's not detecting anything.
And because of that, he is flipping like it would be the edge.
Luckily for us, it is super easy to fix.
We can go ahead to the ground, choose geometry type and change it to polygons.
Now it's going to fill up everything inside.
Okay, now I'm going to make Rhino Faster, like maybe seven.
And we're going to see what will happen when he charges to the wall again.
Yeah.
So now he does not flip, which is very good.
That is what we need now at this point when he hits the wall, we need to change the animation for him
and maybe do some sort of impact.
So let's go to the script all the way above.
We want to make serialized field Private Vector two impact power for that bounce effect when he hits
the wall.
Now let's go here and do something simple.
If we'll detect it then we're going to use method hit wall.
Or actually let's do wall hit okay.
And I'm going to click alt enter generate method.
And inside first of all we're going to set Boolean to true.
So anim set bool of hit wall to true.
Then we're going to give that impact velocity there.
So I'm going to do RB velocity equals to new vector two impact power dot x.
And usually we want to bounce rhino back.
So we're going to do multiply by negative facing direction and impact power dot y.
Super cool.
So that's what we need to trigger the animation.
We also need to exit the animation.
And actually let's place this first over here.
Yeah.
Now we need to exit the animation.
How are we going to do that.
Well we can make a method and call it with the help of animation event in the end of the animation.
So let's make a method private.
Void charge is over and inside of this method we're going to do can move equals to false.
So if you're not going to move again and we're going to do set bool hit wall false.
That's almost everything that we need.
Let's go ahead and see how does this work.
And then I'm going to show you a couple of places where we can improve it.
For now we just need to go to enemy right now hit wall.
And maybe and maybe on the last frame or one frame after that we need to add event and call method enemy
right now methods.
Charge is over okay.
This is supposed to work.
I only want to add impact power.
Let's give it maybe three on the X, four on the y.
This is good.
And now let's go ahead and charge him I mean trigger Him.
Key still works the same.
That's good to know.
And then.
You.
This is very nice.
I like how it looks.
It's so fun.
So much fun.
And we probably need to flip him once he landed.
I don't want to flip him immediately.
That will look weird, but maybe with a little bit of delay is going to be nice.
Um, let's go to enemy right now.
And over here we're going to do invoke and name of flip with a delay of one second.
Yeah.
This will help us a lot.
And, um, I think we need to go over here and make him a variable serialize field.
Private float, max speed.
I want to increase his movement speed while he is running.
And we're also going to need private float default speed so we can store the value.
Let's override start method.
And in the start we're going to do default speed equals to move speed.
Now we have saved the value of the move speed.
And here we need to do some sort of change rate that we're going to use.
So let's do serialize field private float speed up rate.
Yeah I'm going to make it 0.6 F by default.
Should be not higher than one actually.
Let's go over here and do move speed equals to default speed.
And also when we hit the wall we're going to do move speed equals to default speed.
And this is almost over.
So maybe while we are here let's take this into a method extract method.
Turn around something like that.
Yeah.
Like turn back.
Good good, good good.
And over here we can do something like move speed equals to move speed plus and time delta time multiplied
by speed up rate.
So this will increase move speed with time.
And we just need to check if move speed is bigger or equals to maximum speed, then maximum speed equals
to move speed.
We also need to reset the move speed.
Once we hit the wall or once we flip like turn around.
So probably it's a good idea to do it here.
Move speed equals to default speed.
And on the wall hit as well.
Let's do move speed equals to default hit I mean default speed.
Also there is something I'm worried about.
We never stop this velocity until the charge is over.
So I'm afraid that this move speed will interfere with the impact we're doing over here.
So instead of doing can move false over here, let me do it on the wall.
Heat can move false.
All right.
And we're going to go back to unity here to make things faster for me I'm going to go to the tile palette
and draw a small platform over here.
It will be a bit faster because we don't have to run back after he runs to the ledge.
Now let's select Rhino.
Let's do his default move.
Speed five and maximum speed maybe eight and speed up rate.
Actually, let's increase it.
Let's make it 1.5.
Why not?
Now we're going to go and trigger him and see the results.
Very nice I like it.
Oh my God, how do I.
Yeah yeah.
Looks good.
We could try to make him heavier.
We could try to make him heavier and increase his gravity scale.
That would make him more bouncy, I believe.
Let me just.
Quickly.
Maybe.
How could I do this?
Uh, on the player.
I'm going to disable this killing functionality.
Where is it for now?
I just need to, like.
I don't want to kill him.
I want to see him run.
Now let's go to play mode.
Select him.
Let's open rigidbody.
Let's do gravity scale 3.5, for example.
Let's see his bounce now.
Oh that feels nice to see a nice.
Let's try to increase it to something like five and eight.
Yeah cool cool cool cool.
Let's try.
Maybe a bit less vertical.
Yeah.
So good.
Right?
So juicy.
Cool, cool, I like it.
I will increase it on the Y.
Let me see again.
Yo.
What happened to him?
Why does he flip there like an extra time buggy or something in a bug there?
If I aggro him and I stand on the ledge over here while he is bouncing from the impact, he will detect
the player and he'll try to enter charge again.
And that's why we have that sort of an extra flip.
So let's go to enemy right now.
And over here we can detect the player only if can move equals to false.
Oh, but we can move to false over here.
So it's going to detect him after the wall hit anyway.
Okay, I guess we need to create another boolean just to fix this bug.
Let's do private bool can charge.
Going to be true by default.
Then over here we're going to do and can charge.
Then we can do can move true.
And let's set up can charge to false and then can charge will be true only when it's good I noticed.
And we're going to go to the next video.
Oh he still does it huh.
Maybe we can do a different approach here.
Uh, let's not use this boolean, but let's use is grounded.
If player detected and is grounded and only then.
Supposed to help.
Just an idea.
Let me remove this in charge and in charge.
Oh.
Because he detected me.
If he is bouncing, which is not cool.
Okay, now it's fixed.
All right.
I'm happy about it.
Q yeah, I like it so much, man.
Whoa!
Oh my God.
It's so good.
Okay.
Thank you so much for paying attention.
Let's not forget to remove this over here and I'll see you in the next video.