Hello guys.
Welcome to the video.
And now we have one slight problem in the game.
As of now we cannot know who is player one.
Who is player two.
What I mean by that.
Let's say I joined with the GamePad as a player one.
This is my first layer, then I.
Sorry, I forgot to change player count.
Okay, so then I joined with a keyboard as a second player.
That is my second player.
Now, if one of them dies and then second one dies, now we don't know who was player number one, who
was player number two.
And if you join a game with a keyboard first, which is supposed to be the second player, now this
will be a first player you can see in the list.
It is a first player.
So this what we need to fix.
We need to remember the player number.
We need to remember the players device.
And also if we know player number we can give it a skin that player is supposed to have.
That he will choose in the menu before game starts.
So let's do that.
First of all, let's change max player count to two because we're going to have two players.
And now let's go to player manager.
And I'm going to explain how we're going to do this.
So there is no direct way to just get the device that was used.
Maybe there is that I don't know about, but there's no like input device.
Like debugging input device.
We have to check all of the devices that were used for the input, and usually it returns only one device.
I don't know, this is how it works.
So what we have to do here is something very simple.
We need to go over here and we can do for each var.
Device in player.
Devices.
We're going to do debug log.
Device dot name.
So we're going to see what it does.
And.
Now I'm going to join the game.
And we can see a message Xinput controller windows.
Same goes for keyboard.
Um, again, this is how we got to do it.
There is no other way.
Like maybe there is a way that I don't know about, but I couldn't get the device straight ahead from
a like player device.
You can see there is no such variable.
So we're going to use for each.
But it doesn't matter.
It still works very well for us.
Just something that I'm very curious about, but I can then get the device directly.
Maybe because there may be a device that has two like input that can have two devices like keyboard
and mouse, I don't know.
So what we're going to do here, we're going to make.
An array of possible devices.
Let's do serialized field.
Serialize field.
Private string array.
Player device, this one going to have an array of four strings.
Let's go back and I'm making it as four, because I assume there can be maximum of four players in the
game.
Okay.
And this is like a slot for the device.
And I'm going to make them empty.
Empty, empty.
Empty by default.
Just like that.
Um, now we can go back.
And since this is a string that says empty, and also since we can get the name of a device inside of
a player method, we can just check if field is empty and if it is empty, we can take device name and
put it into that slot.
That's what I want to do.
Let's make for each.
VAR device in layer.
Devices.
Maybe let's rename it to new player just in case.
New player a bit cleaner, right?
Easier to understand what is happening.
Okay.
Now inside of this foreach we're going to run for loop for the array of devices.
Okay.
As a length, we're going to use the player device dot length.
So we run in for loop for the each device we run in for loop of the uh, array of the strings we have.
And over here we're going to check each slot in this array.
So we're going to do this.
If layer device with a I is says empty it means we have an empty slot.
We can fill it up with the variable.
And I'm going to do that layer device with the I.
Equals to Devicename.
And now if we fill an app slot with a variable of a device name, it means that we did the job.
The job is done.
We found an empty slot.
We filled it with a device.
We don't need to use this for loop anymore.
Like any longer.
We don't need to check anything else.
We don't need to proceed.
So I'm going to just type here break and this will break the for loop.
Also just so we can better understand why we're doing this, let's debug a message player.
Plus I'm going to do plus uh, I plus one because I want to have a proper player's number and I'm going
to type joined.
The game.
Uh, let's go to unity now and let's see what we have.
As a result, we're going to go back.
Going to go to play mode.
And I'm joining with a gamepad and we can see we've got player device.
Our first layer says Xinput controller windows.
And also there is a message in the console player plus one joined the game.
Okay.
Same goes for keyboard player two.
Join the game and let's go back.
Over here.
I want to remove this plus.
And now let's check if player that joined before rejoining the game.
We can do that by again checking player devices.
String.
Let's do else if player device with the I is equals to device dot name, it means that player with a
device that was recognized before is rejoining the game.
And we're going to do debug log player plus I plus one plus three.
Joined.
The game.
And also, let's just break the.
Or loop because we did detect that player rejoined the game.
Let's go and try this again.
We're going to go to game and I'm going to use gamepad and join player one.
Join the game.
Going to go ahead and destroy the player.
Now I'm going to rejoin and we can see player one rejoin the game.
So now we can have information about same player rejoining the game with the same device, which is
very, very cool and convenient.
Let me do collapse like that.
Okay.
Now, uh, we not only have device being stored in this, uh, array of strings, but also, now that
we have device being stored here, we can get the player's number by just getting access to the, um,
index of the element.
So now let's make a method that would return an integer of a player number.
And then we would use this code over here to detect the player number.
And then we would return the number to null the number of a player.
Uh let's go over here and let's make private int get player number.
We need to pass the player input here, and I'm going to just name it as player device.
Then we're going to need int new player number.
It's going to be equals to zero by default.
But we're going to update the value inside of this for loop.
Let's take this code over here I'm going to cut it out.
Go here, paste it in.
In the end, after four each, we're going to return new player number.
And then we just need to wait.
What is it?
Should not be like that.
This should be new player.
Let's name it as new player.
Okay.
So now over here, instead of debugging a message, we're just going to change the number because we
know how it works.
We know why we're doing this.
We're doing this to check if player joined for the first time or rejoin in the game.
But basically we just need to keep track of the same player.
Right.
So we're going to do new player number equals to I here as well.
New player number equals to I.
Just like that.
And now we can go back.
To this method, and we can use it to detect which player joined the game.
As of now, I'm just going to do a debug log.
Uh, let's do get player number with a new player.
Last message joined the game.
Okay.
Very good.
So let's go ahead and try this.
And then I'm going to show you how to apply skins on players that just join the game.
Uh, zero.
Join the game.
Well, this is the first one.
We know it.
I'm going to just join again.
Zero.
Join the game again.
I'm going to kill it.
Join the game.
Sorry.
Let me kill it.
And join the game.
Now the another one.
Join the game.
Okay.
It works, I love it.
Now let's go back and let's use this number to apply skin on the character.
Uh, how it's going to work.
Well, it will require a bit of a rework, but it's fine.
So on the skin manager over here before we had this, choose skin ID and we could get the skin ID and
set skin ID, but we did it just for one player, so it did work fine just like that.
But now we'll have to change it, and we will have to turn it into an array because we might have multiple
players in the game.
Let's take this chosen skin ID, let's rename it to skin ID.
And let's make it work as an array.
Okay.
This is good.
Now we have to go here.
And instead of setting skin ID directly, we also need to get end player number to set the skin ID.
And now we're going to do something like this.
Skin ID with a player number equals to ID be passing through the method.
And on the get skin ID we need to pass in player number.
And then.
Skin ID with a player number.
Yeah, this is a bit better.
Very good.
Let's save this and we can adjust this manually.
We're going to use menu to change this variable later on.
But as of now let's let's do it manually in the inspector.
And also there are must be some errors that we need to fix.
Yes.
Okay.
Uh, this one going to be fixed later on.
But as of now.
Not to worry about it.
Let's just ask it for zero, okay?
Let me see other errors.
We just need to fix it for now, because later on it's going to be used in a different way.
I'm going to comment this out.
Uh, this one over here.
Select skin.
Let's just, uh, do skin index and pass zero over here.
Because, again, it doesn't matter what we fix in here, it's going to be changed later.
We just want to avoid errors so we can continue development.
Get skin ID with a zero.
It's fine.
Good.
Let's go back to unity now.
And let's go ahead and find managers.
Prefab managers, skin manager.
Over here we have four elements.
And let's say that first layer chose the pink man, second layer chose the ninja frog.
And these two can be empty because it doesn't matter.
Now let's go back to.
Let's go back to player manager.
And over here I'm going to do int skin ID.
Or maybe new player skin ID equals to skin manager dot instance.
Get skin ID and now we need to use player number that we can get with this method.
I could just pass it here but I wanted to do a bit cleaner.
So I'm going to do new player.
Number equals to get player number with a new player.
And then we can use this variable over here.
New player number.
Now that we have skin ID we can pass it to the player to update the skin.
Um.
Let's go to player script.
And over here we have this update skin method which is updating the skin through the saved value in
a player prefs.
But now since we have a bunch of players, it should be used in a different way.
So over here in the start I'm going to remove this update skin method.
I'm not going to use it anymore.
And then we need to go to this update skin method.
And we can see it's not used anywhere now because it has zero references.
And we just need to pass int skin index.
Over here.
And then in the animators over here, we're going to use skin index.
Okay.
Now there is something else.
We're going to have a bug.
Now that we need to fix.
It's going to be very easy to fix.
But first I want you to see this bug.
Before we fix it, let's go to player manager.
And now we're going to get player script that we got before update skin.
And we're going to give it new player skin ID.
So the logic is fine, it's supposed to work, but it's going to have an error message.
Let's go back to unity.
Let's try to join the game.
We know that first player should have a pink man, and I can see there is a null reference exception
that leads us to the, uh, anim line of code over here.
So what happens is something I would say kind of strange, not supposed to be like that, but it happens.
And the problem is that by the time we are trying to update, the skin, player does not yet have a
reference to the animator.
And that's why we can see that message of null reference exception.
We can easily fix it by directly getting the animator at the time of uh, method being called.
I'm going to do Getcomponent in Children of Animator.
Uh, here.
Just like that.
And this will solve the problem.
Let's save this and let's go back to unity.
Going to go to play mode.
And now let me join the game.
There is a pink man.
Very cool.
I'm going to join as a second player on the Ninja Frog.
And this is the GamePad player.
Ninja frog.
Now I'm going to kill the both players.
And now I'm going to join with the GamePad first, which is a second player.
And even though he's joining the first, he's supposed to be player number two.
Let's check this.
Yes.
Player number two.
So everything works fine.
I love it again, ignore this message for now.
We're going to fix it later on.
And we did achieve the goal.
Now.
Now we can know the information about layer number.
We can update the skin if we want to.
And all of this works perfectly good for us.
Okay, let's save the project and let's go to the next video.