PUN 2 Lagkompensation

I Photon Network udføres spillersynkronisering ved at sende værdier over netværket i form af pakker.

For eksempel, for at synkronisere spillerposition, skal vi sende Vector3 til position og Quaternion til rotation, og når værdierne er modtaget, anvender vi dem til at transformere.

Men da værdierne sendes i intervaller, vil blot at anvende dem til transformation resultere i en hakkende bevægelse, det er her Vector3.Lerp og Quaternion.Lerp kommer på plads.

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

Men selv denne metode har nogle ulemper: blot udjævning af position og rotation vil resultere i en unøjagtig repræsentation af spillerens bevægelse, hvilket ikke er helt egnet til nogle typer spil, hvor præcision er vigtig.

Nedenfor er en forbedret version af positionssynkronisering, som tager højde for netværkstid og forsøger at replikere den oprindelige bevægelse så tæt som muligt:

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));
        }
    }
}
  • Vedhæft scriptet ovenfor til din afspillerinstans og tildel det til PhotonView Observed Components.
Foreslåede artikler
Lav et multiplayer bilspil med PUN 2
Unity tilføjer multiplayer-chat til PUN 2-rummene
Synkroniser rigidbodies over netværk ved hjælp af PUN 2
Lav et multiplayer-spil i Unity ved hjælp af PUN 2
Photon Network (klassisk) begyndervejledning
Opbygning af multiplayer-netværksspil i Unity
Multiplayer datakomprimering og bitmanipulation