Compensation de décalage PUN 2

Dans Photon Network, la synchronisation du lecteur se fait en envoyant des valeurs sur le réseau sous forme de paquets.

Par exemple, pour synchroniser la position du joueur, nous devons envoyer Vector3 pour la position et Quaternion pour la rotation, puis lorsque les valeurs sont reçues, nous les appliquons pour transformer.

Cependant, étant donné que les valeurs sont envoyées à intervalles, leur simple application pour transformer entraînera un mouvement saccadé, c'est là que Vector3.Lerp et Quaternion.Lerp entrent en place.

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

Mais même cette méthode présente certains inconvénients: le simple fait de lisser la position et la rotation se traduira par une représentation inexacte du mouvement du joueur, ce qui n'est pas tout à fait adapté à certains types de jeux, où la précision est importante.

Vous trouverez ci-dessous une version améliorée de la synchronisation de position, qui prend en compte le temps de mise en réseau et tente de reproduire le mouvement d'origine le plus fidèlement possible:

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));
        }
    }
}
  • Attachez le script ci-dessus à votre instance de lecteur et attribuez-le aux composants observés de PhotonView.
Articles suggérés
Créez un jeu de voiture multijoueur avec PUN 2
Unity ajoute un chat multijoueur aux salles PUN 2
Synchroniser les corps rigides sur le réseau à l'aide de PUN 2
Créez un jeu multijoueur dans Unity en utilisant PUN 2
Créer des jeux multijoueurs en réseau dans Unity
Compression de données multijoueur et manipulation de bits
Tutoriel de classement en ligne Unity