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): [NetworkSettings(sendInterval = 0.5f)] public class Player_SyncPosition : NetworkBehaviour { [SyncVar] private Vector3 syncPos; [SerializeField] Transform myTransform; [SerializeField] float lerpRate = 15; // Update is called once per frame void Update () { Debug.Log(Time.deltaTime); TransmitPosition(); LerpPosition(); } void LerpPosition() { if (!isLocalPlayer) { myTransform.position = syncPos; // Vector3.Lerp(myTransform.position, syncPos, Time.deltaTime * lerpRate); } } void OnPosChanged(Vector3 newPos) { Debug.Log(newPos); } [Command] void CmdProvidePositionToServer(Vector3 pos) { syncPos = pos; } [ClientCallback] void TransmitPosition() { if (isLocalPlayer) { CmdProvidePositionToServer(myTransform.position); } } }
You probably should try to use FixedUpdate instead of Update. Update will occur on every frame regardless of what your send rate is.
Code (CSharp): void FixedUpdate () { Debug.Log(Time.deltaTime); TransmitPosition(); LerpPosition(); }
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): [NetworkSettings(sendInterval = 0.5f)] public class Player_SyncPosition : NetworkBehaviour { [SyncVar] private Vector3 syncPos; [SerializeField] Transform myTransform; [SerializeField] float lerpRate = 15; void Start() { InvokeRepeating("HandlePosition", 0, 0.5f); } // Update is called once per frame void HandlePosition () { // Debug.Log(Time.deltaTime); TransmitPosition(); LerpPosition(); } void LerpPosition() { if (!isLocalPlayer) { myTransform.position = syncPos; // vector3.lerp(mytransform.position, syncpos, time.deltatime * lerprate); } } void OnPosChanged(Vector3 newPos) { Debug.Log(newPos); } [Command] void CmdProvidePositionToServer(Vector3 pos) { syncPos = pos; } [ClientCallback] void TransmitPosition() { if (isLocalPlayer) { CmdProvidePositionToServer(myTransform.position); } } }
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.
Take a look at this video series: https://www.youtube.com/playlist?list=PLwyZdDTyvucyAeJ_rbu_fbiUtGOVY55BG Pay particular attention to Video number 2, and Video number 5 - he goes over exactly what you're trying to accomplish.
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.
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.
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.