OnSerializeNetworkView PARTIAL data

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:

void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
	if (stream.isWriting)
	 {
		Vector3 posOut = transform.position; 
		Quaternion rotOut = transform.rotation; 
		bool drop = false;
		if(Input.GetKey ("joystick button 0"))drop=true;  
	 	stream.Serialize(ref posOut); 
		stream.Serialize(ref rotOut); 
		stream.Serialize(ref drop); 
	}else{
		stream.Serialize(ref posit);   // THIS WORKS ON ALL RECEIVING MACHINES
		stream.Serialize(ref rotat);   // THIS WORKS ON ALL RECEIVING MACHINES
 		stream.Serialize(ref dropwater);  //THIS WORKS on server, NOT other clients
		transform.position = posit; 
		transform.rotation = rotat;
		// turn on/off stuff from dropwater boolean
	}
}

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

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…

By the way, the NetworkView on the plane is watching the script that contains this OnSerializeNetworkView code…the above code.

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:

void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
    if (stream.isWriting)
     {
        Vector3 posOut = transform.position; 
        Quaternion rotOut = transform.rotation; 
        bool drop = false; -> false
        stream.Serialize(ref posOut); 
        stream.Serialize(ref rotOut); 
        stream.Serialize(ref drop);  -> will allways send false
    }else{
        Vector3 posin = Vector3.zero; 
        Quaternion rotin = Quaternion.identity; 
        bool tmpwaterbool = false;
        stream.Serialize(ref posin);
        stream.Serialize(ref rotin);
        stream.Serialize(ref tmpwaterbool);
        transform.position = posit; 
        transform.rotation = rotat;
        myboolinmycode = tmpwaterbool; -> will allways be false
    }
}

I had the joystick read in update before, but it makes no difference. Here is the whole NetMove.cs script:

using UnityEngine;
using System.Collections;

public class NetMove : MonoBehaviour 
{
Vector3 lastPosition;
static Vector3 posit = Vector3.zero; 
static Quaternion rotat = Quaternion.identity; 	
static bool dropwater; // try different default value, made no difference, dropwater is always false from NetworkMessageInfo info
static bool drop;
float minimumMovement = .05f;
static float NetViewTime=0.0f;
	

	void Update()
	{
			if(Input.GetKey ("joystick button 0"))drop=true;  // this is for water drop -- tested and working here, drop is true when trigger is set
			else drop = false;
	}
	void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
	{
		    if (stream.isWriting)
		    {
				Vector3 posOut = transform.position; 
				Quaternion rotOut = transform.rotation; 
				stream.Serialize(ref drop); // no matter where I put this, it fails on client 2
	 			stream.Serialize(ref posOut); 
				stream.Serialize(ref rotOut); 
		    }else{
				stream.Serialize(ref dropwater);
				stream.Serialize(ref posit); 
				stream.Serialize(ref rotat);
 				transform.position = posit;  // may need to lerp?
				transform.rotation = rotat;
				if(dropwater == false)
				{
					transform.GetComponentInChildren<ParticleEmitter>().particleEmitter.emit = false;
				}else{
					transform.GetComponentInChildren<ParticleEmitter>().particleEmitter.emit = true;
				}
			}
	}
	
}

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:

Thanks for you help Appels…

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.

It’s realy simple though:
Non-auth server example

using UnityEngine;

public class TestScript : MonoBehaviour
{

    public bool mybool = false;

	void Update()
    {
        if (networkView.isMine)
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                mybool = !mybool;
            }
        }
	}

    void OnSerializeNetworkView(BitStream stream)
    {
        if (stream.isWriting)
        {
            stream.Serialize(ref mybool);
        }
        else
        {
            bool tmpbool = false;
            stream.Serialize(ref tmpbool);
            mybool = tmpbool;
            Debug.Log(mybool);
        }
    }
}

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.

using UnityEngine;
using System.Collections;

public class NetMove : MonoBehaviour 
{
Vector3 lastPosition;
Quaternion rotat = Quaternion.identity; 	
bool dropwater = true; // try different default value, made no difference, dropwater is always false from NetworkMessageInfo info
bool drop = false;
bool lastdrop = true;
bool lasttmpbool = true;
	
	void Awake()
	{
	    if (!networkView.isMine)
	        enabled = false;
	}
	
	void Update()
	{
		if (networkView.isMine)		// this was, if (Network.isServer), before Spawn added
		{
		    Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
		    float speed = 10;
		    transform.Translate(speed * moveDir * Time.deltaTime);
			
			if(Input.GetKeyUp ("p"))
			{
				drop ^= true;
			}
			

		}
	}
	void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
	{
	    if (stream.isWriting)
	    {
		    Vector3 myPosition = transform.position;
		    Quaternion myRotation = transform.rotation;
			stream.Serialize(ref myPosition);
			stream.Serialize(ref myRotation);
			stream.Serialize(ref drop);
			if(drop == false  lastdrop == true)  // logic for one shot on/off
			{
				transform.GetComponentInChildren<ParticleSystem>().particleSystem.Stop();
				lastdrop = false;
			}
			if(drop == true  lastdrop ==false)
			{
				transform.GetComponentInChildren<ParticleSystem>().particleSystem.Play();
				lastdrop = true;
			}
	    }
	    else
	    {
	        Vector3 receivedPosition = Vector3.zero;
		    Quaternion recRotation = Quaternion.identity;
			bool tmpwaterbool;
	        stream.Serialize(ref receivedPosition); //"Decode" it and receive it
	        stream.Serialize(ref recRotation); //"Decode" it and receive it
			stream.Serialize(ref tmpwaterbool);
	        transform.position = receivedPosition;
	        transform.rotation = recRotation;
			if(tmpwaterbool == false  lasttmpbool == true) // logic for one shot on/off
			{
				transform.GetComponentInChildren<ParticleSystem>().particleSystem.Stop();
				lasttmpbool = false;
			}
			if(tmpwaterbool == true  lasttmpbool == false)
			{
				transform.GetComponentInChildren<ParticleSystem>().particleSystem.Play();
				lasttmpbool = true;
			}
	    }
	}
}

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…

1515602–86331–$UnityNetTest.unitypackage (29.4 KB)

Take a look at this. Simple clean code.

1515978–86379–$NetSync.unitypackage (17.6 KB)