[Simple] [Networking] Smoothing a Rigidbody

Hello, fellows.
I’ve been using Photon Unity Networking 2 package for a simple multi-player project.
It works, but the stutter and lag smudges the experience a lot.


Could you please help?


I have a Player prefab with a Rigidbody attached (arePhotonView and PhotonRigidbodyView too). This prehab has the script listed bellow. Could you please help me finding out what is wrong? Thank you in advance.


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun; //for photon view is mine

public class net_Player : MonoBehaviourPun, IPunObservable {  //for photon view is mine

	public float moveHorizontal;
	public float moveVertical;
	public float movement_speed;
	public Vector3 movement ;

	public GameObject movement_controller;

	public Vector3 networkPosition;
	public Quaternion networkRotation;


	void Start () {
		movement_speed = 100f;
		movement_controller = this.gameObject;
	}


	void FixedUpdate (){
		if (photonView.IsMine) {

			//movement
			moveHorizontal = Input.GetAxis ("axis_X");
			moveVertical = Input.GetAxis ("axis_Y");
			movement = new Vector3 (moveHorizontal, 0f, -moveVertical);
			movement_controller.gameObject.GetComponent<Rigidbody> ().velocity = movement * movement_speed;

		} else if (photonView.IsMine == false) {
			gameObject.GetComponent<Rigidbody>().position = Vector3.MoveTowards(gameObject.GetComponent<Rigidbody>().position, networkPosition, Time.fixedDeltaTime);
			gameObject.GetComponent<Rigidbody>().rotation = Quaternion.RotateTowards(gameObject.GetComponent<Rigidbody>().rotation, networkRotation, Time.fixedDeltaTime * 100.0f);
		}
	}

	public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
	{
		if (stream.IsWriting)
		{
			stream.SendNext(this.gameObject.GetComponent<Rigidbody>().position);
			stream.SendNext(this.gameObject.GetComponent<Rigidbody>().rotation);
			stream.SendNext(this.gameObject.GetComponent<Rigidbody>().velocity);
		}
		else
		{
			networkPosition = gameObject.GetComponent<Rigidbody>().position = (Vector3) stream.ReceiveNext();
			networkRotation = gameObject.GetComponent<Rigidbody>().rotation = (Quaternion) stream.ReceiveNext();
			gameObject.GetComponent<Rigidbody>().velocity = (Vector3) stream.ReceiveNext();

			float lag = Mathf.Abs((float) (PhotonNetwork.Time - info.SentServerTime));
			networkPosition  += (this.gameObject.GetComponent<Rigidbody>().velocity * lag);
		}
	}
}

Hey there,

most probably everything is working as it should, even though i think you dont even need the rigidbody view since you manage the position syncing manually.

your issue probably is in Vector3.MoveTowards. This will result in a constant speed. If your update is too late the image of the player will already have arrived and stop at the last known position until the new one is there.
This will only work if you have exact timings and one reeeeaaly specific velocity.

what worked for me was using Lerp. If you choose the lerp value conservative small there should be no stuttering. Note though that this will increase the difference between real and notworked position slightly.

If something was unclear let me know.

A way to simply test this would be to add a transform view and trash the manual pos syncing. there you can test some different ways to update positions.