Kompensasi Lag PUN 2

Di Photon Network, sinkronisasi pemutar dilakukan dengan mengirimkan nilai melalui jaringan dalam bentuk paket.

Misalnya, untuk menyinkronkan posisi pemain, kita perlu mengirimkan Vector3 untuk posisi dan Quaternion untuk rotasi, kemudian ketika nilainya diterima, kita menerapkannya untuk mentransformasikannya.

Namun, karena nilai dikirim dalam interval, menerapkannya pada transformasi akan menghasilkan pergerakan yang terputus-putus, di situlah Vector3.Lerp dan Quaternion.Lerp berperan.

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

Namun metode ini pun memiliki beberapa kelemahan: menghaluskan posisi dan rotasi akan menghasilkan representasi gerakan pemain yang tidak akurat, yang kurang cocok untuk beberapa jenis permainan yang mengutamakan presisi.

Di bawah ini adalah versi sinkronisasi posisi yang ditingkatkan, yang memperhitungkan waktu jaringan dan mencoba meniru gerakan asli sedekat mungkin:

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));
        }
    }
}
  • Lampirkan skrip di atas ke instance Player Anda dan tetapkan ke PhotonView Observed Components.
Artikel yang Disarankan
Buat Game Mobil Multi Pemain dengan PUN 2
Unity Menambahkan Obrolan Multipemain ke Ruang PUN 2
Sinkronkan Rigidbodies Melalui Jaringan Menggunakan PUN 2
Buat Game Multiplayer di Unity menggunakan PUN 2
Panduan Pemula Jaringan Foton (Klasik).
Membangun Game Jaringan Multipemain dalam Unity
Kompresi Data Multi Pemain dan Manipulasi Bit