New Input System using same gamepad Input for all players local multiplayer

Hi Unity Community,
alright so bear with me. I am quite new to programming and not quite good at it…
I’m making a local multiplayer split-screen game in which each player drives a pick-up truck and has to collect randomly spawning crates. The split-screen works and all the trucks are set up, just the new input system doesn’t quite do what it’s supposed to do. Each truck is getting the same input, so when I have one controller connected I can control all 4 trucks simultaneously. When I connect a second controller I still control all trucks. I am not quite sure how to assign one controller to one player.

This is how I get the input:

    private void Awake()
    {
        input = new ControllerInput();
        input.Player.Steer.performed += ctx => m_stickMovement = ctx.ReadValue<Vector2>();
        input.Player.Steer.canceled += ctx => m_stickMovement = Vector2.zero;
        input.Player.Accelerate.performed += ctx => m_RTButton = ctx.ReadValue<float>();
        input.Player.Accelerate.canceled += ctx => m_RTButton = float.MinValue;
        input.Player.Reverse.performed += ctx => m_LTButton = ctx.ReadValue<float>();
        input.Player.Reverse.canceled += ctx => m_LTButton = float.MinValue;
        input.Player.Handbrake.performed += ctx => OnHandbrake();
        input.Player.HandbrakeRelease.canceled += ctx => OnHandbrakeRelease();
    }

In my methods I then calculate my car physics and call them in FixedUpdate.

private void FixedUpdate()
    {
        currentSpeed = frontDriverW.rpm; //rpm is the current wheel axle rotation speed in rotations per minute
      
        if (currentSpeed < maxSpeed && m_RTButton > 0.1f)
        {
          
            OnAccelerate();
        }
        else
        {
            if (currentSpeed > maxSpeed)
            {
                frontDriverW.motorTorque = maxSpeed;
                frontPassengerW.motorTorque = maxSpeed;
            }
        }
      
        if (m_LTButton > 0.1f)
        {
          
            OnReverse();
        }
      
        OnSteer();
        UpdateWheelPoses();
    }

This is my PlayerInputManager:

Note: Before starting the game you choose the amount of players playing. So depending on that, the amount of trucks will be set to active.

And this is my PlayerInputComponent each of the trucks has:

Anyone might know what I’m doing wrong?
I would be very grateful for any help and I’m really sorry for my horrible knowledge of coding :x.

Liz

1 Like

Caveat: I haven’t used the new input system yet.

It might be something needs to be hooked up in there… do you have linkages for all four controllers? If not, maybe work through a tutorial on setting up two player local.

1 Like

Please never say sorry just because you’re a beginner, we’ve all been there. And you asked a far better structured question than the vast majority of the beginner forumers here.

As of your approach to the problem. I think you started to do things on your own way too early.
In the Package Manager, under the Input System there is a Samples section.
5932790--634625--answer.PNG

Download the Simple Multiplayer sample in a new project and check out how they set up the project. It is also a couch-multiplayer, so essentially what you need.
The trick is that you won’t do the same thing as you would for single player, instead you will set up a player prefab and let the system instantiate it for you when the player joins in.
One thing though: in the sample there is no camera before the first player join, don’t be alarmed. :slight_smile:

In your own game you will need a camera before that in order to show menu and whatnot but you can subscribe to the player join event somehow where you can disable your own camera, so the players’ cameras will render properly.
Check out the sample, it worth the time it contains a lot of good trick to develop a simple couch multi game!

Oh and in the sample there is only one action: teleport, so just don’t get frustrated when nothing is moving as normal. :smile:
You can easily add the movement yourself.

Good luck with your project and don’t forget to share the result with us!

2 Likes

@Kurt-Dekker
I did watch through several tutorials and it always seems to work for them. They also never linked any controllers in their script :confused: But I will try to check again! :slight_smile: Thank you~

@
Thanks for the hint! I did check the Simple Multiplayer they provided. Since each truck is a bit different I cannot use a player prefab. I have set my PlayerInputManager to “Join Players Manually”.
5934407--634847--upload_2020-6-3_12-2-52.png
Before you start the game you choose how many players are playing. Depending on that, my trucks as well as my cameras will already be in the scene. For instance: You choose 3 players, Camera 4 and Player 4 will be set to inactive while the others are set to active. Maybe that’s what’s I’m doing wrong?
Also in my script, apart from the OnHandbrake and OnHandbrakeRelease, I don’t directly call the methods in Awake. I assign the value given from the input into a variable and use this variable to calculate my physics and then call them in Fixed Update… I guess overall I kind of got confused with my whole script. But I will continue to look into this issue and hopefully fix it soon and be able to share the result! :smile:

I see, in this case could you please show us where you join your players?

Honestly, I haven’t played with this system too much just yet, I didn’t have the time to play with local multi.
But my understanding is this (regarding the issue):
Your problem is that every control moves every player (otherwise everything is okay, separate players show up, they are different, everything works, except for the input). This makes me think that all of your players respond to the inputs, so the inputs aren’t instances but one object for everyone. Let’s see an example:

input.Player.Steer.performed += ctx => m_stickMovement

(I have semantic problems with these as well, but they are secondary, I wouldn’t call my method “m_stickMovement”, it’s steering.)

But more importantly in this m_stickMovement method how do you decide which player to move? Because you’re subscribed to the input action directly in your Awake method.

If I understand the PlayerInputManager API correctly (I may not, I see this for the first time, to be honest), you have the PlayerJoinedEvent. And I suspect that the parameter PlayerInput will be an instance of the controls for this instantiated player.

So I still would look at their solution and follow it and doing only the joining manually.

Disclaimer: if my response sounds messy and uncertain, that’s because it is. I’ve never used this system in practice.

Hahaha. I (we) haven’t thought the most obvious solution for your problem.
https://discussions.unity.com/t/781427/3

You basically can change the prefab in the manager, so the next joining player will have the next prefab when joins. So you can stick to the automatic join this way. You just need to reset it when a new game happens.

1 Like

Oh my @ , you are so right haha!
I will definitely try this out and as soon as I got it working, give some feedback :slight_smile:
Thanks for your help!

@ I just want to say thank you for your help!
I was able to fix my issue :slight_smile: I will try to explain it as good as I can in case other people might have similiar problems :smile:
So for once, the problem why I was able to control all player instances with one controller was, because my InputActionAsset in the Player Input Component wasn’t being copied.
I did change the join behaviour to “Join Players When Button Is Pressed” again to take care of this problem. The InputActionAsset was now being copied, when a new Player joined. I also assigned my Player Prefab for it to work.

To still join different looking prefabs on different positions, I wrote two additional Scripts. One which only gets the MeshRenderer of my prefab. The second one takes different colors and positions. In this script, in my PlayerJoin method (which is being called as soon as a gamepad is connected and taking a PlayerInput parameter), I was able to get my prefab over the parameter and change it’s color as well as it’s position.
So when a player joins, he / she now spawns with a different color and position.

God I was so happy when I got it fixed furious clapping
Hope to show some of it soon!

3 Likes

Congratulations, and I’m looking forward to it! Keep it up!

1 Like

Has anyone figured out how to subscribe to the PlayerJoinedEvent?