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.

Unity Multiplayer [Solved] Spawning Player Controlled objects are controlled by any player

Discussion in 'Multiplayer' started by Boierism, May 6, 2018.

  1. Boierism

    Boierism

    Joined:
    Nov 3, 2017
    Posts:
    4
    Hello,

    I'm trying to set up for a multiplayer game where each player can pick a player model to play with. I've organized the general things as follows:

    On connecting, a player object is generated for each player. This player object will handle the team on which the player will spawn (player presses 1 / 2 for the team) and then it handles what model the player will have (again, only 2 models just to try things out). I added a prefab list to the player object that contains the 2 model prefabs.

    After the player chooses team and prefab, the following code will handle the spawning:


    Code (CSharp):
    1.     [Command]
    2.     void CmdSpawn(int _team, int _model)
    3.     {
    4.         if (!m_isSpawned)
    5.         {
    6.             m_team = _team;
    7.             m_model = _model;
    8.  
    9.             Vector3 spawnLocation = Spawner.GetSpawnerInstance().GetSpawnPosition(m_team);
    10.             GameObject go = (GameObject)Instantiate(m_modelPrefabs[m_model - 1], spawnLocation, Quaternion.identity);
    11.             m_isSpawned = NetworkServer.SpawnWithClientAuthority(go, connectionToClient);
    12.         }
    13.     }
    This works just fine, the player models and team appear as expected.

    However when I attempt to move the object, both player objects are being moved.

    The following info might be relevant:
    The player prefabs have the local player authority set.
    When debugging the server, I can see in the networking info that both player models have local authority true.
    In the model controller script, I'm checking for player authority before moving. (snippet below)

    Code (CSharp):
    1.     void FixedUpdate()
    2.     {
    3.         if (!localPlayerAuthority)
    4.             return;
    5.  
    6.         Vector3 _velocity = m_movementDirection * m_speed;
    7.  
    8.         m_velocity = _velocity;
    9.  
    10.         // apply movement
    11.         if (_velocity != Vector3.zero)
    12.         {
    13.  
    14.             m_rb.MovePosition(m_rb.position + _velocity * Time.fixedDeltaTime);
    15.         }
    16.     }
    Any kind of help is much appreciated, I think I already spend 3 hours on trying to get this to work and can't seem to be able to get it done.
     
  2. forcepusher

    forcepusher

    Joined:
    Jun 25, 2012
    Posts:
    227
    Hello. I think you meant to use isLocalPlayer or hasAuthority instead of localPlayerAuthority.
     
    Last edited: May 7, 2018
  3. Boierism

    Boierism

    Joined:
    Nov 3, 2017
    Posts:
    4
    I have tried using "isLocalPlayer" however the object is separated from the player object so the isLocalPlayer property is false.
     
  4. Boierism

    Boierism

    Joined:
    Nov 3, 2017
    Posts:
    4
    Update:

    I managed to fix half of the problem. I added an RPC call to disable the player model controller when I'm spawning it:

    Code (CSharp):
    1.     [Command]
    2.     void CmdSpawn(int _team, int _model)
    3.     {
    4.         if (!m_isSpawned)
    5.         {
    6.             m_team = _team;
    7.             m_model = _model;
    8.  
    9.             Vector3 spawnLocation = Spawner.GetSpawnerInstance().GetSpawnPosition(m_team);
    10.             GameObject go = (GameObject)Instantiate(m_modelPrefabs[m_model - 1], spawnLocation, Quaternion.identity);
    11.             m_isSpawned = NetworkServer.SpawnWithClientAuthority(go, connectionToClient);
    12.  
    13.             RpcEnableControls(go);
    14.         }
    15.     }
    16.  
    17.     // this should only disable the controls for the other players
    18.     [ClientRpc]
    19.     void RpcEnableControls(GameObject _rb)
    20.     {  
    21.         if (!isLocalPlayer)
    22.             _rb.GetComponent<PlayerModelController>().enabled = false;
    23.     }
    If I have one instance of the game hosting and another one connected to it and then I spawn all the instances, the controller works fine.

    However If I connect after one is already spawned, the model controller will be enable on it and the player who connected late will be able to move all the player models.

    Haven't really got time this morning to go through this, figured I post it early to keep the discussion going if someone wants to throw some tips.
     
  5. Boierism

    Boierism

    Joined:
    Nov 3, 2017
    Posts:
    4
    Look at me talking to myself...

    Just had a shower thought before leaving for work. I figured I could disable the player model controller on the prefabs so by default nobody can control the model, and enable it on spawn just for the local player.

    This way whenever one player connects he generates the model and then enables the controller for him.

    I guess this thread can be closed now.

    Special thanks to:
    https://en.wikipedia.org/wiki/Rubber_duck_debugging