Hello guys.
Welcome to the video.
So we did a great job with all of the previous sections.
And game is nearly finished in this one we're going to do polish of the game.
We're going to fix some bugs.
If we have them, we're going to fix the issues, maybe change the composition of the game a little
bit and improve some things that could be done better.
For example, we're going to make dust effect or camera shake when Rhino hits the wall, things like
that.
Small things that improves the game overall, but it's not going to change much in the core of the game.
All right.
So first thing I want to do is, uh, decomposition of the game manager.
Let me go to level one and I have game manager here.
So this game manager takes care of making audio manager if we don't have any.
So I want to do this for other managers.
And also our game manager does too many things now, too many things at once.
I did it like that because it was a bit easier just to drop everything into one script.
Uh, but I know for a fact that we're going to have a player manager later on for, uh, local co-op
or version of the game, so we better make a player manager and move some functionality there.
Also, we could make a fruit manager, and then game manager would have reference to all of those things.
Okay, that's what I want to do.
So uh, let's go ahead and do this.
First the player manager.
We have this header of a player and respawn functionality.
And also we're looking for respawn point.
We're going to go ahead and make an empty object.
I'm going to call it player manager and we're going to make a script for this.
Let's do script.
Player manager.
Let me go back.
Put the script on the game object.
Uh, over here.
Then let's open this.
And we want to make it as a public static player manager instance.
Now I'll go to game manager.
I'll copy the awake.
Uh, let's take awake.
Place it here.
Also, when I go to game manager and I want to cut out this header for the player going to cut it out,
go to the player manager, paste it in.
Now it will show me a bunch of errors on the game manager because now we don't have variables, but
we try to use them like these for example.
So I'm going to cut it out here.
Then I'm going to go to player manager over here.
And I'm going to open start method.
And in the start we're going to paste this in.
Okay.
Very nice.
Now we need a respawn method and respawn coroutine.
I'm gonna go ahead all the way below here.
And this is the place we respawn in player.
So I'm going to take these two methods, cut them out, go to player manager and paste them in.
All right.
Now we have this functionality on a separate game object.
By the way, this shows me an error because we need to make using System.collections.
Uh, over here at the top.
Yeah.
This one.
All right.
So we've got the functionality.
Let's save everything.
And now that we saved it, it's going to show me a bunch of errors in different places.
If we go to unity we're going to see them in the console.
So one of them here.
On a dead zone once we respawn the player.
So we're going to change it from game manager to player manager.
Just that.
Uh, let's go back.
Let's see another one over here.
We're using game manager.
We just need to do layer manager.
By the way this method over here, we're going to do it in a different way a bit later on.
All right.
Because now if player dies there is still a second before he responds.
And enemy cannot detect him.
It doesn't break the game, but it happens.
Uh, let's go here now.
Over here we have update respawn point.
And by the way this should be moved to player manager.
So I'm going to take it.
Go to Player Manager and paste it in here.
All right.
Very good.
Now let's save everything like that.
And I guess we're going to have a couple of more errors.
Let's go to unity.
There is one on the checkpoint.
So here we call in method update respawn point.
We need to replace it with a player manager like that.
Good.
Very good.
Now let's go back.
I'm going to go ahead and assign prefab over here.
Prefab.
There is a player.
So we're going to give it over here.
And then I want to go to prefab folder and make a player manager as a prefab.
And then we're going to go to game manager and ask it to check if we don't have player manager in the
game, because if we don't have to, we need to create one.
We just need the reference over here.
Serialized field, private game player manager, player manager.
Then we're going to go back to the method we have over here.
Create managers if needed.
And we're going to do this if player manager.
That instance equals to null, then instantiate layer Manager.
Simple as that.
If you like, you can pass managers to the next level with a don't destroy game object, but I don't
think it's necessary.
This is just for us while we testing this.
Um.
Here.
Very good.
So let's go to prefabs now and assign these on the game manager like that.
Now we need to apply overrides.
So this change will be applied to all of the game managers on all levels.
I'm going to click apply and I'm going to delete player manager just so I can check it.
Also on the player manager.
Over here we have prefab.
Okay?
It's fine.
So don't have player manager.
I'm going to go to play mode and.
Now we've got one.
And if I die, it will create a new one.
Although I cannot die now because I'm on easy difficulty.
And we also need difficulty manager in the game just to test different things.
So I'm going to go ahead and make.
Sorry.
We don't need to make it.
We have it on the scene of a main menu.
Let's go to main menu.
Can I save the changes?
Can I go to prefabs, drag skin manager and difficulty manager and drag them here like that?
Okay.
Very cool on the skin, manager.
Yeah, we have it.
Okay.
It's fine.
We have it as an instance.
Then let's go back to the scene.
Level one.
And we want to do this for those two managers as well.
So on the game manager I'm going to make variable serialized field private skin manager.
Centralized field.
Private, uh, difficulty manager.
Nice.
And we can go back to that method.
Over here and we need to do these checks as well if skin manager.
That instance equals to null, then instantiate skin manager.
If difficulty manager equals to null, then instantiate.
Difficult to manage are very good.
So now it will create one if we need to test different things.
For example, now I need to test death of the character and I don't have difficulty manager in the scene,
but it's okay, it will be created for me.
Difficulty manager, skin manager.
Let's go.
Okay.
It is where it is.
There.
I'm going to do hard and I'll go and try to kill myself.
You.
All, my character does not die because we did not update it on the.
Layer.
Over here we have a variable of a game difficulty and we update it at the start.
How can we update the difficulty just in case?
Peak definition.
This is a private method.
Let's make it public.
Actually, I guess it can be private and we can just make a context menu.
And we can just do a context menu.
Uh, update difficulty.
There are many ways to do that.
We could make it just like the variable could be visible in the inspector.
Actually, that would be the simplest way.
Why don't I think of it?
Oh my God, I'm so sorry, guys.
Let's go and just make it as serialized field.
So now we can easily test it.
This was the easiest decision.
I mean, way to fix it.
Why didn't I, uh, you know, sometimes it can be like that.
You don't think of best decision at first.
Okay.
So hard difficulty going to go ahead and.
Hugh, I died and I have all of the managers in the game.
Very good.
Of course, this will not be changed because we are testing seen, but if you start the game from main
menu, it's going to be fine.
Now regarding the game manager, it still does lots of things.
For example, it does take care of a trap of creating an object, and I think we can make some sort
of object creator game object, and then we can call that game object if we need to create some object
with a delay, and we cannot do it from any other place, just like we have with the arrow, because
I suppose some of you want to respawn falling platforms once they fell, and then we would have to add
variable to game manager.
And game manager is kind of responsible for other things.
So let's go to scripts.
I think we can do it in the managers folder.
I'm going to make.
Object creator.
Uh, where is it?
Object creator.
Let's make it as a public static object creator instance.
Then we're going to do a wake.
And we need functionality from any manager we have from here.
For example I'm going to take it paste it in here.
Then let's go to Game Manager.
And let's take.
These create object and create object.
Coroutine gonna cut it out.
Go back paste it in here.
What is it?
Instance.
Okay.
We need using system collection.
Using system collections.
And now we need header with references and it's good to go.
Let's go to.
Here.
Let's take it.
Go back to Object Creator.
Paste it in here.
And then it's basically it.
Now we're going to have a bunch of errors that we need to fix.
And also let's make a serialized field private object creator, object creator.
And then over here if object creator.
Dot instance equals to null, then instantiate object creator.
Nice.
Now let's go and fix those errors.
And one of them will be on the trap arrow.
Because we are using a game manager here, so we can do object creator instead, as well as here object
creator instead.
Okay, if you have any other functionality that used Game Manager to create an object, you can change
it now.
And we only need to go and make the prefab of object Creator.
Let's make object creator.
Let's put the script on and let's find arrow Prefab.
Uh, traps.
Arrow.
And I'm going to just go to prefabs, make it here.
And I think we can make a folder for managers now managers.
Gonna take it all.
And put them into managers.
Boom!
Very clean and nice.
Now this one is here.
I'm going to apply.
Oh it's okay.
We don't need to apply overwrites.
And now it's good to go.
We only need to assign it here on a game manager object creator.
Nice.
Now game manager is only responsible for creating other managers, for collecting fruits and for loading
the levels and saving info.
Still kinda a lot like we could decompose the fruits functionality.
Uh, but I'm not sure it's necessary for now.
I think it's fine.
I think we're not going to do anything with fruits for now, because it's just fruits and.
Yeah.
Uh, maybe I would only make a fruit parent.
Public transform route.
Parent.
And then when we collecting the fruits info I'm going to do this.
If fruit parent is not equals to null, then uh, I'll just move this above like that and then I'll
do.
No sorry.
Let's not do it here.
Let's make another method and let's make it.
Let's make private void parent all the fruits.
Because you might have lots of fruits in the game and you want to find the parent for them, so you
don't clutter up the hierarchy, because it's kind of difficult to manage when you have lots of objects
in the hierarchy.
So I'm going to do this, uh, if fruit parent equals to null, then return.
And if no we're going to take this line of code over here, paste it in here.
And then for each.
Fruit.
Fruit in all fruits.
Fruit.
Transform parent equals to fruit parent.
So we're going to parent all of the objects if we want to.
And let's make context menu for this context menu parent all fruits.
Good.
Now let's save this and let's go back.
Now, if you want to clean up the hierarchy because it's kind of difficult to manage it.
You can make fruit errant and you can find game manager, give it a fruit parent and then just click
Parental Fruits.
And now they'll be here altogether.
And if you want you can switch them off.
Cool.
Well, that's it for now.
Thank you so much for paying attention and taking the time to clean this up.
Uh, again, we could separate fruit management somewhere else, maybe as well as a checkpoints, but
as of now, this is pretty manageable, so I think it's fine.
Yeah.
Because we need to pass the fruit's info when we save, uh, the game, when we collect the fruits,
all of that needs to be done with playerprefs and everything.
So if we want to make fruit manager, then we would have to pass the reference, or we would have to
use Playerprefs in two different scripts.
And that can be a bit confusing.
It's better to have everything together like we have now.
Okay, okay.
That's good.
Let's go to the next video.
We're going to do more foolish.