- Home /
[PUN] Syncing Rigidbodies across network.
Hello! I've been searching for the past few hours on how to sync rigidbodies across the network using Photon Unity Networking.
This is my code:
using UnityEngine;
using System.Collections;
public class BallSynchronize : Photon.MonoBehaviour
{
Vector3 realPosition = Vector3.zero;
Quaternion realRotation = Quaternion.identity;
Vector3 realPosition1 = Vector3.zero;
Vector3 realVelocity1 = Vector3.zero;
Quaternion realRotation1 = Quaternion.identity;
Vector3 realVelocity2 = Vector3.zero;
public void Update ()
{
if(!photonView.isMine)
{
transform.position = Vector3.Lerp(transform.position, realPosition, 0.1f);
transform.rotation = Quaternion.Lerp(transform.rotation, realRotation, 0.1f);
}
}
public void FixedUpdate ()
{
if(!photonView.isMine)
{
rigidbody.position = Vector3.Lerp(rigidbody.position, realPosition1, 0.1f);
rigidbody.velocity = Vector3.Lerp(rigidbody.velocity, realVelocity1, 0.1f);
rigidbody.rotation = Quaternion.Lerp(rigidbody.rotation, realRotation1, 0.1f);
rigidbody.angularVelocity = Vector3.Lerp(rigidbody.angularVelocity, realVelocity2, 0.1f);
}
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if(stream.isWriting)
{
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
stream.SendNext(rigidbody.position);
stream.SendNext(rigidbody.rotation);
stream.SendNext(rigidbody.velocity);
stream.SendNext(rigidbody.angularVelocity);
}
else
{
realPosition = (Vector3)stream.ReceiveNext();
realRotation = (Quaternion)stream.ReceiveNext();
realPosition1 = (Vector3)stream.ReceiveNext();
realRotation1 = (Quaternion)stream.ReceiveNext();
realVelocity1 = (Vector3)stream.ReceiveNext();
realVelocity2 = (Vector3)stream.ReceiveNext();
}
}
}
Except it just goes immediately to 0, 0, 0 and not where I place it in the scene. Any help on why this may be?
Answer by Flassari · Oct 13, 2014 at 04:02 PM
The last parameter to LERP must change over time, otherwise it will just be constantly at 10% if you keep it at 0.1.
If you still have the demos that came with PUN, search for the NetworkLerp class that should show you in a nutshell how to do it.
I'm pasting here the relevant code in case you don't have it.
Also, make sure that if you are not the photon owner of the ball that the rigidBody is set to kinematic.
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
Vector3 pos = transform.localPosition;
Quaternion rot = transform.localRotation;
stream.Serialize(ref pos);
stream.Serialize(ref rot);
stream.SendNext(_inputController.isMoving);
}
else
{
// Receive latest state information
Vector3 pos = Vector3.zero;
Quaternion rot = Quaternion.identity;
stream.Serialize(ref pos);
stream.Serialize(ref rot);
_animation.SetBool("isMoving", (bool) stream.ReceiveNext());
_latestCorrectPos = pos; // save this to move towards it in FixedUpdate()
_onUpdatePos = transform.localPosition; // we interpolate from here to latestCorrectPos
_latestCorrectRot = rot; // save this to move towards it in FixedUpdate()
_onUpdateRot = transform.localRotation; // we interpolate from here to latestCorrectPos
_fraction = 0; // reset the fraction we alreay moved. see Update()
}
}
public void Update()
{
// 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 = _fraction + Time.deltaTime * 9;
transform.localPosition = Vector3.Lerp(_onUpdatePos, _latestCorrectPos, _fraction); // set our pos between A and B
transform.localRotation = Quaternion.Lerp(_onUpdateRot, _latestCorrectRot, _fraction); // set our rotation between A and B
}
_fraction = _fraction + Time.deltaTime * 9;
transform.localPosition = Vector3.Lerp(_onUpdatePos, _latestCorrectPos, _fraction);
This is wrong because _fraction > 1 and Lerp max value is 1.
Vector3.Lerp can takes a lerp value > 1. If so, transform.localPosition
will be equal to _latestCorrectPos
, even if _fraction
= 999999 ;
You created an account and revived a 2 year old question for this?
1: _fraction is reset to 0 each network update, 10 times per second. That means the deltatime between each network update will be maximum 0.1f. It lerps for 90% of this by multiplying by 9 (0.0f -> 0.9f), giving 10% extra as lag buffer for each update. That means if the network acts perfectly this Lerp function will never get a number bigger than 0.9f. This is all explained in the commented code.
2: In Unity's official documentation for Lerp it states, and I quote: "The parameter t is clamped to the range [0, 1]." Not only for our case is it expected, we DEPEND on it to do it so the Lerp function doesn't overshoot the interpolation.
You can say whatever you like but fact is it does not work.
Explain what does not work if you want precise answers
And I won't say anything, with this kind of attitude you can fix your own code yourself.
Your answer
Follow this Question
Related Questions
Unity array out of range exception, using photon unity network. 1 Answer
Photon only shows host their changes to players, not other way around 1 Answer
Syncing FPS Firing Sound over network via RPC {PHOTON} 1 Answer
How to instatiate two players simultaneoulsy before loading level 1 Answer
Multiplayer Raycasting 0 Answers