Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Time synchronization with Netcode

Discussion in 'Netcode for GameObjects' started by b4guw1x, Aug 10, 2023.

  1. b4guw1x

    b4guw1x

    Joined:
    Apr 16, 2020
    Posts:
    12
    Hi there. I need to have a simple sync time for server and clients.
    I have gameobjects that has constant velocity. And i spawn - despawn them with server. But since they are not spawned at exact same time (because of the lag) i can’t fix their positions.
    My approach is this :
    1- When each object spawned, they sent an RPC to server for sync the position (at OnNetworkSpawn).
    2- Server send an rpc to object that say "You are at (x,y,z) position at NetworkManager.ServerTime)
    3- When object take this rpc, it will look at their Server.ServerTime and calculate the difference.
    4- Set this object position = The pos that taken from server + velocity * time difference from server

    But it’s not working on high ping values. So i think i can fix it with syncronized time with server. Is there any way to create sync timer with netcode? Or do you have any approach to fix it?

    Here is my approach

    Server side :


    Code (CSharp):
    1.  
    2.  
    3.         [ServerRpc(RequireOwnership = false)]
    4.         public void RequestPositionFix_ServerRpc(ulong networkID)
    5.         {
    6.             foreach (var pair in _spawnedObjects)
    7.             {
    8.                 var _networkObject = pair.Value.FirstOrDefault(x => x.NetworkObjectId == networkID);
    9.  
    10.                 if (!_networkObject)
    11.                 {
    12.                     continue;
    13.                 }
    14.              
    15.                 _networkObject.GetComponent<BaseObstacle>()
    16.                     .SyncPosition_ClientRpc(networkID,                NetworkManager.ServerTime.Time,_networkObject.transform.position);
    17.             }
    18.         }
    Client Side :

    Code (CSharp):
    1.         [ClientRpc]
    2.         public void SyncPosition_ClientRpc(ulong objectID, double serverSpawnTime,Vector3 serverSpawnPos)
    3.         {
    4.             if(objectID != NetworkObjectId) return;
    5.  
    6.             _serverSpawnTime = serverSpawnTime;
    7.             _serverSpawnPos = serverSpawnPos;
    8.             SyncPositionWithServer();
    9.         }
    10.  
    11.         protected override void SyncPositionWithServer()
    12.         {
    13.             transform.position = _serverSpawnPos;
    14.             var _zDiff = (_localSpawnTime - _serverSpawnTime) * _gameController.GameSpeed;
    15.             transform.position += Vector3.back * (float)_zDiff;
    16.         }
    (Since this object is moving only on Z, i made it for Z axis)
     
    Last edited: Aug 11, 2023
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,019
    Could you explain what you need this for and what the actual (nontechnical) issue is that you have with how the default behaviour works, and the issue you see with high ping?

    I have a hunch that it may be impossible to „fix“ because you cannot perfectly synch any two clients at a given point in time due to the nature of varying RTT (lag). It becomes obvious at high ping because in one frame RTT for client A may be 1000 and for B it‘s 1300. And in the next tick A has 2500 RTT while B has 800. And if you simulate this on the local machine with two client instances, the object will never really be in the same position for both clients.

    But … it may not need to be as long as the server simulates everything and since both clients will rarely compare their screens with one another.
     
  3. b4guw1x

    b4guw1x

    Joined:
    Apr 16, 2020
    Posts:
    12
    Thanks for your reply. I got a fast paced platform game. But for optimisation reasons, players are not moving on their scene. Instead, background and obstacles are spawing infront of them and going backwards.
    The obstacles are going with constant speed on Z axis. For example they are moving -15 meters at each second.
    But since i can't spawn them at exactly same time, i have some visual bugs.

    For security reasons , collisions are happening on server side. But since the obstacle on clients are not in the same position with server, they are colliding the obstacles that are far away from their player on their screen. Especially when they have higher ping, they could contact with obstacle at really weird positions (Like if they have 500 ping, the position difference is about 7.5 meter which is 1/4 of my scene). That's why i want to have a little bit more sync positions.
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,019
    Okay but this isn‘t going to work. The most accurate collision detection will be on the client side. The second best thing to do is to let the server know that the player passed or did not pass an obstacle at a given local tick/time, and the server checks what the position of the collision was at the time and whether the player did pass or fail that obstacle and informs the client.

    Basically you are trying to do the opposite. ;)
    Let the clients tell the server what they do, and the server confirms or corrects the clients. That‘s the only way to avoid visual inaccuracies and still have server authority. There will always be situations where the client visually thinks they made it or failed but didn‘t. That‘s normal and cannot be avoided.
     
  5. b4guw1x

    b4guw1x

    Joined:
    Apr 16, 2020
    Posts:
    12
    You are right. Let me try that. Thanks for your reply !