Interpolation Problems
Hi,
I am trying to make a runner type game with multiplayer features, so position of each player is quite important. I am not very in to the subject, so I am quite lost.
Using the Lerp example of photon, i got this networkCharacter script:
[code2=csharp]void Start()
{
correctPlayerPos = transform.localPosition;
lastCorrectPlayerPos = transform.localPosition;
fraction = 0;
}
//Update is called once per frame
void Update()
{
if (!photonView.isMine) //If it is another player, we have to correct its position
{
// We get 10 updates per sec. sometimes a few less or one or two more, depending on variation of lag.
// Due to that we want to reach the correct position in a little over 100ms. This way, we usually avoid a stop.
// Lerp() gets a fraction value between 0 and 1. This is how far we went from A to B.
//
// Our fraction variable would reach 1 in 100ms if we multiply deltaTime by 10.
// We want it to take a bit longer, so we multiply with 9 instead.
fraction += Time.deltaTime * 9;
Vector3 newPos = Vector3.Lerp(this.lastCorrectPlayerPos, this.correctPlayerPos, fraction);
newPos.z = transform.localPosition.z;
transform.localPosition = newPos;
}
}
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
// We own this player: send the others our data
Vector3 pos = transform.localPosition;
stream.Serialize(ref pos);
Quaternion rot = transform.rotation;
stream.Serialize(ref rot);
controlPlayer plScript = (controlPlayer)transform.GetComponent("controlPlayer");
int actualPath = (int)plScript.currentPath;
stream.Serialize(ref actualPath);
}
else
{
Vector3 pos = Vector3.zero;
stream.Serialize(ref pos);
this.correctPlayerPos = pos;
this.lastCorrectPlayerPos = transform.localPosition;
fraction = 0;
Quaternion rot = Quaternion.identity;
stream.Serialize(ref rot);
transform.rotation = rot;
int actualPath = 0;
stream.Serialize(ref actualPath);
controlPlayer plScript = (controlPlayer)transform.GetComponent("controlPlayer");
plScript.currentPath = (mapManager.pathType) actualPath;
}
}[/code2]
My concern is about the position is not very accurate. I post a video showing the problems. The capsules represent the players (the centered one is the main player of each client), and they appear with different distance values on each screen. What am I doing wrong?
https://www.dropbox.com/s/t1zrj7ipp96v2 ... 16581.mov
I am trying to make a runner type game with multiplayer features, so position of each player is quite important. I am not very in to the subject, so I am quite lost.
Using the Lerp example of photon, i got this networkCharacter script:
[code2=csharp]void Start()
{
correctPlayerPos = transform.localPosition;
lastCorrectPlayerPos = transform.localPosition;
fraction = 0;
}
//Update is called once per frame
void Update()
{
if (!photonView.isMine) //If it is another player, we have to correct its position
{
// We get 10 updates per sec. sometimes a few less or one or two more, depending on variation of lag.
// Due to that we want to reach the correct position in a little over 100ms. This way, we usually avoid a stop.
// Lerp() gets a fraction value between 0 and 1. This is how far we went from A to B.
//
// Our fraction variable would reach 1 in 100ms if we multiply deltaTime by 10.
// We want it to take a bit longer, so we multiply with 9 instead.
fraction += Time.deltaTime * 9;
Vector3 newPos = Vector3.Lerp(this.lastCorrectPlayerPos, this.correctPlayerPos, fraction);
newPos.z = transform.localPosition.z;
transform.localPosition = newPos;
}
}
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
// We own this player: send the others our data
Vector3 pos = transform.localPosition;
stream.Serialize(ref pos);
Quaternion rot = transform.rotation;
stream.Serialize(ref rot);
controlPlayer plScript = (controlPlayer)transform.GetComponent("controlPlayer");
int actualPath = (int)plScript.currentPath;
stream.Serialize(ref actualPath);
}
else
{
Vector3 pos = Vector3.zero;
stream.Serialize(ref pos);
this.correctPlayerPos = pos;
this.lastCorrectPlayerPos = transform.localPosition;
fraction = 0;
Quaternion rot = Quaternion.identity;
stream.Serialize(ref rot);
transform.rotation = rot;
int actualPath = 0;
stream.Serialize(ref actualPath);
controlPlayer plScript = (controlPlayer)transform.GetComponent("controlPlayer");
plScript.currentPath = (mapManager.pathType) actualPath;
}
}[/code2]
My concern is about the position is not very accurate. I post a video showing the problems. The capsules represent the players (the centered one is the main player of each client), and they appear with different distance values on each screen. What am I doing wrong?
https://www.dropbox.com/s/t1zrj7ipp96v2 ... 16581.mov
0
Comments

Getting positions right with varying levels of lag is pretty difficult.
Have a look at the synchronization demo in PUN. It shows various variants how to handle lag.
One option it doesn't show is: Send a keyinput right away but execute it ~100ms later locally. This gives the message some time to travel and players might be more in sync.0