Search Unity

OnSerializeNetworkView PARTIAL data

Discussion in 'Multiplayer' started by jbarbeau, Jan 31, 2014.

  1. jbarbeau

    jbarbeau

    Joined:
    Dec 21, 2012
    Posts:
    46
    I have the network working in a flight simulator. Each plane has a NetworkView that is watching NetMove.cs script.

    I pass the movement of the planes in OnSerializeNetworkView AND a boolean value like this:

    Code (csharp):
    1.  
    2. void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    3. {
    4.     if (stream.isWriting)
    5.      {
    6.         Vector3 posOut = transform.position;
    7.         Quaternion rotOut = transform.rotation;
    8.         bool drop = false;
    9.         if(Input.GetKey ("joystick button 0"))drop=true;  
    10.         stream.Serialize(ref posOut);
    11.         stream.Serialize(ref rotOut);
    12.         stream.Serialize(ref drop);
    13.     }else{
    14.         stream.Serialize(ref posit);   // THIS WORKS ON ALL RECEIVING MACHINES
    15.         stream.Serialize(ref rotat);   // THIS WORKS ON ALL RECEIVING MACHINES
    16.         stream.Serialize(ref dropwater);  //THIS WORKS on server, NOT other clients
    17.         transform.position = posit;
    18.         transform.rotation = rotat;
    19.         // turn on/off stuff from dropwater boolean
    20.     }
    21. }
    22.  
    23.  

    As you can see in the comments, some of the data doesn't get through to Clients. ALL data gets to the server. All clients and the Server move this Network.Instantiated object correctly, but the boolean value fails, but ONLY on other clients than the one that Instantiated the object.

    I've tried moving the boolean value to the top, and using a different NetworkView on the object to pass the value, nothing works.... It's always the same, the server works but other clients don't.

    Anybody know why?

    Thanks
     
  2. jbarbeau

    jbarbeau

    Joined:
    Dec 21, 2012
    Posts:
    46
    This is still a mystery to me, does anyone have an idea? It's not groups or ViewID because some of the data works fine.

    I am using 1 machine to debug 2 instances, one launched in a brower, and one in the editor.... the same IP of course, I don't know why that would cause PARTIAL data. I will try 3 totally separate machines, I'll report back....
     
  3. jbarbeau

    jbarbeau

    Joined:
    Dec 21, 2012
    Posts:
    46
    By the way, the NetworkView on the plane is watching the script that contains this OnSerializeNetworkView code...the above code.
     
  4. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    stream.isWriting is called on the server side.
    So this line:
    if(Input.GetKey ("joystick button 0"))drop=true;
    will only be called on the server, move that code in an update method.

    Also this:
    Code (csharp):
    1. void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    2. {
    3.     if (stream.isWriting)
    4.      {
    5.         Vector3 posOut = transform.position;
    6.         Quaternion rotOut = transform.rotation;
    7.         bool drop = false; -> false
    8.         stream.Serialize(ref posOut);
    9.         stream.Serialize(ref rotOut);
    10.         stream.Serialize(ref drop);  -> will allways send false
    11.     }else{
    12.         Vector3 posin = Vector3.zero;
    13.         Quaternion rotin = Quaternion.identity;
    14.         bool tmpwaterbool = false;
    15.         stream.Serialize(ref posin);
    16.         stream.Serialize(ref rotin);
    17.         stream.Serialize(ref tmpwaterbool);
    18.         transform.position = posit;
    19.         transform.rotation = rotat;
    20.         myboolinmycode = tmpwaterbool; -> will allways be false
    21.     }
    22. }
     
  5. jbarbeau

    jbarbeau

    Joined:
    Dec 21, 2012
    Posts:
    46
    I had the joystick read in update before, but it makes no difference. Here is the whole NetMove.cs script:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class NetMove : MonoBehaviour
    5. {
    6. Vector3 lastPosition;
    7. static Vector3 posit = Vector3.zero;
    8. static Quaternion rotat = Quaternion.identity;  
    9. static bool dropwater; // try different default value, made no difference, dropwater is always false from NetworkMessageInfo info
    10. static bool drop;
    11. float minimumMovement = .05f;
    12. static float NetViewTime=0.0f;
    13.    
    14.  
    15.     void Update()
    16.     {
    17.             if(Input.GetKey ("joystick button 0"))drop=true;  // this is for water drop -- tested and working here, drop is true when trigger is set
    18.             else drop = false;
    19.     }
    20.     void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    21.     {
    22.             if (stream.isWriting)
    23.             {
    24.                 Vector3 posOut = transform.position;
    25.                 Quaternion rotOut = transform.rotation;
    26.                 stream.Serialize(ref drop); // no matter where I put this, it fails on client 2
    27.                 stream.Serialize(ref posOut);
    28.                 stream.Serialize(ref rotOut);
    29.             }else{
    30.                 stream.Serialize(ref dropwater);
    31.                 stream.Serialize(ref posit);
    32.                 stream.Serialize(ref rotat);
    33.                 transform.position = posit;  // may need to lerp?
    34.                 transform.rotation = rotat;
    35.                 if(dropwater == false)
    36.                 {
    37.                     transform.GetComponentInChildren<ParticleEmitter>().particleEmitter.emit = false;
    38.                 }else{
    39.                     transform.GetComponentInChildren<ParticleEmitter>().particleEmitter.emit = true;
    40.                 }
    41.             }
    42.     }
    43.    
    44. }

    The variables used for position are pushed on the stack (local) and work fine, but I made both dropwater and drop booleans a static variable.

    You said:
    but stream.isWriting happens on Client1.... (unless I am misunderstanding something on authoritative/nonauthoritative. I think I'm using non-authoritative server.) I can see the data writing on Client1.

    Here's a picture that may explain what is happening better:
    $Drop Network Problem.jpg
     

    Attached Files:

  6. jbarbeau

    jbarbeau

    Joined:
    Dec 21, 2012
    Posts:
    46
    Thanks for you help Appels....
     
  7. jbarbeau

    jbarbeau

    Joined:
    Dec 21, 2012
    Posts:
    46
    Appels.....Actually your statement in the line:

    myboolinmycode = tmpwaterbool; -> will always be false

    Isn't correct.

    tmpwaterbool is passed by reference to stream.serialize(), and data is put into it.

    I confirmed this by using your code exactly, and setting tmpwaterbool to true, I get false out all the time on the 2nd client... it never changes, output is always false.

    I'm still puzzling over this.....

    SOMEONE must have made the NetworkView work passing more than position and rotation..... besides this simple boolean value, I need to pass animation states, and other things. HOW? I need to understand what's going wrong.
     
  8. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    It's realy simple though:
    Non-auth server example
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class TestScript : MonoBehaviour
    4. {
    5.  
    6.     public bool mybool = false;
    7.  
    8.     void Update()
    9.     {
    10.         if (networkView.isMine)
    11.         {
    12.             if (Input.GetKeyDown(KeyCode.Space))
    13.             {
    14.                 mybool = !mybool;
    15.             }
    16.         }
    17.     }
    18.  
    19.     void OnSerializeNetworkView(BitStream stream)
    20.     {
    21.         if (stream.isWriting)
    22.         {
    23.             stream.Serialize(ref mybool);
    24.         }
    25.         else
    26.         {
    27.             bool tmpbool = false;
    28.             stream.Serialize(ref tmpbool);
    29.             mybool = tmpbool;
    30.             Debug.Log(mybool);
    31.         }
    32.     }
    33. }
     
  9. jbarbeau

    jbarbeau

    Joined:
    Dec 21, 2012
    Posts:
    46
    It is simple, and should work, that's what is so frustrating.

    To zero in on the problem I made a project with a little as possible. Just 2 scripts for network code, and no assets to speak of just a cube with a particle system attached to turn on and off using the "p" key to toggle.

    Here's the NetMove.cs code that the NetworkView on the Cube is watching.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class NetMove : MonoBehaviour
    5. {
    6. Vector3 lastPosition;
    7. Quaternion rotat = Quaternion.identity;    
    8. bool dropwater = true; // try different default value, made no difference, dropwater is always false from NetworkMessageInfo info
    9. bool drop = false;
    10. bool lastdrop = true;
    11. bool lasttmpbool = true;
    12.    
    13.     void Awake()
    14.     {
    15.         if (!networkView.isMine)
    16.             enabled = false;
    17.     }
    18.    
    19.     void Update()
    20.     {
    21.         if (networkView.isMine)     // this was, if (Network.isServer), before Spawn added
    22.         {
    23.             Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
    24.             float speed = 10;
    25.             transform.Translate(speed * moveDir * Time.deltaTime);
    26.            
    27.             if(Input.GetKeyUp ("p"))
    28.             {
    29.                 drop ^= true;
    30.             }
    31.            
    32.  
    33.         }
    34.     }
    35.     void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    36.     {
    37.         if (stream.isWriting)
    38.         {
    39.             Vector3 myPosition = transform.position;
    40.             Quaternion myRotation = transform.rotation;
    41.             stream.Serialize(ref myPosition);
    42.             stream.Serialize(ref myRotation);
    43.             stream.Serialize(ref drop);
    44.             if(drop == false  lastdrop == true)  // logic for one shot on/off
    45.             {
    46.                 transform.GetComponentInChildren<ParticleSystem>().particleSystem.Stop();
    47.                 lastdrop = false;
    48.             }
    49.             if(drop == true  lastdrop ==false)
    50.             {
    51.                 transform.GetComponentInChildren<ParticleSystem>().particleSystem.Play();
    52.                 lastdrop = true;
    53.             }
    54.         }
    55.         else
    56.         {
    57.             Vector3 receivedPosition = Vector3.zero;
    58.             Quaternion recRotation = Quaternion.identity;
    59.             bool tmpwaterbool;
    60.             stream.Serialize(ref receivedPosition); //"Decode" it and receive it
    61.             stream.Serialize(ref recRotation); //"Decode" it and receive it
    62.             stream.Serialize(ref tmpwaterbool);
    63.             transform.position = receivedPosition;
    64.             transform.rotation = recRotation;
    65.             if(tmpwaterbool == false  lasttmpbool == true) // logic for one shot on/off
    66.             {
    67.                 transform.GetComponentInChildren<ParticleSystem>().particleSystem.Stop();
    68.                 lasttmpbool = false;
    69.             }
    70.             if(tmpwaterbool == true  lasttmpbool == false)
    71.             {
    72.                 transform.GetComponentInChildren<ParticleSystem>().particleSystem.Play();
    73.                 lasttmpbool = true;
    74.             }
    75.         }
    76.     }
    77. }
    78.  
    I've uploaded the UnityPackage called UnityNetTest, that exhibits this problem. You need to run 3 instances to see the issue. Server and client can see the particle System turn on and off correctly with the "p" key. Client 2 does NOT turn on ever. Notice the translation and rotation of the cubes all work on all machines.

    I HAVE to solve this, so I appreciate any help. It makes no sense, I may have something wrong, but if you can show me what, I'd greatly appreciate it.....

    Thanks.....
     

    Attached Files:

  10. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    Take a look at this. Simple clean code.
     

    Attached Files: