Hello guys.
Welcome to the video.
In this section I want to show you how to make local multiplayer.
We're going to make a co-op player mode where two players can play together, and the system works in
a way that if you want, you can make more players.
3 or 4 is fine as long as you have input devices.
As for me, I'm going to use keyboard and gamepad to make the system and to check everything, as I
assume that most of the people who are doing this course are going to have keyboard and one gamepad.
All right, now let me show you what we're going to do here.
I'm going to take my prototype project and enter the play mode.
And I'm going to use gamepad so we can go to new game.
We can choose how many players is going to play, for example two on a normal difficulty.
Now first player is supposed to select the skin.
Let's say first player is a pink man and second player can be a ninja frog.
We're going to click select.
Then we need to select level.
Now over here, we need to display some kind of message that would say press button to join.
And we're going to do that in the end of the section.
Then we're going to press join button.
And there is a player that you can control.
And also you can press any key on the keyboard as a second player to join the game.
And this is what we're going to do.
And both of them are controlled by different devices.
And also, uh, the system we made will remember which player has which skin and controlling device.
So every time player presses input from a gamepad.
So every time player presses input from a gamepad, he's going to have character that he chose, even
if both of them dead.
And now there is no one.
And player from the keyboard will do the input.
Who's supposed to be the second player?
He will be the second player.
All right, so that's the system we're going to make in this section.
And it's going to be a lot.
To be honest.
Till yesterday I was thinking there's going to be very easy.
You just make a couple of prefabs and make it work.
But I learned from experience that I actually have to set up entire system for this, and it took me
maybe 3 or 4 hours to come up with this.
So I hope you will like it.
All right, let's begin.
Uh, first of all, we need to adjust the way how player manager works.
As of now, we have sort of custom player manager that respawns the player.
Uh, let me go to prefabs and take the player manager over here.
So this is the custom player manager we have.
But if you want to have a local multiplayer, it will be easier to use Player Input Manager from unity,
because that one can automatically assign control and devices to the character it creates.
So that's why we need to go here and add component of a player input manager.
Now thanks to this component, unity now can listen to the devices that were used.
And if someone pressed the join button, it's going to make a new player.
For us.
That means we don't need to use prefab on a player manager anymore.
So let's go ahead and clean this up a little bit.
So over here, uh, let's take these, uh, line of code.
I just need it in the future.
So I'm gonna paste it in here and comment this out.
And these two methods can be removed for now because we're going to use different system later on.
So let's just delete these two methods okay.
Now let's go all the way above.
And let's remove player prefab and respawn delay because again we're not going to use them.
I'm going to save the script, and there may be a couple of errors in unity that we need to fix real
quick.
Yeah, there is one on a dead zone that tries to respawn the player.
Let's remove it.
And let's see what else is there.
Um, there is this one.
Action on player respawn.
I guess it says that action is not being invoked anywhere.
Yeah, it's never used.
Okay.
Um.
We're going to use it a bit later on, but for now, let's just use it at the start method so it does
not give us an error message.
All right.
Cool.
So now we don't have a prefab on our player manager, but we need to create player somehow.
Well we're going to do that with the help of player input manager.
First of all let's change send message to invoke events because we're going to need to check when player
joined the game so we can add some functionality like update skin of the player or update the position
of the player.
Then there is a join behavior and I want to have join action is triggered as a join behavior.
That's what I want to do.
So first we need to go and make the action on the, uh, input action editor.
Over here.
Let's delete the post action.
Actually, we can just use it.
Let's rename this from post to join.
I think I did delete this in the like in one of the videos.
Why?
It's why is it here?
This is so weird.
Okay, I'm going to just delete it in case you don't have it.
And I'm going to show you how to make it from the start.
We're going to click plus over here and we're going to name it as uh join.
Game.
Maybe.
All right then, over here, we need to choose a device that we want to use for joining and also a button.
As for keyboard, let's just find keyboard and find any key.
Or if you want you can use enter key.
Yeah, but I'll use any key.
Any key.
Okay.
You also need another button.
Let's add binding and let's do a gamepad.
I'm going to type start over here.
Start on a gamepad.
Also.
Now we're using start button to pause the game from a gamepad on a UI over here.
And it will pause the game and it will join the player at the same time.
We're going to take care of this later on, but as of now, let's just fix it in a very simple way.
Let's change pause button from start to something else like select for example, select button on a
gamepad.
So it will not interfere.
Let's save the asset.
Now we can, uh, go over here to join behavior, and we're going to change it to join player when join
action is triggered.
And then we need to choose the action.
We're going to click Use Reference.
Then we need to click this dot over here and find this join game action.
This is the one.
Okay, I'm going to choose it.
This is nice.
Now this player input manager want to have a prefab so it knows what the player is.
Uh, we're going to go to.
Asset prefab folders.
There is a player and we're going to drag this over here to the prefab field.
Now this is supposed to work as it is right now, but it will not.
Uh, let's just try it.
Let's see what it's going to show us.
And I want you to know about this.
I'm going to use my gamepad, and I'm going to press the start button.
And you can see we have a message.
The game object does not have a player input component on it.
Because of that player input manager cannot recognize this player prefab as a player, and that's what
we need to fix right now.
Um, let's go to player prefab.
Actually, we have it over here and we need to go ahead and add.
Player input component.
Now, later on, we're going to need to use this player input component to assign actions.
So two player is going to be controlled by two different devices.
So we're going to need to type get component of a player input.
But I was smart enough to and that is a sarcastic comment.
That was a very uh bad decision.
I named player input as player input.
As well as the script player input.
And now if you try to get a component of a player input over here, it might search for this script
of a player input because it has the very same name.
The solution here is very simple.
First of all, let's take this player input.
Let's rename it to Player Input set.
Oh, no.
It created another script.
It's okay.
I'm going to delete it from here.
Let me delete it.
It's fine.
No worries.
And then let's go to this player input script.
We're gonna take the name.
And we're going to rename this to.
Player.
Input set and before you confirm it, make sure you have checked rename symbols file so it will rename
file in unity as well.
Now I'm going to press enter.
It's going to change the name everywhere.
And if I close Visual Studio.
I'm going to have player input set over here with this name as well as in the script over here.
Right.
And because of that, now we can get component freely on a player in the future.
This was a very bad decision that I did and I'm sorry I did that.
All right.
Now we need to assign actions over here.
Let's assign it like that.
Over here we can choose default scheme.
I'm going to choose keyboard and I want to disable auto switch and default map will be player.
Nice.
Now we have this.
Let's take overrides and let's apply them.
Let's double check player manager.
It has a prefab and everything should be ready.
Let's go to player mode.
And now I'm going to try to join new player.
There's the one with the keyboard.
Now I'm going to press start button on a gamepad and I join the player.
The only problem now is that we can control both players with one device.
Both of them can be controlled with the gamepad right now, and if I put my gamepad down and use my
keyboard, both of them are controlled as well.
So that's the fix we need to apply right now.
And actually it's not that difficult to do.
We just need to do one simple change.
Uh, on the player script, we created this new instance of a player input.
Uh, right here.
This is what we do, right?
And when player input manager creates a prefab with a player input component, with this component,
it automatically gives it a device to control the player.
And now instead of creating new player input, uh, instance, just like we do now in the script, we
need to get access to this component, and then we need to get access to exactly this action map that
is under this component in this field of actions over here.
This is what we need to use for the input.
So each player will be recognized as a different one.
Right.
That's what we need to do because as of now when we have two players, we create a new instance of controls
for uh, each of them.
But each of them, even with the new one, are controlled by, um, one device or two devices.
It's just like one player that has two input devices.
That's what it does.
And this is how it works in a version of the game for a single player, which is totally fine because
you can take the keyboard, you can play the game, then you can change your mind.
You can switch to gamepad and use gamepad to play the game.
So in that case, that is just what we need.
But in this case, each player should be controlled by different device.
That's why we're going to go ahead to the script.
And change the system a little bit from create a new instance in the code over here, we're going to
change it.
To the variable of input action asset.
And then we're going to get component of the player input and then get this input action asset.
That's the goal.
Yeah, I hope that makes sense.
Let's go back to script.
Over here.
I want to remove this line of code and this, um, player input.
I'll just brutally remove it, and instead we're going to make public input.
Input action asset, and it shows me an underlined error message because we do not use Unity's engine
input system.
Let's go all the way above and type using unity engine input system.
Okay, now it's fine and I want to give it the same name as I had before, so I'm going to name it as
player input.
Let's do get private set so we can use it in the future.
So we just basically changed the variable from a player input set to input action asset.
Now this one is like an empty variable of a type input action asset.
And we need to give it some value.
We need to assign it somewhere.
We're going to go to the awake method over here.
And instead of this we're going to do player input.
Equals to get component of a player input.
Actions.
All right.
So if you remember, actions over here is the same thing as action over here.
And the same thing is an action over here.
So that's basically what we're doing here.
We're just getting component of a player input that is used for player input manager to create players.
And then we get in this action asset from the component.
Okay.
And now what we need to do is change code over here.
And fortunately, now we have to look for action with a string.
And I don't really like it, but it does work.
So I guess I'll have to accept it because it works very well and it allows me to control different players
with different devices.
So instead of all of this, I'm going to go ahead over here.
And I'm going to type dot find action.
And now we need to give it name of the action.
And we know that action is named jump.
So I'm going to use jump over here.
Close the parentheses dot performed.
So that's the only change we need to do.
And if you change name of the actions in your input action asset make sure you change it in the script
as well.
Now we need to replace it here as well but not with a jump.
It should be movement and then over here as well.
But not with a jump.
It should be movement.
That's what we need to do.
Now I'm going to take this over here.
Remove it because I feel a bit lazy.
And I'm going to take these three lines of code.
Copy them, go here, paste them in and I'm going to change from plus to minus.
Minus.
Over here.
Very nice.
Now let's save this.
And let's go back to unity.
I'm going to go to play mode.
And I have a player that is controlled by the keyboard.
And also I can press start button on a game, but and I'm going to have a player that is controlled
by the gamepad, and both of them are controlled by different devices.
Isn't it cool?
Very very cool.
I love it so much, man.
Ta da!
Yes.
So we did a lot and yet we did a little bit.
I mean, like, there was not much of a change, but we made a huge change for the game.
Right.
Very cool one.
So I think I'm going to end the video with this.
Let's just apply overrides over here and let's apply overrides on the player.
Oh we don't need to do that.
And let's go to the next video.
We still have to do lots of changes for the system.
Okay, I'll see you there.