Search Unity

SendInterval and position sync

Discussion in 'Multiplayer' started by shoo, Mar 7, 2016.

  1. shoo

    shoo

    Joined:
    Nov 19, 2012
    Posts:
    67
    Hello! I am trying to sync transform position manually based on UNET tutorial. I removed lerp function and made sendInterval = 0.5 but object movement was really smooth, and deltaTime was like ~0.004 so seems Update() of NetworkBehaviour don't care about sendInverval option. So how I can use sendInterval? I want to reduce my network sends to 60 per 1 second instead of doing sends on every update!

    Code (CSharp):
    1.  
    2. [NetworkSettings(sendInterval = 0.5f)]
    3. public class Player_SyncPosition : NetworkBehaviour {
    4.  
    5.     [SyncVar]
    6.     private Vector3 syncPos;
    7.  
    8.     [SerializeField]
    9.     Transform myTransform;
    10.     [SerializeField]
    11.     float lerpRate = 15;
    12.  
    13.     // Update is called once per frame
    14.     void Update () {
    15.         Debug.Log(Time.deltaTime);
    16.         TransmitPosition();
    17.         LerpPosition();
    18.     }
    19.  
    20.     void LerpPosition()
    21.     {
    22.         if (!isLocalPlayer)
    23.         {
    24.             myTransform.position = syncPos; // Vector3.Lerp(myTransform.position, syncPos, Time.deltaTime * lerpRate);
    25.         }
    26.     }
    27.  
    28.     void OnPosChanged(Vector3 newPos)
    29.     {
    30.         Debug.Log(newPos);
    31.     }
    32.  
    33.     [Command]
    34.     void CmdProvidePositionToServer(Vector3 pos)
    35.     {
    36.         syncPos = pos;
    37.     }
    38.  
    39.     [ClientCallback]
    40.     void TransmitPosition()
    41.     {
    42.         if (isLocalPlayer) { CmdProvidePositionToServer(myTransform.position); }
    43.     }
    44. }
    45.  
     
  2. Freakyuno

    Freakyuno

    Joined:
    Jul 22, 2013
    Posts:
    138
    You probably should try to use FixedUpdate instead of Update. Update will occur on every frame regardless of what your send rate is.
     
  3. Freakyuno

    Freakyuno

    Joined:
    Jul 22, 2013
    Posts:
    138
    Code (CSharp):
    1.  
    2. void FixedUpdate () {
    3.  
    4.  
    5.       Debug.Log(Time.deltaTime);
    6.  
    7.  
    8.        TransmitPosition();
    9.  
    10.  
    11.         LerpPosition();
    12.  
    13.  
    14.     }
    15.  
     
  4. shoo

    shoo

    Joined:
    Nov 19, 2012
    Posts:
    67
    Well, FixedUpdate is good, but its not what I need. It makes send data every 0.02 second - it is 50 fps, but I need 100. Actually I want to have control about my send rate. Also, I found that sendInterval option make server send information back to clients with specified rate, but [Command] still is not deppend on this rate. So maybe I need some timer function which will send data as fast as I need. But its weird. I think Unity need to have goom made NetworkTransform sync, which will allow to make fast rates and working lerp.

    Code (CSharp):
    1. [NetworkSettings(sendInterval = 0.5f)]
    2. public class Player_SyncPosition : NetworkBehaviour {
    3.  
    4.     [SyncVar]
    5.     private Vector3 syncPos;
    6.  
    7.     [SerializeField]
    8.     Transform myTransform;
    9.     [SerializeField]
    10.     float lerpRate = 15;
    11.  
    12.     void Start() {
    13.         InvokeRepeating("HandlePosition", 0, 0.5f);
    14.     }
    15.  
    16.     // Update is called once per frame
    17.     void HandlePosition () {
    18.         // Debug.Log(Time.deltaTime);
    19.         TransmitPosition();
    20.         LerpPosition();
    21.     }
    22.  
    23.     void LerpPosition()
    24.     {
    25.         if (!isLocalPlayer)
    26.         {
    27.             myTransform.position = syncPos; // vector3.lerp(mytransform.position, syncpos, time.deltatime * lerprate);
    28.         }
    29.     }
    30.  
    31.     void OnPosChanged(Vector3 newPos)
    32.     {
    33.         Debug.Log(newPos);
    34.     }
    35.  
    36.     [Command]
    37.     void CmdProvidePositionToServer(Vector3 pos)
    38.     {
    39.         syncPos = pos;
    40.     }
    41.  
    42.     [ClientCallback]
    43.     void TransmitPosition()
    44.     {
    45.         if (isLocalPlayer) { CmdProvidePositionToServer(myTransform.position); }
    46.     }
    47. }
    48.  
     
    Last edited: Mar 8, 2016
  5. Freakyuno

    Freakyuno

    Joined:
    Jul 22, 2013
    Posts:
    138
    So you're saying that the NetworkTransform -> SendRate slider doesn't really seem to do anything?
     
  6. shoo

    shoo

    Joined:
    Nov 19, 2012
    Posts:
    67
    It works good but slider is limited to 29. It is not enough for smooth movement and it becomes worse when player have bad ping. For modern shooters it should be atleast 60 rates I think, and CS GO have up to 128 rates. But also transform lerp at NetworkTransform doesn't work at all. Ppl on forum write that lerp will work with rigidbody. It works, but when I use kinematic rigidbody there is no lerp for me again.
     
    Last edited: Mar 8, 2016
  7. Freakyuno

    Freakyuno

    Joined:
    Jul 22, 2013
    Posts:
    138
  8. srylain

    srylain

    Joined:
    Sep 5, 2013
    Posts:
    159
    Using the code from those tutorials won't allow you to change the sendrate normally, as it will still send as often as FixedUpdate is ran. This is because (I think) that as soon as you send a command it sends a packet, and doesn't wait for the sendrate to elapse to send it. On the server, anytime you change a SyncVar it's set to dirty which makes it send the new value to the clients as soon as it can.

    I ended up having to have my own timer that makes it wait to send the new position/rotation values (I did use those tutorials), and that works just fine. My own player movement is fine at 20 times a second, so theoretically it would work even better with a higher sendrate.
     
  9. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    I am currently using the same approach for sending player movement input from clients to the server. Technically, I use a coroutine for sending the commands at fixed time steps (also 20 updates per second). I don't know if it's the most efficient way though. It just felt that FixedUpdate is not the ideal choice as it is supposed to be used for physics and changes in the fixed time step would affect network performance. Of course, another option would be implementing the timer in the Update function with using Time.deltaTime, but yet I don't know if this would be preferable over using a coroutine.
     
    Last edited: Mar 9, 2016
  10. Ashkan_gc

    Ashkan_gc

    Joined:
    Aug 12, 2009
    Posts:
    1,124
    the sendRate of the NetworkBehaviour only affects the state sync code so your syncvars or OnSerialize and OnDeserialize functions. If you are sending using commands, you should use a coroutine or similar structure to change the rate of sending yourself. I mean uNet doesn't automatically batch your commands and RPCs to be sent with the rate.