Search Unity

Only last player joined is able to synch

Discussion in 'Multiplayer' started by Tim-Falken, Sep 18, 2014.

  1. Tim-Falken

    Tim-Falken

    Joined:
    Jan 11, 2013
    Posts:
    3
    Hello,

    I've started creating a multiplayer game in which the players move as you would in an FPS.

    I set it up in such a way that each game has it's own local player controller, which then controls a player object. The player object then uses OnSerializeNetworkView to synchronize it's position.

    When you join a game, i use Network.Instantiate to spawn a player object. You can then look around and walk. The server will show you walking around. However, when the server's player then moves, the newly connected client does not see the server's player moving.

    Then, when another player connects, only that player is shown moving on all other screens.

    So it seems that only the last connected player is able to synchronize it's position over the network. I've been staring at my code for quite a while, and I can't seem to figure out why this is happening.


    This is what's supposed to happen:
    • Server starts or a player joins it, a playercontroller already in the scene locally
    • playercontroller Network.Instantiates a player object
    • local playercontroller gets the input, and starts a function causing the playerObj to move.
    • playerObj synchronizes it's position and rotation using OnSerializeNetworkView
    I'm having some trouble explaining this, so if it's unclear let me know :)


    Here are all the scripts I believe are related to this:
    Local Controller
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class LocalController : PlayerControllerBase
    5. {
    6.     void LateUpdate()
    7.     {
    8.         if(isActive)
    9.         {
    10.             playerObject.AdjustAim (mouseXMovement, mouseYMovement);
    11.             playerObject.Move(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
    12.  
    13.             Camera.main.transform.position = playerObject.transform.position;
    14.             Camera.main.transform.rotation = playerObject.verticalJoint.transform.rotation;
    15.         }
    16.     }
    17. }
    PlayerControllerBase which the local controller derives from:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerControllerBase : MonoBehaviour
    5. {
    6.     [SerializeField] private FirstPersonController firstPersonControllerPrefab;
    7.     [SerializeField] protected FirstPersonController playerObject;
    8.     protected float mouseXMovement, mouseYMovement;
    9.  
    10.     protected bool isActive{ get; private set; }
    11.  
    12.     void Update ()
    13.     {
    14.         if((Network.isServer || Network.isClient) && playerObject == null)
    15.         {
    16.             isActive = true;
    17.             playerObject = (FirstPersonController)Network.Instantiate (firstPersonControllerPrefab, Random.insideUnitSphere * 5, Quaternion.identity, 1);
    18.             playerObject.ControlFromLocalMachine = true;
    19.         }
    20.  
    21.         mouseXMovement = Input.GetAxis ("Mouse X");
    22.         mouseYMovement = -Input.GetAxis ("Mouse Y");
    23.  
    24.         Screen.lockCursor = isActive;
    25.     }
    26. }
    27.  
    FirstPersonController, the player object that moves around and does stuff.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class FirstPersonController : NetworkEntity
    5. {
    6.     [SerializeField] public GameObject verticalJoint;
    7.     private Quaternion verticalJointRotation;
    8.  
    9.  
    10.     protected override void NetworkSerialize (BitStream stream, float networkDeltaTime)
    11.     {
    12.         if(!IsClient)
    13.             verticalJointRotation = verticalJoint.transform.rotation;
    14.  
    15.  
    16.         base.NetworkSerialize (stream, networkDeltaTime);
    17.  
    18.         stream.Serialize (ref verticalJointRotation);
    19.     }
    20.  
    21.     public override void ClientUpdate ()
    22.     {
    23.         base.ClientUpdate ();
    24.  
    25.         verticalJoint.transform.rotation = Quaternion.Lerp(verticalJoint.transform.rotation, verticalJointRotation, 0.5f);
    26.     }
    27.  
    28.     public void AdjustAim(float hor, float vert)
    29.     {
    30.         transform.Rotate (0, hor, 0);
    31.         verticalJoint.transform.Rotate (vert, 0, 0);
    32.     }
    33.  
    34.     public void Move(float x, float z)
    35.     {
    36.         transform.position += transform.forward * z + transform.right * x;
    37.  
    38.         transform.position += Vector3.up * -transform.position.y;
    39.     }
    40. }
    41.  
    NetworkEntity that the player object derives from:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent(typeof(NetworkView))]
    5. public class NetworkEntity : MonoBehaviour
    6. {
    7.     public static bool IsClient;
    8.     protected float networkDelay;
    9.  
    10.     private Vector3 pos;
    11.     private Quaternion rot;
    12.  
    13.     public bool ControlFromLocalMachine;
    14.  
    15.     void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    16.     {
    17.         networkDelay = (float)(Network.time - info.timestamp);
    18.        
    19.         NetworkSerialize (stream, networkDelay);
    20.     }
    21.  
    22.     protected virtual void NetworkSerialize(BitStream stream, float networkDeltaTime)
    23.     {
    24.         if(!IsClient)
    25.         {
    26.             pos = transform.position;
    27.             rot = transform.rotation;
    28.         }
    29.        
    30.         stream.Serialize(ref pos);
    31.         stream.Serialize(ref rot);
    32.     }
    33.  
    34.     public virtual void ClientUpdate()
    35.     {
    36.         transform.position = Vector3.Lerp(transform.position, pos, 0.5f);
    37.         transform.rotation = Quaternion.Lerp(transform.rotation, rot, 0.5f);
    38.     }
    39.  
    40.     public virtual void ServerUpdate()
    41.     {
    42.  
    43.     }
    44.  
    45.     void Update()
    46.     {
    47.         IsClient = !ControlFromLocalMachine;
    48.  
    49.         if(IsClient)
    50.         {
    51.             ClientUpdate();
    52.         }
    53.         else
    54.         {
    55.             ServerUpdate();
    56.         }
    57.     }
    58. }
    59.  
    I have no clue how a newly connected player can cause the other players to stop synchronizing, but I'm probably simply missing something. Any help is appreciated!