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.