Difficulty Implementing Synchronization

Options
Hi guys,

I struggled for hours on Saturday to implement some basic synchronization over Photon Cloud. I get everything to work right when I do a simple:

transform.position = (Vector2)stream.ReceiveNext();

But I'm trying to implement an algorithm that calculates the delay between stream chunks and lerps between the positions. Problem is, my dude just doesn't move. Rotation works but not the position movement (for other players mind you). I've done the code and redone the code at least a half dozen times and it looks like it should be working.

Here's the code. Please help!
	//private Vector2 syncPosition;
	private float lastSynchronizationTime = 0f;
	private float syncDelay = 0f;
	private float syncTime = 0f;
	private Vector2 syncStartPosition = Vector2.zero;
	private Vector2 syncEndPosition = Vector2.zero;

	void Start () {
	
	}

	void Update () {
		if(photonView.isMine){
			InputMovement();
		} else {
			SyncedMovement();
		}
	}

	private void SyncedMovement(){
		syncTime += Time.deltaTime;
		transform.position = Vector2.Lerp(syncStartPosition, syncEndPosition, syncTime/syncDelay);
		//syncStartPosition = transform.position;
	}

	void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info){

		if(stream.isWriting){
			stream.SendNext(transform.position);
		} else {
			//syncPosition = (Vector2)stream.ReceiveNext();

			syncEndPosition = (Vector2)stream.ReceiveNext();
			syncStartPosition = transform.position;

			syncTime = 0f;
			syncDelay = Time.time - lastSynchronizationTime;
			lastSynchronizationTime = Time.time;
		}
	}

Comments

  • vadim
    Options
    Does sync method from DemoSynchronization (Assets\Photon Unity Networking\Demos\DemoSynchronization) work for you? If it does then you can use it as starting point and gradually enhance it if something is not good enough. Also check lerp snippet in Marco Polo Tutorial
    Btw, Vector2 used in your code whereas all mentioned samples use Vector3.
  • Thanks for getting back to me.

    Yes. I can get all of the examples to work. Basic lerping works.

    That's the most frustrating thing is that this is the "incremental next step" for my planned net code.

    What I'm trying to do is to lerp between the start and end positions of each packet at the speed of the time between packets.

    This should be much less choppy than any of the example synchs. I plan on implementing velocity prediction as well. But... I can't get this working. :(
  • vadim
    Options
    So what about Vector2? Is it used intentionally? Did you try Vector3?
    What I'm trying to do is to lerp between the start and end positions of each packet at the speed of the time between packets.
    DemoSynchronization has 4 different sync methods inside. 'Interpolation' looks like what you want.
    Can you tell please why interpolation is not good enough for your project and what we can enhance?
  • I can have trouble explaining myself so bear with me.

    The interpolation with Photon moves a a photonview object halfway between its last position and its current position every time a packet is received.

    In a lot of games this can look very smooth, and certainly looks the best compared to the other examples included in PUN.

    However, this can cause some pretty nasty issues for games where there's fast moving parts and hit detection between players.

    To other players, a photonview transform is always halfway between where it was and where it is going to.

    I'm trying to fix this in two ways, one of which is in the first example I posted below.

    1. Add velocity prediction (not in the example below, but I have working in another prototype).

    2. Calculate the delay between packets and use that as the speed for interpolation. This helps ensure a steadier movement. This is what I'm having trouble with in the example below.

    So let me walk you through my algorithm. You can see the implementation in the code I posted in my first post. If you can help me figure this out it would be a great thing to improve your tutorials with!

    Note: I'm using Vector2 transform.position hear because I'm using 2D sprites and it would be a waste of data to send the extra variable.

    In OnPhotonSerializeView:
    1. Use the stream.isWriting to send my Vector2 transform.position to the server.
    2. Use stream.isReading to receive that position and store it in a variable called End Position. This is the variable we will be interpolating to.
    3. Store the current transform in a variable called Start Position. This is the place we will be interpolating from.
    4. Set a variable called Time to zero. This will measure the time between frames.
    5. Set a variable called Synchronization Time to the current time.
    6. Set a variable called Delay to the current time minus the last Synchronization Time call. This calculates the delay between packets.

    In SynchedMovement:
    1. Add the time since the last frame to Time.
    2. Here's where all the magic happens (is supposed to anyway). My position interpolates each frame between my current position and the position I last received from the server. The speed in which I move is (MyTimeBetweenFrames/MyTimeBetweenPackets). This way if I receive more delay between packets I give my object more time to "catch up" to the end position, making the movement seem smoother.

    It's pretty complicated I know. I just don't know what I'm missing here...
  • vadim
    Options
    The interpolation with Photon moves a a photonview object halfway between its last position and its current position every time a packet is received.
    Things are too simplified in your description. The demo keeps last 20 positions/times and interpolates linearly between them. It should be enough to make things run smooth. The only issue is delay which you can't avoid on network.
    Did you try this in your code? We must be sure that at least something works for you. Then enhance it if required.
    Note: I'm using Vector2 transform.position hear because I'm using 2D sprites and it would be a waste of data to send the extra variable.
    Better optimize traffic after things get working at all. Make sure that all ok with Vector3D first.
  • I had the transform observed by the photon object instead of the script. I got it working now... Thanks!