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));
}
}
}
- उपरोक्त स्क्रिप्ट को अपने प्लेयर इंस्टेंस में संलग्न करें और इसे फोटोनव्यू ऑब्जर्व्ड कंपोनेंट्स को असाइन करें।