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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Non-smooth movement with NetworkTransform

Discussion in 'Multiplayer' started by UnbreakableOne, Oct 18, 2015.

  1. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    Hi,

    I'm using HLAPI for networking of my game and have used NetworkTransform on my characters but no matter how I change the component's values, the movement is not smooth. Like it's not interpolating. I see snappy movement on the local client.

    I've written my own character controller and doesn't use physic but has a Rigidbody 2D attached to it. I've tried "Sync Transform" among other settings for "Transform Sync Mode" but they don't different much.

    Cheers.
     
  2. carking1996

    carking1996

    Joined:
    Jun 15, 2010
    Posts:
    2,605
    You need to lerp things manually in code to get it to work smoothly, it doesn't do it right out of the box.
     
  3. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    How can I do it whilst using HLAPI and NetworkTransform? I think I have no control over transform component's position and it gets updated automatically over the network.
     
  4. carking1996

    carking1996

    Joined:
    Jun 15, 2010
    Posts:
    2,605
    Some code..

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Networking;
    4. using System.Collections.Generic;
    5.  
    6. public class PlayerSyncPosition : NetworkBehaviour {
    7.  
    8.     [SyncVar (hook = "SyncPositionValues")] private Vector3 syncPos;
    9.     [SerializeField] Transform myTransform;
    10.     private float lerpRate = 15;
    11.     private float normalLerpRate = 16;
    12.     private float fasterLerpRate = 27;
    13.  
    14.     private Vector3 lastPos;
    15.     private float threshold = 0.5f;
    16.  
    17.     //Latency stuff
    18.     private List<Vector3> syncPosList = new List<Vector3> ();
    19.     [SerializeField] private bool useHistoricalLerping = false;
    20.     private float closeEnough = 0.11f;
    21.  
    22.     void Start(){
    23.         lerpRate = normalLerpRate;
    24.     }
    25.  
    26.     void Update(){
    27.         LerpPosition ();
    28.     }
    29.  
    30.     void FixedUpdate (){
    31.         TransmitPosition ();
    32.     }
    33.  
    34.     void LerpPosition(){
    35.         if (!isLocalPlayer) {
    36.             if(useHistoricalLerping){
    37.                 HistoricalLerping();
    38.             }else{
    39.                 OrdinaryLerping();
    40.             }
    41.         }
    42.     }
    43.  
    44.     //Lerp types
    45.     void OrdinaryLerping(){
    46.         myTransform.position = Vector3.Lerp (myTransform.position, syncPos, Time.deltaTime * lerpRate);
    47.     }
    48.  
    49.     void HistoricalLerping(){
    50.         if (syncPosList.Count > 0) {
    51.             myTransform.position = Vector3.Lerp (myTransform.position, syncPosList[0], Time.deltaTime * lerpRate);
    52.             if(Vector3.Distance (myTransform.position, syncPosList[0]) < closeEnough){
    53.                 syncPosList.RemoveAt(0);
    54.             }
    55.  
    56.             if(syncPosList.Count > 10){
    57.                 lerpRate = fasterLerpRate;
    58.             }else{
    59.                 lerpRate = normalLerpRate;
    60.             }
    61.         }
    62.     }
    63.    
    64.     //Send info
    65.     [Command]
    66.     void CmdProvidePositionToServer(Vector3 pos){
    67.         syncPos = pos;
    68.     }
    69.  
    70.     [ClientCallback]
    71.     void TransmitPosition(){
    72.         if (isLocalPlayer && Vector3.Distance (myTransform.position, lastPos) > threshold) {
    73.             CmdProvidePositionToServer (myTransform.position);
    74.             lastPos = myTransform.position;
    75.         }
    76.     }
    77.  
    78.     [Client]
    79.     void SyncPositionValues(Vector3 latestPos){
    80.         syncPos = latestPos;
    81.         syncPosList.Add (syncPos);
    82.     }
    83. }
    84.  
     
    codestage likes this.
  5. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    I guess you are not using NetworkTransform and sync position with SyncVars, am I right?

    If that's the case, I much prefer to use NetworkTransform as it has good amount of optimizations for syncing Transform component.
     
  6. carking1996

    carking1996

    Joined:
    Jun 15, 2010
    Posts:
    2,605
    No, no network transform. But this is better as it's smooth movement across the board.
     
  7. UnbreakableOne

    UnbreakableOne

    Joined:
    Nov 16, 2013
    Posts:
    168
    I've read that lerping won't work on Sync Transform and probably that was why it was choppy/jerky. I've changed it to Sync Rigidbody 2D and it's better now.
     
  8. Chom1czek

    Chom1czek

    Joined:
    Sep 19, 2015
    Posts:
    66
    @carking1996 could you explain a little bit more about that code? What's the difference between [ClientCallback] and [Client]? Does it work like this? Every FixedUpdate() on LocalPlayer (on client's instance) we provide our current position to server by CmdProvide, the CmdProvide syncs that var across all the clients and when it's changed then the hook fuction SyncPositionValues applies it on every other instance?
     
  9. Zoey_O

    Zoey_O

    Joined:
    Mar 15, 2013
    Posts:
    28
    If you still want to use Sync Transform you can have a network transform for just the remote position and have your main gameobject lerp towards it with whatever speed/teleport settings you want. The network transform would only have debug rendering info on it that you would hide outside the editor, and your actual gameobject would follow it around, speeding up when lagging if needed or teleporting if the distance became to great. You'd have to write all the code for the lerping at that point though.
     
    moco2k likes this.