PUN 2 लैग मुआवजा

फोटॉन नेटवर्क में, प्लेयर सिंक्रोनाइज़ेशन पैकेट के रूप में नेटवर्क पर मान भेजकर किया जाता है।

उदाहरण के लिए, खिलाड़ी की स्थिति को सिंक्रनाइज़ करने के लिए हमें स्थिति के लिए वेक्टर3 और रोटेशन के लिए क्वाटरनियन भेजने की आवश्यकता होती है, फिर जब मान प्राप्त होते हैं, तो हम उन्हें परिवर्तन के लिए लागू करते हैं।

हालाँकि, चूँकि मान अंतरालों में भेजे जाते हैं, बस उन्हें परिवर्तन के लिए लागू करने से अस्थिर गति उत्पन्न होगी, यहीं पर वेक्टर3.लेरप और क्वाटरनियन.लेरप आते हैं।

transform.position = Vector3.Lerp(transform.position, latestPos, Time.deltaTime * 5);
transform.rotation = Quaternion.Lerp(transform.rotation, latestRot, Time.deltaTime * 5);

लेकिन इस पद्धति के भी कुछ नुकसान हैं: केवल स्थिति और घुमाव को सुचारू करने से खिलाड़ी के आंदोलन का गलत प्रतिनिधित्व होगा, जो कुछ प्रकार के खेलों के लिए बिल्कुल उपयुक्त नहीं है, जहां सटीकता महत्वपूर्ण है।

नीचे स्थिति सिंक्रनाइज़ेशन का एक उन्नत संस्करण है, जो नेटवर्किंग समय को ध्यान में रखता है और मूल आंदोलन को यथासंभव निकट से दोहराने का प्रयास करता है:

using UnityEngine;
using Photon.Pun;

public class PUN2_LagFreePlayerSync : MonoBehaviourPun, IPunObservable
{
    //Values that will be synced over network
    Vector3 latestPos;
    Quaternion latestRot;
    //Lag compensation
    float currentTime = 0;
    double currentPacketTime = 0;
    double lastPacketTime = 0;
    Vector3 positionAtLastPacket = Vector3.zero;
    Quaternion rotationAtLastPacket = Quaternion.identity;

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.IsWriting)
        {
            //We own this player: send the others our data
            stream.SendNext(transform.position);
            stream.SendNext(transform.rotation);
        }
        else
        {
            //Network player, receive data
            latestPos = (Vector3)stream.ReceiveNext();
            latestRot = (Quaternion)stream.ReceiveNext();

            //Lag compensation
            currentTime = 0.0f;
            lastPacketTime = currentPacketTime;
            currentPacketTime = info.SentServerTime;
            positionAtLastPacket = transform.position;
            rotationAtLastPacket = transform.rotation;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (!photonView.IsMine)
        {
            //Lag compensation
            double timeToReachGoal = currentPacketTime - lastPacketTime;
            currentTime += Time.deltaTime;

            //Update remote player
            transform.position = Vector3.Lerp(positionAtLastPacket, latestPos, (float)(currentTime / timeToReachGoal));
            transform.rotation = Quaternion.Lerp(rotationAtLastPacket, latestRot, (float)(currentTime / timeToReachGoal));
        }
    }
}
लिंक
Unity 6