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

Networking Smooth Camera Follow on Client

Discussion in '5.1 Beta' started by opsive, May 14, 2015.

  1. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,093
    I've been playing with this one for awhile now and I'm curious if anybody has any ideas on how to solve it.

    I modified the move sample project so the camera will smoothly follow the ball using Vector3.SmoothDamp for position and Quaternion.Slerp for rotation. When I play the game as the host the follow is perfectly smooth. However, as soon as I connect to the host as a client, the ball jitters a lot as the camera tries to follow the ball. Right now I am modifying the camera position within LateUpdate but I've tried within FixedUpdate as well and it actually got worse. The ball is set to Sync Rigidbody 3D with Local Player Authority turned off so I can only guess that the jitter happens because the server is syncing the ball position to the client which causes the camera to no longer smoothly follow the ball.

    I have attached the modified move project to this post if you want to take a look. All you have to do is start a client and server instance and notice the jitter on the client. The camera follow script is about as basic as it can get:

    Code (csharp):
    1.  
    2.   void FixedUpdate ()
    3.   {
    4.     if (m_Player == null) {
    5.       return;
    6.     }
    7.  
    8.     Vector3 cpos = m_Player.position + Quaternion.LookRotation(Vector3.forward) * new Vector3(0, 2, -3);
    9.     Vector3 vel = Vector3.zero;
    10.     transform.position = Vector3.SmoothDamp(transform.position, cpos, ref vel, 0.1f);
    11.     transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(m_Player.position - transform.position), 5 * Time.deltaTime);
    12.   }
    13.  
    Has anybody else had to solve this problem? Any ideas?

    Thanks,
    Justin
     

    Attached Files:

  2. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    Probably the jitter is in the interpolation of the NetworkTransform, not the camera.
     
  3. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,093
    That makes sense. When I set the Network Send Rate to 0 there is no jitter so that also points to the NetworkTransform.

    I'm thinking that when the sync happens I can force move the camera by the delta. Is there a callback for when this sync happens? I tried to override both NetworkTransform.OnDeserialize and NetworkBehaviour.OnDeserialize but in both of these cases the position is still the same as what it is was in the previous update loop.

    Edit: I played around with it some more and if I set the NetworkTransform to Sync Transform instead of Sync Rigidbody3D then I do get the delta position within NetworkTransform.OnDeserialize. If I just add the delta to the camera's position the ball still jitters a bit but it is definitely better. Thanks for you help!
     
    Last edited: May 15, 2015
  4. ObliviousHarmony

    ObliviousHarmony

    Joined:
    Jul 3, 2014
    Posts:
    79
    Hey Opsive,

    You just unintentionally helped me create server-auth movement with client-side prediction, so I'm very grateful for that :D

    On the subject of your thread, I've got a few tips that might help you out, assuming I'm understanding what you're doing. I'll prefix this with an apology, as I don't have access to my Unity right now and can't review your project. :(

    One issue that might cause jittering is with interpolation between two positions. When the client receives the position, it just sets it to it, but this is not ideal. What you would want to do is have the last position and the new position, and then interpolate between the two over the course of many Update() calls. I believe UNet ships with a solution for this, check out the NetworkTransformVisualizer (I believe, something like that)
     
  5. opsive

    opsive

    Joined:
    Mar 15, 2010
    Posts:
    5,093
    :)
    NetworkTransformVisualizer does exist but it looks like it is mostly for debugging:
    When I added it to the player object it shows some debug lines but the jittering didn't change.

    Your interpolation idea makes sense, but how can you override the position to allow you to interpolate it? I haven't found the hook in NetworkTransform that allows you to do this. On the NetworkTransform there is a variable that looks promising (called Interpolate Movement Factor) but I didn't notice a difference after trying different values.
     
  6. ObliviousHarmony

    ObliviousHarmony

    Joined:
    Jul 3, 2014
    Posts:
    79
    You mentioned overriding NetworkTransform.OnDeserialize, and I think that might be key (again, cannot test as I'm not at my workstation). I would probably try caching the position/rotation and stuff and then call base.OnDeserialize() and see how they change. Assuming this is correct, I would reset the position/rotation to the pre-deserialize state and then lerp between that position and the target position/rotation. It's not ideal of course, but it should work!

    Edit: Looking at the documentation actually, I think this is something that should already be implemented. The above would at least test to see if it's working as it should. If it still jitters, perhaps the issue is with something else?

    Edit 2: Take a loop at "snapThreshold" It seems to be related to interpolation, along with the "interpolateMovement" property as well.
     
    Last edited: May 15, 2015
  7. kkjamie

    kkjamie

    Joined:
    Mar 9, 2014
    Posts:
    1
    Hey ObliviousHarmony, care to elaborate on how you achieved client-side prediction?