PUN 2 fördröjningskompensation

I Photon Network görs spelarsynkronisering genom att skicka värden över nätverket i form av paket.

Till exempel, för att synkronisera spelarens position måste vi skicka Vector3 för position och Quaternion för rotation, och när värdena tas emot använder vi dem för att transformera.

Men eftersom värdena skickas i intervaller, kommer att helt enkelt använda dem för att transformera resultera i en hackig rörelse, det är där Vector3.Lerp och Quaternion.Lerp kommer på plats.

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

Men även denna metod har några nackdelar: att helt enkelt utjämna position och rotation kommer att resultera i en felaktig representation av spelarens rörelse, vilket inte är riktigt lämpligt för vissa typer av spel, där precision är viktigt.

Nedan finns en förbättrad version av positionssynkronisering, som tar hänsyn till nätverkstid och försöker replikera den ursprungliga rörelsen så nära som möjligt:

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));
        }
    }
}
  • Bifoga skriptet ovan till din Player-instans och tilldela det till PhotonView Observed Components.
Föreslagna artiklar
Gör ett bilspel för flera spelare med PUN 2
Unity Lägger till flerspelarchatt till PUN 2-rummen
Synkronisera stela kroppar över nätverk med PUN 2
Skapa ett multiplayer-spel i Unity med PUN 2
Photon Network (Classic) Nybörjarguide
Bygga nätverksspel för flera spelare i Unity
Multiplayer-datakomprimering och bitmanipulation