Non-smooth movement with NetworkTransform

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.

You need to lerp things manually in code to get it to work smoothly, it doesn’t do it right out of the box.

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.

Some code…

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Collections.Generic;

public class PlayerSyncPosition : NetworkBehaviour {

    [SyncVar (hook = "SyncPositionValues")] private Vector3 syncPos;
    [SerializeField] Transform myTransform;
    private float lerpRate = 15;
    private float normalLerpRate = 16;
    private float fasterLerpRate = 27;

    private Vector3 lastPos;
    private float threshold = 0.5f;

    //Latency stuff
    private List<Vector3> syncPosList = new List<Vector3> ();
    [SerializeField] private bool useHistoricalLerping = false;
    private float closeEnough = 0.11f;

    void Start(){
        lerpRate = normalLerpRate;
    }

    void Update(){
        LerpPosition ();
    }

    void FixedUpdate (){
        TransmitPosition ();
    }

    void LerpPosition(){
        if (!isLocalPlayer) {
            if(useHistoricalLerping){
                HistoricalLerping();
            }else{
                OrdinaryLerping();
            }
        }
    }

    //Lerp types
    void OrdinaryLerping(){
        myTransform.position = Vector3.Lerp (myTransform.position, syncPos, Time.deltaTime * lerpRate);
    }

    void HistoricalLerping(){
        if (syncPosList.Count > 0) {
            myTransform.position = Vector3.Lerp (myTransform.position, syncPosList[0], Time.deltaTime * lerpRate);
            if(Vector3.Distance (myTransform.position, syncPosList[0]) < closeEnough){
                syncPosList.RemoveAt(0);
            }

            if(syncPosList.Count > 10){
                lerpRate = fasterLerpRate;
            }else{
                lerpRate = normalLerpRate;
            }
        }
    }
   
    //Send info
    [Command]
    void CmdProvidePositionToServer(Vector3 pos){
        syncPos = pos;
    }

    [ClientCallback]
    void TransmitPosition(){
        if (isLocalPlayer && Vector3.Distance (myTransform.position, lastPos) > threshold) {
            CmdProvidePositionToServer (myTransform.position);
            lastPos = myTransform.position;
        }
    }

    [Client]
    void SyncPositionValues(Vector3 latestPos){
        syncPos = latestPos;
        syncPosList.Add (syncPos);
    }
}
1 Like

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.

No, no network transform. But this is better as it’s smooth movement across the board.

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.

@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?

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.

1 Like