PUN 2 Gecikme Telafisi

Photon Network'te oynatıcı senkronizasyonu, değerlerin ağ üzerinden paketler halinde gönderilmesiyle yapılır.

Örneğin, oyuncu konumunu senkronize etmek için konum için Vector3'ü ve dönüş için Quaternion'u göndermemiz gerekiyor, ardından değerler alındığında bunları dönüşüme uyguluyoruz.

Ancak değerler aralıklarla gönderildiğinden, bunları yalnızca dönüşüme uygulamak değişken bir hareketle sonuçlanacaktır; Vector3.Lerp ve Quaternion.Lerp burada devreye girer.

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

Ancak bu yöntemin bile bazı dezavantajları vardır: Konumun ve dönüşün basit bir şekilde yumuşatılması, oyuncunun hareketinin hatalı bir şekilde temsil edilmesine neden olur ve bu, hassasiyetin önemli olduğu bazı oyun türleri için pek uygun değildir.

Aşağıda, ağ oluşturma süresini hesaba katan ve orijinal hareketi mümkün olduğu kadar yakın bir şekilde kopyalamaya çalışan, konum senkronizasyonunun geliştirilmiş bir sürümü bulunmaktadır:

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));
        }
    }
}
  • Yukarıdaki betiği Player örneğinize ekleyin ve onu PhotonView Observed Components'a atayın.
Önerilen Makaleler
PUN 2 ile Çok Oyunculu Araba Oyunu Yapın
Unity, PUN 2 Odalarına Çok Oyunculu Sohbet Ekliyor
PUN 2'yi Kullanarak Sert Cisimleri Ağ Üzerinden Senkronize Etme
PUN 2'yi kullanarak Unity'de Çok Oyunculu Bir Oyun Yapın
Photon Network (Klasik) Başlangıç ​​Kılavuzu
Unity'de Çok Oyunculu Ağ Bağlantılı Oyunlar Oluşturma
Çok Oyunculu Veri Sıkıştırma ve Bit İşleme