Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Third Party Photon PUN2 - Non-Rigidbody Lag Compensation and Jittery Cars

Discussion in 'Multiplayer' started by shubhank008, Jun 15, 2020.

  1. shubhank008

    shubhank008

    Joined:
    Apr 3, 2014
    Posts:
    107
    I have made a very simple car game.
    I am not syncing PhotonTransformView but instead doing lag compensation using LERP (well tried doing movetowards but it was more laggy and jittery).

    I am using PurePool with PUN2 (pool) but don't think it should matter ?

    Some of code snippets here:

    Local Player moves using

    Code (CSharp):
    1. /////////////////////////////////////////////////////////////////
    2.             ///Player Movement
    3.             // Move the player forward
    4.             ///////////////////////////////////////////////////////////////////
    5.             ///
    6.             if (MultiplayerManager.Instance.checkIfObjectIsMine(this.gameObject))
    7.             {
    8.                 thisTransform.Translate(Vector3.forward * Time.deltaTime * speed * speedMultiplier, Space.Self);
    9.             }
    10.  

    Remote Player compensation movement

    Code (CSharp):
    1. public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    2.     {
    3.         if (stream.IsWriting)
    4.         {
    5.             stream.SendNext(this.transform.position);
    6.             stream.SendNext(this.transform.rotation);
    7.         }
    8.         else
    9.         {
    10.             //Network player, receive data
    11.             latestPos = (Vector3)stream.ReceiveNext();
    12.             latestRot = (Quaternion)stream.ReceiveNext();
    13.  
    14.             //Lag compensation
    15.             currentTime = 0.0f;
    16.             lastPacketTime = currentPacketTime;
    17.             currentPacketTime = info.SentServerTime;
    18.             positionAtLastPacket = transform.position;
    19.             rotationAtLastPacket = transform.rotation;
    20.  
    21.         }
    22.     }
    23.  
    24.  
    25.     public void Update()
    26.     {
    27.  
    28.         if (!myPhotonView.IsMine)
    29.         {
    30.             //Lag compensation
    31.             timeToReachGoal = currentPacketTime - lastPacketTime;
    32.             currentTime += Time.deltaTime;
    33.  
    34.             //Update remote player
    35.             transform.position = Vector3.Lerp(positionAtLastPacket, latestPos, (float)(currentTime / timeToReachGoal));
    36.             transform.rotation = Quaternion.Lerp(rotationAtLastPacket, latestRot, (float)(currentTime / timeToReachGoal));
    37.         }
    38.     }

    PurePool

    Code (CSharp):
    1. using Photon.Pun;
    2.  
    3. using Umbrace.Unity.PurePool;
    4.  
    5. using UnityEngine;
    6.  
    7. namespace Umbrace.Unity.PurePool.Photon {
    8.  
    9.     public class PunPoolingSetup : MonoBehaviour {
    10.  
    11.         [SerializeField, HideInInspector]
    12.         private PrefabPool punPrefabPool;
    13.      
    14.         private void Start() {
    15.             // Create the PrefabPool object, which is the bridge between PUN and Pure Pool.
    16.             this.punPrefabPool = new PrefabPool();
    17.  
    18.             // Set the manager to load by name from the Resources folders.
    19.             // This is required as most objects spawned by PUN will not be set up in the manager already, and will need to be loaded.
    20.             NamedGameObjectPoolManager.Instance.UseResources = true;
    21.  
    22.             // Assign the manager, so it knows how to acquire and release from the pools.
    23.             this.punPrefabPool.Manager = NamedGameObjectPoolManager.Instance;
    24.  
    25.             // Set PUN to use the PrefabPool object.
    26.             PhotonNetwork.PrefabPool = punPrefabPool;
    27.         }
    28.      
    29.         private void OnEnable() {
    30.             // Set PUN to use the PrefabPool object again.
    31.             PhotonNetwork.PrefabPool = this.punPrefabPool;
    32.         }
    33.      
    34.     }
    35.  
    36. }


    Actual behavior, both are PC builds on same PC and same network and India/Asia server

    VH91a8LAoX.gif

    DebugView of the LagCompensation stats even when both cars were driving almost side by side

    7vBAFkrD7S.gif
     
  2. shubhank008

    shubhank008

    Joined:
    Apr 3, 2014
    Posts:
    107
    anyone ?
     
  3. tobiass

    tobiass

    Joined:
    Apr 7, 2009
    Posts:
    3,062
    Well, the approach is kind of right but as you see yourself, it falls short of expectations.
    This assumes that the sender will be able to always send on time and that the messages always take a fixed time to arrive. This is not the case.
    If a package is late, the receiver does not get an update for a longer time. His remote car may reach the latest position and stops there.
    When the late info is finally in, the receiver has less time to catch up and should reach the point quicker, to make up for the time the network took.

    If you want to find the solution yourself, fine. Read up on lag compensation and those topics.
    Else, I would recommend getting Simple Network Sync for PUN 2. It's a set of components that focus on hiding lag and getting smooth results. The components may look intimidating at first but the results are great and it's well worth the effort. Emotiron is on the PUN team now, by the way.
     
  4. shubhank008

    shubhank008

    Joined:
    Apr 3, 2014
    Posts:
    107
    I have read the lag compensation article and almost all online unity and photon forum posts and solutions and tried them all, believe me been almost a week since I am trying to make it work.
    The weird part is, I am debug logging the time difference between last and next update and its barely like 0.1 or even lesser sometimes.
    I have tried different approaches even trying using RPC calls for the movement as well but thing is no matter what solution I tried, that jittery movement is still there.

    If the car was lagging behind a bit, it would be okay and could think of better lag compensation, but its that weird jummpy/jittery behavior thats concerning.

    I will check out SNS but its just weird that its behaving like that when I know for sure that the code and implementation is right and shouldn't cause such a behavior yet in my game there is no other script that controls movement other than that Translate code..
     
  5. shubhank008

    shubhank008

    Joined:
    Apr 3, 2014
    Posts:
    107
    So I tried SNS witht he below settings but still nothing, same results as the GIFs posted above.

    Unity_vwb8A9ak0t.png
     
  6. uzucraque

    uzucraque

    Joined:
    Oct 25, 2018
    Posts:
    2
    I have the same problem.
     
  7. uzucraque

    uzucraque

    Joined:
    Oct 25, 2018
    Posts:
    2
    did you manage to find the solution?
     
  8. emotitron

    emotitron

    Joined:
    Oct 9, 2016
    Posts:
    41

    Those were the only two components on the object? Other than your basic controller code? Or were you also trying to do some kind of lag compensation on there as well?

    https://discord.gg/egaRfd8
    If you ping me in the Discord channel, it might be faster to back and forth some questions about your setup.

    When you say "lag compensation" in the context of player movements here - I should make sure we agree on what you mean by that. Players are not deterministic by any measure so you can't lag compensate forward in time, like you can a predictable objects like a projectile. Any attempts to extrapolate them will produce massive amounts of rubberbanding when they change direction. But I am not sure that is what you mean by lag compensation here.