Search Unity

How to synchronize rotations over OnSerialize() and Commands

Discussion in 'Multiplayer' started by ClausKleber, Aug 28, 2015.

  1. ClausKleber

    ClausKleber

    Joined:
    Aug 17, 2015
    Posts:
    6
    Hello,

    I am trying to sync my character bone rotations over the network. So for that I've wrote my own OnSerialize() an on OnDeserialize() function to sync the rotation list syncTransforms.

    Code (CSharp):
    1. public override bool OnSerialize(NetworkWriter writer, bool initialState) {
    2.     base.OnSerialize(writer, initialState);
    3.  
    4.     foreach (Transform trans in syncTransforms) {
    5.         writer.Write(trans.localRotation);
    6.     }
    7.     return true;
    8. }
    9.  
    10. public override void OnDeserialize(NetworkReader reader, bool initialState) {
    11.     base.OnDeserialize(reader, initialState);
    12.  
    13.     if (!isLocalPlayer) {
    14.         foreach (Transform trans in syncTransforms) {
    15.             trans.localRotation = reader.ReadQuaternion();
    16.         }
    17.     }
    18. }
    But unfortunately the OnSerialize() method is only called on server and not on the client which has the authority. So I have a few questions.
    1. Is there a way that OnSerialize() runs on the client with authority?
      If not my first idea is to send every frame from the authority client a command to the server with the rotation list.
    2. But if I do that how can I send the command only on the next network update step and not on every frame which would create an unnessessary command queue?
      The OnSerialize() function is called every network update, is this right?
    3. And how can I declare the OnSerialize() function to send on the unreliable channel only?
    In the case somebody knows a better way to update this rotations please let me know.

    Thanks a lot!
     
    Last edited: Aug 28, 2015
  2. Firoball

    Firoball

    Joined:
    Aug 6, 2015
    Posts:
    62
    Normally you send a Command [Command] from Client to Server containing the pressed buttons, and do all movement on the server.

    On the server you can either use [SyncVar] for autoamted synching or write a custom OnSerialize routine (both in the same script is not possible) which you have to trigger by setting at least one DirtyBit. If you don't set any DirtyBits, OnSerialize won't be triggered.

    For sending on unreliable Channel prefix your class with a custom attribute:

    Code (CSharp):
    1. [NetworkSettings(channel=1)]
    2. public class blabla : NetworkBehaviour
    3. {
    4. //do fancy stuff here
    5. }
    channel 1 is the default unreliable channel.
     
  3. ClausKleber

    ClausKleber

    Joined:
    Aug 17, 2015
    Posts:
    6
    Thank's for your answer!
    It was not clear to me that I have to seperate any [SyncVar] and OnSerialize() function in several NetworkBehaviour classes.

    But I wonder now when I have to send my [Command] to server. In every frame?
    The network rate is much less than the unity update rate. So this makes no sense to me because this will write the commands in a buffer but the server needs only the newest command.
     
    Last edited: Aug 31, 2015
  4. Firoball

    Firoball

    Joined:
    Aug 6, 2015
    Posts:
    62
    Either collect data over several frames and send all of it every x ms (input data can be compressed very well), or grab and send input data only on fixed update rate.