Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question InputActions not reaching ThirdPersonController in multiplayer

Discussion in 'Input System' started by umbrella-crash, Sep 6, 2022.

  1. umbrella-crash

    umbrella-crash

    Joined:
    Mar 3, 2022
    Posts:
    20
    I hope someone here can explain what I'm doing wrong. This problem is happening in very specific circumstances. I've managed to narrow down what's happening, but I'm stuck at this point. It seems to be related to timing.

    I'm making a relatively simple multiplayer game using Photon PUN2 and the Unity Starter Assets including their ThirdPersonController, StarterAssets.inputactions and the StarterAssetsInputs.cs script (among other stuff).

    For the first player who creates a room and spawns into the scene, everything works fine. The second player who joins the room and spawns into the scene is where things get tricky.

    If the second players spawns in a Start() method that runs right after the scene loads, then things seem to work fine. The player can move the character around. The first character is visible, controlled from the other client (a Start() method in a script on the player character checks to see if PhotonView.IsMine, and disables the ThirdPersonController if it is not). So far so good.

    But if the second player spawns in with a delay, the input actions don't get to the ThirdPersonController anymore. This delay can be as simple as a one second wait in the same method that was spawning them before.

    The reason for the delay is to get some user input before spawning the character. At first I thought this was related to an interaction between that UI and the player controller inputs. However, even when I remove all UI, this happens, unless the player spawns at scene start time on their client. It turns out the only reason the UI caused a problem is because it delayed the spawning.

    Tracing things through, I've found that the Input Actions are firing, and the StarterAssetsInputs script is receiving them and changing its states. What seems to have happened, as nearly as I can tell, is that the ThirdPersonController of the second character is holding a different instance of the StarterAssetsInputs. So the original instance is being updated, but the controller is looking at a different one that isn't receiving events from the input actions.

    Does anyone here have an idea of what is happening? Why I'm getting a different StarterAssetsInputs when instantiation is delayed? What I should do about any of this? I'm probably misunderstanding something about how these parts are supposed to be put together.

    I'm using 2022.1.15f1.
    Thanks for any pointers!
     
    Enemony likes this.
  2. umbrella-crash

    umbrella-crash

    Joined:
    Mar 3, 2022
    Posts:
    20
    I finally figured it out. In case someone else has a similar problem and ends up here, this is my understanding (still incomplete), and how to fix it. (And if someone else has a better understanding of why this happens with Starter Assets, I'd appreciate it if you'd add your explanation.)

    In the configuration I'm using, it turns out only the first character with a PlayerInput component enabled will actually receive player input. Others will end up with a different instance of the components and not receive any input. I think this is a difference in Starter Assets from the way it usually works.

    Anyway, to make the problem go away, disable the PlayerInput component on each player character prefab. Doing this in the editor makes sure it is disabled when the character is instantiated. Then, in the Start() function of a script attached to the player character, check to see if the character is the one you want player input for. (In my case, this means querying
    photonView.IsMine
    .) For that one character, enable the PlayerInput component.
    GetComponent<PlayerInput>().enabled = true;
    That's it.
     
    stevekrile, UnityGuy1717 and Enemony like this.
  3. UnityGuy1717

    UnityGuy1717

    Joined:
    Mar 20, 2020
    Posts:
    13
    @umbrella-crash Thank you very much for providing your solution. My setup is a bit different, but this solved the problem for me as well! Greatly appreciate it!!
     
    umbrella-crash likes this.
  4. stevekrile

    stevekrile

    Joined:
    Jul 17, 2023
    Posts:
    5
    Just to put a ribbon on this answer, if you are using Client Authoritative I found adding this script to the player with a PlayerInput attribute does the trick.

    Code (CSharp):
    1.    
    2. private void Start()
    3.     {
    4.         if(IsLocalPlayer)
    5.         {
    6.             gameObject.GetComponent<PlayerInput>().enabled = true;
    7.         }
    8.     }
    9.