- Home /
Why is this duplicate object not behaving like the original?
This is a weird problem to describe, so I'll try my best.
Essentially, I am making a 2 player 2D platformer-fighting game game that involves 2 players moving at the same time using WASD for player 1 and IJKL for player 2 (there will be buttons for attacking and using potions later but I don't have code for that right now). Currently, I have fully working animations on my Player 1 GameObject for Idle, Walk, Block, and Jump. The movement on this GameObject work great and I can control it just how I want to. Now, to make player 2, I just duplicated the Player 1 GameObject and checked a box in my Player Movement script that specifies that it is player 2. The problem with this Player 2 GameObject is that when I do a single jump (because in my game you can do a double jump, I have the code for that already) the jump animation immediately switches to Idle state and you're able to start blocking before reaching the ground, which is not the intention. This doesn't happen with the Player 1 object; I can only block if I am on the ground, which is good.
Here are the relevant scripts:
Player Movement: https://pastebin.com/X8VdRmar Character Controller: https://pastebin.com/0hUKUNSj
Here are pictures of the project:
Scene Hierarchy: https://i.imgur.com/7MIZpL7.png Player 1 Inspector: https://i.imgur.com/JWAyhJt.png Player 2 Inspector: https://i.imgur.com/fLMWSDE.png
Video depiction of the problem: https://www.youtube.com/watch?v=ACdvrwxzBs0&feature=youtu.be
Tell me if you need more info, I tried to provide as much as I could. Thanks :)
Answer by MacDx · Jun 06, 2019 at 07:44 PM
This is an interesting one. I can't pinpoint the exact issue here but I can give you some insight into why I think this is happening. To answer your question, Why is this duplicate object not behaving like the original? it is because inside that duplicate object code, you are somehow trying to manage 2 separate instances of itself.
That is a very weird way of doing things and I recommend against it. The player movement class is meant to move a player right? Good object oriented programming says it shouldn't matter what player, it should just move a player. This means that it is not supposed to contain code that tries to figure out what player he is trying to move out of whatever number of players.
How would I solve this? There are many ways. You could abstract the player as an ID and have a wrapper object for the inputs tied to that ID, or you could have an input manager that reads every input you need and then just passes the info to the appropriate player instance and stuff like that but for this case, and just so you can test it out quickly, try doing this:
Get rid of the isPlayer2 variable. This is the root cause of the problem in your logic.
In the PlayerMovement script get rid of every if/else check that is meant to identify player 1 or 2. Basically just make the code control a single player.
Add the three following string fields to your script, axisID, jumpID and crouchID (You can make them public or private with serialize field like in the controller script, you will set them on the inspector)
In the inspector for player1 set the three variables to Horizontal, Jump and Crouch, as for player2 I think you should understand by now what I'm suggesting.
Then on every call to Input.GetBlaBla("string") replace the hard coded string with the correct variable. For example, instead of Input.GetAxisRaw("Horizontal") write Input.GetAxisRaw(axisID).
After that just try running the game to see if the problem is solved. The advantage of this is that you now have the certainty that both players are completely independent since their code is not trying to move them and at the same time verify who is who. And so, figuring the bug (if it is still there) would be a lot simpler this way.
I hope this helps! If you have any questions please go ahead and ask, I'll be happy to answer.
Okay, it happened again. I did change my movement scrip though, so here's an updated version of that.
What I am noticing is that when Player 1 jumps, the animation plays through while he's in the air and then it stops once he lands on the ground, how it should be. Then I select Player 2 in the Animator window and I see that the $$anonymous$$night_Jump animation gets canceled out of almost immediately and it switches to $$anonymous$$night_Idle, a state that can transition into $$anonymous$$night_BasicAttack meaning that Player 2 can Basic Attack while he's in the air, which is not the intent.
Here's a video of how Unity looks when the issue is happening: https://www.youtube.com/watch?v=Q98S1-L0zv4&feature=youtu.be
Answer by MrPieGaming · Jun 07, 2019 at 01:26 AM
So it turns out that after my friend imported some things to the project, both Players work perfectly fine now (What he imported has no relation to the scripts, so I really don't know why it works now). The Player 1 GameObject behaves how it should and the Player 2 GameObject also behaves how it should. This was such an odd glitch. But thank you for your reply, your idea seems pretty smart and if I have any troubles like this in the future when I'm adding other characters I'll revisit this thread.
Here's an updated version of my PlayerMovement script by the way: https://pastebin.com/z2w47nU8
EDIT: The problem happened again. I replied above with more info.