Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Resolved] Unity 5.2 NetworkWriter.Write(byte[] buffer, int offset, int count) uses offset in 5.2

Discussion in 'Multiplayer' started by chrismarch, Sep 18, 2015.

  1. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    470
    I'm attempting to upgrade my project from 5.1.1f1 to 5.2.0p1 (Windows). I am running into a serialization mismatch on the (non-host) clients, where they read the wrong number of bytes from their NetworkReaders. I am building my server and clients with matching versions of Unity. Any API changes that could lead to this? I noticed NetworkClient.isConnected for the first time during this process, as the client was attempting to send when NetworkClient.active was true, and I received a new error in this case, which I prevent by checking NetworkClient.isConnected.

    Did the behavior of NetworkClient.active, such as whether it returns true when connected or not, change in 5.2?
     
  2. tapticc

    tapticc

    Joined:
    Jan 16, 2014
    Posts:
    379
  3. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    NetworkClient.active is static (global), and is true if any NetworkClient instance exists. Primary useful to check if you are running on a server or a client.

    client.isConnected is an instance member variable (not global) that is true if that particular client is connected to a server.
     
  4. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    470
    I still haven't tracked down the issue. The serialization mismatch doesn't happen on a host sending to its own client, but only on our server to separate client. I get a lot of errors on the client where (I think) the deserialization tries to read too much, like this
     
  5. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    is it generated SyncVar code or custom serialization functions?

    is there Networkbeahviour script script inheritance?
     
  6. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    470
    Everything is pointing to our custom serialization functions. Here is how our OnDeserialize methods tend to look, ever since the change where they can be called with zero dirty bits:

    Code (CSharp):
    1. public override void OnDeserialize(NetworkReader reader, bool initialState)
    2. {
    3.     uint syncVarDirtyBits = 0xFFFFFFFF; // TODO rename, now that the NetworkBehaviour property shares this name
    4.     if (!initialState)
    5.     {
    6.         syncVarDirtyBits = reader.ReadPackedUInt32();
    7.     }
    8.      
    9.     if (syncVarDirtyBits != 0)
    10.     {
    11.         // read the network reader for the bits dirty
    12.     }
    13. }
    What is a NetworkBehaviour script script interface?
     
  7. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    "inheritance"... if there is a base class that is also a NetworkBehaviour, you must also call it's OnDeserialize function
     
  8. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    470
    Do you mean things that derive from NetworkBehaviour indirectly? Like
    Code (CSharp):
    1. class Foo : NetworkBehaviour { ... }
    2. class Bar : Foo { ... }
    So, are you suggesting I need this:
    Code (CSharp):
    1. class Foo : NetworkBehaviour {
    2.     ... OnDeserialze(...) { ...}
    3. }
    4.  
    5. class Bar : Foo {
    6.     ... OnDeserialize(...) {
    7.         base.OnDeserialize(...);
    8.         ....
    9.     }
    10. }
    The only case we have like that is where Foo (parent class) has sealed overrides for OnSerialize and OnDeserialize, and the child classes do not use SyncVar or SyncList, they just override a helper function.
     
    Last edited: Sep 22, 2015
  9. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    470
    The buffers in the NetworkReaders recieved by the client in OnDeserialize are smaller than the ones written to by the server, using the same build. The server finishes a message, writing to position 23 in a buffer with a 4 byte "header" (written to by the HLAPI/EndMessage?). The client receives a buffer with only 20 bytes, including a 6 byte header. This only occurs in 5.2, not 5.1.
     
    Last edited: Sep 22, 2015
  10. Firoball

    Firoball

    Joined:
    Aug 6, 2015
    Posts:
    60
    Are you using the built-in network simulator? There were issues like that reported before and using some external simulatio instead made the problem go away.
     
  11. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    Can you set NetworkConnection.logNetworkMessages to see the difference?
     
  12. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    470
    NetworkEmulation is set to None, but thanks for the heads up.
     
  13. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    470
    So, NetworkWriter.Write(byte[] buffer,int offset, int count) ignored offset for versions before 5.2, and now that it uses it, my code broke.
     
    Last edited: Sep 22, 2015
    seanr likes this.