Unity Multiplayer Networking..... in 2D!?!? crazy i know!

Hey Everyone, Im prototyping a multiplayer game loosely following a tutorial i found here: How to create an online multiplayer game with Unity - Paladin Studios

I am trying to get smooth transitions over the network, but in 2D!
Here is my PlayerMove Script.

using UnityEngine;
using System.Collections;

public class PlayerMovement : MonoBehaviour {
	
	public float playerSpeed = 10;
	public float jumpPower = 350;
	public bool isGrounded = false;
	private Vector3 moveX;

	//network Variables
	private float lastSynchronizationTime = 0f;
	private float syncDelay = 0f;
	private float syncTime = 0f;
	private Vector2 syncStartPos = Vector2.zero;
	private Vector2 syncEndPos = Vector2.zero;
	
	void OnCollisionEnter2D(Collision2D Col){
		if (Col.gameObject.layer == 8) {
			isGrounded = true;
		}
	}
	
	// Update is called once per frame
	void Update () {
		if (networkView.isMine){
			Inputmanager ();
		}
		else
		{
			SyncedMovement();
		}
	}

	void Inputmanager(){
		moveX = Input.GetAxis("Horizontal") * transform.right * Time.deltaTime * playerSpeed;
		transform.Translate (moveX);
		if (Input.GetButtonDown ("Jump") && isGrounded == true){
			Jump();
		}
	}

	void Jump () {
		gameObject.rigidbody2D.AddForce (Vector3.up * jumpPower);
		isGrounded = false;
	}

	private void SyncedMovement()
	{
		syncTime += Time.deltaTime;
		rigidbody2D.position = Vector2.Lerp(syncStartPos, syncEndPos, syncTime / syncDelay); //This is the error causing Line.
	}


	void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info){
		Vector3 syncPos = Vector3.zero;
		if (stream.isWriting){
			syncPos = rigidbody2D.position;
			stream.Serialize(ref syncPos);
		}
		if (stream.isReading){
			stream.Serialize(ref syncPos);
			rigidbody2D.position = syncPos;		
		}
		else
		{
			stream.Serialize (ref syncPos);
			syncTime = 0f;
			syncDelay = Time.time - lastSynchronizationTime;
			lastSynchronizationTime = Time.time;
			syncStartPos = rigidbody2D.position;
			syncEndPos = syncPos;
		}
	}

}

Currently when the second player is instantiated, he slowly falls down from where he is instantiated to the ground, as soon as he gets there he jolts back up to where he was instantiated. he cant be controlled and the other player is only visible in short blinks when you move him around sporadically.

If i comment out this line: rigidbody2D.position = Vector2.Lerp(syncStartPos, syncEndPos, syncTime / syncDelay); everything works dandy, he falls down and the physics look normal, except i don’t get the smooth transitions i’m after. Does anyone know the work around for this problem?

If anyone gives me a solution i will award you 15 awesome points in my awesome game (…its just where i give people online points for being awesome haha).

Thanks for giving this a look, you can contact me on twitter for your awesome points :wink: https://twitter.com/DavidMcdonald89

Since every player is controlling his own character locally (and just broadcasting it’s own state) there’s no use of doing manual “smoothing / lerping / interpolation”. All you have to do is adding the rigidbody’s velocity as well. Also your OnSerializeNetworkView looks very strange. It looks like you serializing the position two times while you deserializing it only once. isReading and isWriting are actually never true at the same time. They actually follow the rule:

isReading = !isWriting;

I usually use it like this. I added the velocity:

void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
    Vector3 syncPos = rigidbody2D.position;
    Vector3 velocity = rigidbody2D.velocity;
    
    stream.Serialize(ref syncPos);
    stream.Serialize(ref velocity);
    
    if (stream.isReading)
    {
        rigidbody2D.position = syncPos;
        rigidbody2D.velocity = velocity;
    }
}

Keep in mind that in case your object can rotate as well, you should add rotation and angularVelocity as well.

Now the other players get the position as well as it’s velocity so the object will move the the same speed as it’s counterpart. If you really want to implement snapshots it’s a bit more tricky. Each snapshot should save it’s timestamp and you would interpolate between the two last received snapshots based on the timestamps.