WEBVTT

00:00.000 --> 00:00.420
Hello guys.

00:00.420 --> 00:01.230
Welcome to the video.

00:01.230 --> 00:04.590
In this section I want to show you how to make local multiplayer.

00:04.590 --> 00:10.230
We're going to make a co-op player mode where two players can play together, and the system works in

00:10.230 --> 00:13.110
a way that if you want, you can make more players.

00:13.110 --> 00:16.410
3 or 4 is fine as long as you have input devices.

00:16.410 --> 00:21.690
As for me, I'm going to use keyboard and gamepad to make the system and to check everything, as I

00:21.690 --> 00:26.640
assume that most of the people who are doing this course are going to have keyboard and one gamepad.

00:26.670 --> 00:29.100
All right, now let me show you what we're going to do here.

00:29.100 --> 00:32.490
I'm going to take my prototype project and enter the play mode.

00:32.490 --> 00:35.010
And I'm going to use gamepad so we can go to new game.

00:35.010 --> 00:39.990
We can choose how many players is going to play, for example two on a normal difficulty.

00:39.990 --> 00:42.420
Now first player is supposed to select the skin.

00:42.420 --> 00:47.400
Let's say first player is a pink man and second player can be a ninja frog.

00:47.400 --> 00:48.720
We're going to click select.

00:48.720 --> 00:50.430
Then we need to select level.

00:51.550 --> 00:56.410
Now over here, we need to display some kind of message that would say press button to join.

00:56.410 --> 00:58.750
And we're going to do that in the end of the section.

00:58.750 --> 01:00.580
Then we're going to press join button.

01:00.580 --> 01:02.680
And there is a player that you can control.

01:02.680 --> 01:07.210
And also you can press any key on the keyboard as a second player to join the game.

01:07.420 --> 01:08.770
And this is what we're going to do.

01:08.770 --> 01:11.410
And both of them are controlled by different devices.

01:11.410 --> 01:17.800
And also, uh, the system we made will remember which player has which skin and controlling device.

01:17.800 --> 01:20.320
So every time player presses input from a gamepad.

01:20.470 --> 01:25.690
So every time player presses input from a gamepad, he's going to have character that he chose, even

01:25.690 --> 01:26.800
if both of them dead.

01:26.800 --> 01:28.480
And now there is no one.

01:28.480 --> 01:31.060
And player from the keyboard will do the input.

01:31.060 --> 01:32.500
Who's supposed to be the second player?

01:32.500 --> 01:34.360
He will be the second player.

01:34.540 --> 01:37.660
All right, so that's the system we're going to make in this section.

01:37.660 --> 01:38.980
And it's going to be a lot.

01:38.980 --> 01:39.760
To be honest.

01:39.760 --> 01:42.700
Till yesterday I was thinking there's going to be very easy.

01:42.700 --> 01:45.010
You just make a couple of prefabs and make it work.

01:45.010 --> 01:49.630
But I learned from experience that I actually have to set up entire system for this, and it took me

01:49.630 --> 01:51.850
maybe 3 or 4 hours to come up with this.

01:51.850 --> 01:53.860
So I hope you will like it.

01:53.860 --> 01:55.450
All right, let's begin.

01:55.510 --> 01:59.710
Uh, first of all, we need to adjust the way how player manager works.

01:59.710 --> 02:04.180
As of now, we have sort of custom player manager that respawns the player.

02:04.690 --> 02:09.670
Uh, let me go to prefabs and take the player manager over here.

02:10.550 --> 02:13.130
So this is the custom player manager we have.

02:13.370 --> 02:20.510
But if you want to have a local multiplayer, it will be easier to use Player Input Manager from unity,

02:20.510 --> 02:26.420
because that one can automatically assign control and devices to the character it creates.

02:26.450 --> 02:31.400
So that's why we need to go here and add component of a player input manager.

02:31.430 --> 02:36.260
Now thanks to this component, unity now can listen to the devices that were used.

02:36.260 --> 02:39.680
And if someone pressed the join button, it's going to make a new player.

02:39.680 --> 02:40.340
For us.

02:40.340 --> 02:44.180
That means we don't need to use prefab on a player manager anymore.

02:44.180 --> 02:47.000
So let's go ahead and clean this up a little bit.

02:48.990 --> 02:54.090
So over here, uh, let's take these, uh, line of code.

02:54.090 --> 02:55.650
I just need it in the future.

02:55.650 --> 02:59.310
So I'm gonna paste it in here and comment this out.

03:00.580 --> 03:05.380
And these two methods can be removed for now because we're going to use different system later on.

03:05.380 --> 03:08.500
So let's just delete these two methods okay.

03:08.500 --> 03:10.750
Now let's go all the way above.

03:10.750 --> 03:17.050
And let's remove player prefab and respawn delay because again we're not going to use them.

03:18.240 --> 03:23.670
I'm going to save the script, and there may be a couple of errors in unity that we need to fix real

03:23.670 --> 03:24.300
quick.

03:25.230 --> 03:29.490
Yeah, there is one on a dead zone that tries to respawn the player.

03:29.490 --> 03:30.750
Let's remove it.

03:32.450 --> 03:34.370
And let's see what else is there.

03:38.020 --> 03:39.730
Um, there is this one.

03:40.500 --> 03:41.940
Action on player respawn.

03:41.940 --> 03:45.510
I guess it says that action is not being invoked anywhere.

03:45.510 --> 03:47.070
Yeah, it's never used.

03:47.100 --> 03:47.970
Okay.

03:48.000 --> 03:48.480
Um.

03:49.770 --> 03:54.240
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

03:54.240 --> 03:55.830
not give us an error message.

03:55.830 --> 03:56.430
All right.

03:56.670 --> 03:57.450
Cool.

03:57.450 --> 04:03.300
So now we don't have a prefab on our player manager, but we need to create player somehow.

04:03.300 --> 04:06.630
Well we're going to do that with the help of player input manager.

04:06.630 --> 04:13.860
First of all let's change send message to invoke events because we're going to need to check when player

04:13.860 --> 04:19.200
joined the game so we can add some functionality like update skin of the player or update the position

04:19.200 --> 04:19.830
of the player.

04:19.830 --> 04:27.540
Then there is a join behavior and I want to have join action is triggered as a join behavior.

04:27.540 --> 04:28.740
That's what I want to do.

04:29.620 --> 04:35.590
So first we need to go and make the action on the, uh, input action editor.

04:36.100 --> 04:37.150
Over here.

04:37.150 --> 04:40.750
Let's delete the post action.

04:40.840 --> 04:42.610
Actually, we can just use it.

04:42.670 --> 04:47.650
Let's rename this from post to join.

04:48.620 --> 04:51.710
I think I did delete this in the like in one of the videos.

04:51.710 --> 04:52.070
Why?

04:52.070 --> 04:53.510
It's why is it here?

04:53.960 --> 04:55.070
This is so weird.

04:55.070 --> 04:57.230
Okay, I'm going to just delete it in case you don't have it.

04:57.230 --> 04:59.510
And I'm going to show you how to make it from the start.

04:59.510 --> 05:03.860
We're going to click plus over here and we're going to name it as uh join.

05:04.720 --> 05:05.290
Game.

05:05.290 --> 05:05.890
Maybe.

05:07.040 --> 05:13.730
All right then, over here, we need to choose a device that we want to use for joining and also a button.

05:13.880 --> 05:19.370
As for keyboard, let's just find keyboard and find any key.

05:19.370 --> 05:21.830
Or if you want you can use enter key.

05:22.460 --> 05:24.380
Yeah, but I'll use any key.

05:25.890 --> 05:26.970
Any key.

05:27.180 --> 05:27.930
Okay.

05:28.840 --> 05:30.280
You also need another button.

05:30.280 --> 05:35.770
Let's add binding and let's do a gamepad.

05:35.770 --> 05:37.960
I'm going to type start over here.

05:37.960 --> 05:39.430
Start on a gamepad.

05:39.790 --> 05:40.180
Also.

05:40.180 --> 05:45.280
Now we're using start button to pause the game from a gamepad on a UI over here.

05:45.280 --> 05:49.840
And it will pause the game and it will join the player at the same time.

05:49.840 --> 05:55.150
We're going to take care of this later on, but as of now, let's just fix it in a very simple way.

05:55.150 --> 06:02.470
Let's change pause button from start to something else like select for example, select button on a

06:02.470 --> 06:03.190
gamepad.

06:07.260 --> 06:08.970
So it will not interfere.

06:08.970 --> 06:10.860
Let's save the asset.

06:17.090 --> 06:24.410
Now we can, uh, go over here to join behavior, and we're going to change it to join player when join

06:24.410 --> 06:25.730
action is triggered.

06:26.970 --> 06:28.890
And then we need to choose the action.

06:28.890 --> 06:30.780
We're going to click Use Reference.

06:30.780 --> 06:35.790
Then we need to click this dot over here and find this join game action.

06:37.600 --> 06:38.680
This is the one.

06:39.070 --> 06:40.900
Okay, I'm going to choose it.

06:40.900 --> 06:41.920
This is nice.

06:41.920 --> 06:47.080
Now this player input manager want to have a prefab so it knows what the player is.

06:47.530 --> 06:48.970
Uh, we're going to go to.

06:50.160 --> 06:52.200
Asset prefab folders.

06:52.200 --> 06:56.610
There is a player and we're going to drag this over here to the prefab field.

06:56.640 --> 07:00.960
Now this is supposed to work as it is right now, but it will not.

07:00.960 --> 07:02.100
Uh, let's just try it.

07:02.100 --> 07:04.260
Let's see what it's going to show us.

07:04.260 --> 07:06.000
And I want you to know about this.

07:06.000 --> 07:09.210
I'm going to use my gamepad, and I'm going to press the start button.

07:09.210 --> 07:11.100
And you can see we have a message.

07:11.100 --> 07:15.390
The game object does not have a player input component on it.

07:16.400 --> 07:23.090
Because of that player input manager cannot recognize this player prefab as a player, and that's what

07:23.090 --> 07:24.500
we need to fix right now.

07:26.960 --> 07:29.330
Um, let's go to player prefab.

07:29.330 --> 07:35.870
Actually, we have it over here and we need to go ahead and add.

07:36.770 --> 07:38.660
Player input component.

07:39.250 --> 07:45.160
Now, later on, we're going to need to use this player input component to assign actions.

07:45.160 --> 07:48.460
So two player is going to be controlled by two different devices.

07:48.460 --> 07:51.850
So we're going to need to type get component of a player input.

07:51.850 --> 07:57.160
But I was smart enough to and that is a sarcastic comment.

07:57.160 --> 08:00.160
That was a very uh bad decision.

08:00.160 --> 08:03.550
I named player input as player input.

08:04.790 --> 08:06.830
As well as the script player input.

08:06.830 --> 08:13.400
And now if you try to get a component of a player input over here, it might search for this script

08:13.400 --> 08:16.700
of a player input because it has the very same name.

08:16.700 --> 08:18.800
The solution here is very simple.

08:18.800 --> 08:21.200
First of all, let's take this player input.

08:21.200 --> 08:23.480
Let's rename it to Player Input set.

08:25.210 --> 08:26.080
Oh, no.

08:26.080 --> 08:27.880
It created another script.

08:27.880 --> 08:28.390
It's okay.

08:28.390 --> 08:29.980
I'm going to delete it from here.

08:31.320 --> 08:32.460
Let me delete it.

08:34.670 --> 08:35.480
It's fine.

08:35.480 --> 08:36.110
No worries.

08:36.110 --> 08:38.870
And then let's go to this player input script.

08:38.900 --> 08:41.150
We're gonna take the name.

08:44.560 --> 08:46.660
And we're going to rename this to.

08:47.390 --> 08:48.410
Player.

08:49.100 --> 08:56.540
Input set and before you confirm it, make sure you have checked rename symbols file so it will rename

08:56.540 --> 08:58.040
file in unity as well.

08:58.070 --> 08:59.810
Now I'm going to press enter.

09:02.210 --> 09:04.700
It's going to change the name everywhere.

09:05.000 --> 09:07.700
And if I close Visual Studio.

09:08.360 --> 09:13.850
I'm going to have player input set over here with this name as well as in the script over here.

09:13.850 --> 09:14.630
Right.

09:14.630 --> 09:18.710
And because of that, now we can get component freely on a player in the future.

09:18.710 --> 09:22.940
This was a very bad decision that I did and I'm sorry I did that.

09:22.940 --> 09:23.480
All right.

09:23.480 --> 09:26.420
Now we need to assign actions over here.

09:26.420 --> 09:28.340
Let's assign it like that.

09:29.480 --> 09:31.010
Over here we can choose default scheme.

09:31.010 --> 09:36.110
I'm going to choose keyboard and I want to disable auto switch and default map will be player.

09:36.110 --> 09:36.980
Nice.

09:36.980 --> 09:38.360
Now we have this.

09:38.360 --> 09:41.450
Let's take overrides and let's apply them.

09:41.450 --> 09:43.550
Let's double check player manager.

09:43.550 --> 09:46.490
It has a prefab and everything should be ready.

09:47.000 --> 09:48.260
Let's go to player mode.

09:48.260 --> 09:50.870
And now I'm going to try to join new player.

09:50.870 --> 09:52.580
There's the one with the keyboard.

09:52.580 --> 09:56.690
Now I'm going to press start button on a gamepad and I join the player.

09:56.690 --> 10:01.160
The only problem now is that we can control both players with one device.

10:01.160 --> 10:05.840
Both of them can be controlled with the gamepad right now, and if I put my gamepad down and use my

10:05.840 --> 10:08.570
keyboard, both of them are controlled as well.

10:08.570 --> 10:10.610
So that's the fix we need to apply right now.

10:10.610 --> 10:12.920
And actually it's not that difficult to do.

10:12.950 --> 10:15.110
We just need to do one simple change.

10:15.500 --> 10:21.740
Uh, on the player script, we created this new instance of a player input.

10:22.970 --> 10:24.020
Uh, right here.

10:24.020 --> 10:25.430
This is what we do, right?

10:25.850 --> 10:34.220
And when player input manager creates a prefab with a player input component, with this component,

10:34.220 --> 10:37.940
it automatically gives it a device to control the player.

10:37.940 --> 10:45.590
And now instead of creating new player input, uh, instance, just like we do now in the script, we

10:45.590 --> 10:52.040
need to get access to this component, and then we need to get access to exactly this action map that

10:52.040 --> 10:56.000
is under this component in this field of actions over here.

10:56.000 --> 10:58.010
This is what we need to use for the input.

10:58.010 --> 11:01.220
So each player will be recognized as a different one.

11:01.310 --> 11:01.640
Right.

11:01.640 --> 11:07.130
That's what we need to do because as of now when we have two players, we create a new instance of controls

11:07.130 --> 11:08.930
for uh, each of them.

11:08.930 --> 11:16.190
But each of them, even with the new one, are controlled by, um, one device or two devices.

11:16.190 --> 11:19.400
It's just like one player that has two input devices.

11:19.400 --> 11:20.300
That's what it does.

11:20.300 --> 11:25.580
And this is how it works in a version of the game for a single player, which is totally fine because

11:25.580 --> 11:29.090
you can take the keyboard, you can play the game, then you can change your mind.

11:29.090 --> 11:31.670
You can switch to gamepad and use gamepad to play the game.

11:31.670 --> 11:34.040
So in that case, that is just what we need.

11:34.040 --> 11:37.610
But in this case, each player should be controlled by different device.

11:37.610 --> 11:40.250
That's why we're going to go ahead to the script.

11:41.040 --> 11:47.040
And change the system a little bit from create a new instance in the code over here, we're going to

11:47.040 --> 11:47.790
change it.

11:48.750 --> 11:51.270
To the variable of input action asset.

11:51.270 --> 11:57.600
And then we're going to get component of the player input and then get this input action asset.

11:57.600 --> 11:58.620
That's the goal.

11:59.560 --> 12:01.390
Yeah, I hope that makes sense.

12:01.510 --> 12:02.860
Let's go back to script.

12:04.580 --> 12:05.330
Over here.

12:05.330 --> 12:11.300
I want to remove this line of code and this, um, player input.

12:11.300 --> 12:17.090
I'll just brutally remove it, and instead we're going to make public input.

12:18.970 --> 12:27.820
Input action asset, and it shows me an underlined error message because we do not use Unity's engine

12:27.820 --> 12:28.840
input system.

12:28.840 --> 12:33.970
Let's go all the way above and type using unity engine input system.

12:34.450 --> 12:40.090
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

12:40.090 --> 12:41.380
player input.

12:41.830 --> 12:44.980
Let's do get private set so we can use it in the future.

12:44.980 --> 12:51.010
So we just basically changed the variable from a player input set to input action asset.

12:51.010 --> 12:54.940
Now this one is like an empty variable of a type input action asset.

12:54.940 --> 12:57.250
And we need to give it some value.

12:57.250 --> 12:58.960
We need to assign it somewhere.

13:00.220 --> 13:02.890
We're going to go to the awake method over here.

13:02.890 --> 13:06.640
And instead of this we're going to do player input.

13:07.640 --> 13:10.940
Equals to get component of a player input.

13:12.640 --> 13:13.690
Actions.

13:14.400 --> 13:15.090
All right.

13:15.090 --> 13:20.880
So if you remember, actions over here is the same thing as action over here.

13:20.880 --> 13:23.610
And the same thing is an action over here.

13:23.610 --> 13:25.680
So that's basically what we're doing here.

13:25.680 --> 13:31.530
We're just getting component of a player input that is used for player input manager to create players.

13:31.530 --> 13:35.670
And then we get in this action asset from the component.

13:36.520 --> 13:37.240
Okay.

13:38.280 --> 13:42.240
And now what we need to do is change code over here.

13:42.240 --> 13:46.110
And fortunately, now we have to look for action with a string.

13:46.110 --> 13:48.600
And I don't really like it, but it does work.

13:48.600 --> 13:54.630
So I guess I'll have to accept it because it works very well and it allows me to control different players

13:54.630 --> 13:55.920
with different devices.

13:55.920 --> 14:00.180
So instead of all of this, I'm going to go ahead over here.

14:01.260 --> 14:05.610
And I'm going to type dot find action.

14:06.580 --> 14:08.530
And now we need to give it name of the action.

14:08.530 --> 14:10.690
And we know that action is named jump.

14:10.690 --> 14:12.460
So I'm going to use jump over here.

14:12.550 --> 14:14.590
Close the parentheses dot performed.

14:14.590 --> 14:16.510
So that's the only change we need to do.

14:16.510 --> 14:21.370
And if you change name of the actions in your input action asset make sure you change it in the script

14:21.370 --> 14:22.120
as well.

14:22.120 --> 14:25.960
Now we need to replace it here as well but not with a jump.

14:25.960 --> 14:30.700
It should be movement and then over here as well.

14:31.490 --> 14:32.720
But not with a jump.

14:32.720 --> 14:34.490
It should be movement.

14:34.490 --> 14:35.780
That's what we need to do.

14:35.900 --> 14:38.330
Now I'm going to take this over here.

14:39.490 --> 14:41.560
Remove it because I feel a bit lazy.

14:41.560 --> 14:43.750
And I'm going to take these three lines of code.

14:44.580 --> 14:51.060
Copy them, go here, paste them in and I'm going to change from plus to minus.

14:51.960 --> 14:52.680
Minus.

14:52.680 --> 14:53.520
Over here.

14:53.520 --> 14:54.420
Very nice.

14:54.420 --> 14:56.310
Now let's save this.

14:57.600 --> 14:59.610
And let's go back to unity.

15:01.960 --> 15:03.550
I'm going to go to play mode.

15:04.470 --> 15:06.960
And I have a player that is controlled by the keyboard.

15:06.960 --> 15:11.040
And also I can press start button on a game, but and I'm going to have a player that is controlled

15:11.040 --> 15:14.970
by the gamepad, and both of them are controlled by different devices.

15:15.000 --> 15:15.990
Isn't it cool?

15:16.410 --> 15:17.520
Very very cool.

15:17.520 --> 15:18.690
I love it so much, man.

15:19.500 --> 15:20.250
Ta da!

15:20.820 --> 15:21.540
Yes.

15:21.540 --> 15:24.900
So we did a lot and yet we did a little bit.

15:24.900 --> 15:29.550
I mean, like, there was not much of a change, but we made a huge change for the game.

15:29.550 --> 15:30.000
Right.

15:30.000 --> 15:30.990
Very cool one.

15:30.990 --> 15:33.600
So I think I'm going to end the video with this.

15:33.600 --> 15:39.450
Let's just apply overrides over here and let's apply overrides on the player.

15:39.450 --> 15:40.800
Oh we don't need to do that.

15:40.800 --> 15:42.390
And let's go to the next video.

15:42.390 --> 15:45.000
We still have to do lots of changes for the system.

15:45.000 --> 15:46.590
Okay, I'll see you there.
