Predict / Sync Movements

Options
jyw
jyw
edited November 2014 in DotNet
Hello,

I'm working on a small network game to get used to photon network.
I have some troubles predicting and syncing the avatar's movement.

When Player1 moves his avatar to the same direction and same speed, it should be easy to predict the position of his character.
On Player1s side: I send the avatar's position and movedirection * speed through through the network.
On Player2s side: I calculate the time difference and predict Player1's avatar position by
predictedPosition = m_networkPlayerPos + m_networkMoveVector * (1f + timePassed);

I continue predicting the position until new data arrives with this code
predictedPosition = rigidbody2D.position + m_moveVector;

When new data arrives I compare my estimated avatar's position with where it should be, however this is always off by ~0.6.
Debug.Log("New Data. Where Avatar is: " + rigidbody2D.position + "\nWhere he should be: " +  predictedPosition);

Did I forget to add anything? Can you guys help me a bit? ;)
The code snipples above are taken from this method:
void UpdateNetworkPosition() {
        Vector2 predictedPosition;
        if (m_previousNetworkDataReceivedTime != m_lastNetworkDataReceivedTime) {
            //new data arrived
            float timePassed = (float)(PhotonNetwork.time - m_lastNetworkDataReceivedTime);
            predictedPosition = m_networkPlayerPos + m_networkMoveVector * (1f + timePassed);

            Debug.Log("New Data. Where Avatar is: " + rigidbody2D.position + "\nWhere he should be: " +  predictedPosition);
            m_previousNetworkDataReceivedTime = m_lastNetworkDataReceivedTime;
        }
        else {
            //no new data
            predictedPosition = rigidbody2D.position + m_moveVector;
        }
        rigidbody2D.MovePosition(predictedPosition);
    }

Comments

  • vadim
    Options
    Hi,

    How do you set m_lastNetworkDataReceivedTime?
    Looks like It should be equal to PhotonNetwork.time on Player1 client when it sends position (assuming that m_networkPlayerPos is Player1 position at that time).
  • jyw
    Options
    How do you set m_lastNetworkDataReceivedTime?
    Looks like It should be equal to PhotonNetwork.time on Player1 client when it sends position (assuming that m_networkPlayerPos is Player1 position at that time).
    That is correct.
    Its set in OnPhotonSerializeView when I get new position etc.
    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) {
            AvatarMovement.SerializeState(stream, info);
        }
    
        public void SerializeState(PhotonStream stream, PhotonMessageInfo info) {
            if (stream.isWriting) {
                //We own this player: send the others our data
                stream.SendNext((Vector2)transform.position);
                stream.SendNext(transform.rotation);
                stream.SendNext(m_moveVector); 
            }
            else {
                //Network player, receive data
                m_networkPlayerPos = (Vector2)stream.ReceiveNext();
                m_networkPlayerRot = (Quaternion)stream.ReceiveNext();
                m_networkMoveVector = (Vector2)stream.ReceiveNext();
                m_lastNetworkDataReceivedTime = info.timestamp;
            }
        }
    

    If I print timePassed, its usually around 0.032 - 0.063. It seem very small. Is the internet really that fast ? :D
  • vadim
    Options
    Looks like your internet is quite fast. 30-60 ms ping is good.

    Btw, why do you need m_previousNetworkDataReceivedTime != m_lastNetworkDataReceivedTime check?
    You can always interpolate from last received position or else you use timePassed only once per position update.