Search Unity

Help to refine the script of players of game objects

Discussion in 'Multiplayer' started by skDYLAN, Feb 13, 2018.

  1. skDYLAN

    skDYLAN

    Joined:
    Oct 29, 2017
    Posts:
    3
    Hello. I'm working on a script for synchronizing objects in real time, everything is fine, interpolation works like it should, but jerks are observed, instead of smooth movement. Can someone look fresh and find a flaw in the code.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class SyncObj : NetworkBehaviour {
    7.  
    8.     public NetGM_Player netGM_Player = null;
    9.     float maxRate = 0.06f; // частота отправки кадров
    10.  
    11.     Vector3 lastPosition = new Vector3 (0, 100, 0);
    12.  
    13.     Vector3 endPosition = new Vector3();
    14.     Quaternion endRotation = new Quaternion();
    15.     Vector3 startMarker_Position = new Vector3();
    16.     Quaternion startMarker_Rotation = new Quaternion();
    17.     float endTime = 0;
    18.     float prec=0;
    19.  
    20.     float numscr = 0;
    21.  
    22.     float lastSendScren = 0;
    23.  
    24.     int factor = 1;
    25.  
    26.     public float delta =0;
    27.  
    28.     Rigidbody rig;
    29.  
    30.     Vector3 oldPosServ = new Vector3();
    31.     Quaternion oldRotServ = new Quaternion();
    32.  
    33.     Vector3 newPosServ = new Vector3();
    34.     Quaternion newRotServ = new Quaternion();
    35.  
    36.     // client
    37.     List<ScreenTransform> _scrinsTransformPlayer = new List<ScreenTransform>();
    38.     int numScreen = 0;
    39.  
    40.     // Use this for initialization
    41.     void Start () {
    42.         // query the current position of the object
    43.         if (isClient) {
    44.             CmdSyncStartPos (transform.position, transform.rotation);
    45.             rig = GetComponent<Rigidbody> ();
    46.             rig.isKinematic = true;
    47.             rig.useGravity = false;
    48.             rig.mass = 0f;
    49.             rig.angularDrag = 0f;
    50.             rig.interpolation = RigidbodyInterpolation.Interpolate;
    51.         }
    52.     }
    53.  
    54.     // Update is called once per frame
    55.     void LateUpdate () {
    56.         Client ();
    57.     }
    58.  
    59.     void FixedUpdate()
    60.     {
    61.         ClientUpdate ();
    62.         ServerFixedUpdate ();
    63.     }
    64.  
    65.     //request the current object position from the server
    66.     [Command]
    67.     void CmdSyncStartPos(Vector3 pos, Quaternion rot)
    68.     {
    69.         if (transform.position != pos || transform.rotation != rot) {
    70.             RpcSendAllNewTransform (transform.position, transform.rotation, Time.time);
    71.         }
    72.     }
    73.     [ClientRpc]
    74.     void RpcSendAllNewTransform(Vector3 newPosition, Quaternion newRotation, float time)
    75.     {
    76.         // add a new frame to the queue
    77.         numScreen++;
    78.         //Debug.Log ("Номер: " + numScreen + " Время: " + Time.fixedTime);
    79.         _scrinsTransformPlayer.Add (new ScreenTransform(gameObject.GetInstanceID(), newPosition, newRotation, time, numScreen));
    80.     }
    81.  
    82.     //// GM_local_main object to which the player has access, this object contains the time synchronized with the server
    83.     //получаемое через метод GetServerTime();
    84.     void Client()
    85.     {
    86.         if (!isClient)
    87.             return;
    88.  
    89.  
    90.     }
    91.  
    92.     void ClientUpdate()
    93.     {
    94.         if (!isClient)
    95.             return;
    96.  
    97.         if (netGM_Player == null) {
    98.             GameObject obj = GameObject.Find ("GM_local_main");
    99.             if (obj != null) {
    100.                 netGM_Player = obj.GetComponent<NetGM_Player> ();
    101.             }
    102.         }
    103.  
    104.  
    105.         if (netGM_Player != null) {
    106.  
    107.          
    108.                  //interpolation
    109.                  // If the screens are in the queue
    110.             if (_scrinsTransformPlayer.Count > 0)
    111.             {
    112.  
    113.                 if (SerchScreen ()) {
    114.  
    115.                     startMarker_Position = transform.position;
    116.  
    117.                     //The end position is taken from the frame
    118.                     endPosition = _scrinsTransformPlayer [0].position;
    119.  
    120.                     numscr = _scrinsTransformPlayer [0].number;
    121.  
    122.                     startMarker_Rotation = transform.rotation;
    123.                     endRotation = _scrinsTransformPlayer [0].rotation;
    124.                     //the time to which the object must reach its point
    125.                     endTime = _scrinsTransformPlayer [0].time;
    126.                     //remove a frame from the queue
    127.                         _scrinsTransformPlayer.RemoveAt (0);
    128.  
    129.                 }
    130.  
    131.             }
    132.             //We calculate what percentage of the total path the object had to make to the current time
    133.             float test = netGM_Player.GetServerTime () + Time.fixedTime;
    134.             prec = ((netGM_Player.GetServerTime () + Time.fixedTime - maxRate*2) - (endTime)) / (maxRate);
    135.  
    136.             Debug.Log ("процент: " + prec + " Текущее время: " + (netGM_Player.GetServerTime() + Time.fixedTime - maxRate*2) + " endTime " + endTime + " номер " + numscr);
    137.  
    138.             //we interpolate the position of the object
    139.             transform.position = Vector3.Lerp (startMarker_Position, endPosition, prec);
    140.             transform.rotation = Quaternion.Slerp (startMarker_Rotation, endRotation, prec);
    141.         }
    142.  
    143.     }
    144.  
    145.     void ServerFixedUpdate()
    146.     {
    147.         if (!isServer)
    148.             return;
    149.  
    150.         if (lastSendScren == 0) {
    151.  
    152.             oldPosServ = transform.position;
    153.             oldRotServ = transform.rotation;
    154.             // 3 цикла: 3 * 0.2 = 0.6
    155.             lastSendScren = 2;
    156.             RpcSendAllNewTransform (transform.position, transform.rotation, Time.fixedTime);
    157.         } else
    158.             lastSendScren--;
    159.     }
    160.  
    161.     // search for the right frame
    162.     bool SerchScreen()
    163.     {
    164.         bool find = false;
    165.         int k = 0;
    166.         for (int i = 0; i < _scrinsTransformPlayer.Count; i++) {
    167.  
    168.             // (current server time) - (delay in 2 * maxRate)
    169.             if (netGM_Player.GetServerTime () + Time.fixedTime - maxRate*2 >= _scrinsTransformPlayer [i].time
    170.             ){
    171.                     k = i;
    172.                     find = true;
    173.             }
    174.         }
    175.         if (find)
    176.             for (int j = 0; j < k - 1; j++) {
    177.                 _scrinsTransformPlayer.RemoveAt (0);
    178.             }
    179.         return find;
    180.     }
    181. }
    I apologize for google translate, but I really need help, I'm trying to find an error for a month now
     
  2. skDYLAN

    skDYLAN

    Joined:
    Oct 29, 2017
    Posts:
    3
    transform.position = Vector3.Lerp (startMarker_Position, endPosition, prec);
    to
    transform.position = Vector3.SmoothDamp (transform.position, endPosition, ref velocity, maxRate); ?
     
  3. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    I haven't read through all your code, but something that stuck out to me is you are sending your updates to the clients on the default channel, which unless you've changed it is the reliable channel. If a ClientRpc to sync the position is sent and not received you don't want it to try to resend it, as that information is already too old by the time it resends it. So I'd switch to using channel 1 for those.

    I doubt that is your real problem though.
     
  4. skDYLAN

    skDYLAN

    Joined:
    Oct 29, 2017
    Posts:
    3
    I solved my problem. Now I'm using UDP and Vector3.SmoothDamp instead of Vector3.lerp