Synchronize moving platform over network(jerkin on client)

The whole answer can be found below.

Please note: The Photon forum is closed permanently. After many dedicated years of service we have made the decision to retire our forum and switch to read-only: we've saved the best to last! And we offer you support through these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation on PUN.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

Synchronize moving platform over network(jerkin on client)

Azaldur
2011-12-20 13:39:44

Hey, I made a multiplayer game where one of my players got control over a platform and can move it. This works fine. But when an other player, who is not the network owner(this is the first player joining the game, who can also control the platform), stands on the platform, the screen and platform "jerks"(i hope it is the right word to describe this behaviour, i'm not native englisch :D . An other word i found is "bucking"). I tried using physics and also transform.translate but its not working right. If i look with the "platform network owner" player to the other player he also isn't in its right position, where he is on his own screen. This error also happens only when the players stands on the platform. I hope someone can help me :) .

Comments

Leepo
2011-12-21 10:47:50

Networking physics can be quite troublesome and needs to be thought out well. You have quite a few options here, however most important is that you need to be aware of what you are sending and who controls the movement.

Some options:

  • Don't network physics. This is probably not an option for you.
  • Authorative masterclient: Make ONLY the masterclient control the objects (and have the other clients smooth the received positions with the current position: use Lerp
  • Keep the solution as is, with different owners (or even multiple owner)..but make sure you apply smoothing. Dont set the positions directly but lerp towards the correct value: // Here correctVector3 is a Vector3 that you send/receive via OnSerializePhotonView transform.position = Vector3.Lerp(transform.position, correctVector3, Time.deltaTime);

Azaldur
2011-12-21 13:21:54

Hey Leepo, thanks for your answer :). I already lerp the position and rotation, but that doesnt work right. I'm currently not using physics(rigidbody), but transform.translate to move the platform. But the problem is still there. I tried a differend solution, now. I send rpcs to the other players, when the movement of the platform changes. This seems to work(no jerking), but maybe this does get to problems later? But also with this solution, the other players doesnt appear at the same position as they really are while the platform is moving. When the platform doesnt move they return to their real position(like it is on their own screen). If you don't exactly now where my problem is, i can also explain it in german(because i know that some of you are from germany, like myself :) ).

Azaldur
2011-12-22 14:11:21

Also when i join the game with a second player there is a "yellow" warning: "New player=False player: testst nr=2". This sounds as if the player can't join the game, but he can and nothing else happens, despite the warning. Somebody know what that means?

Azaldur
2012-02-29 12:52:26

EDIT: Solved it :)

I really don't know what else i could try to make this work. This is the network code i got currently in the project. It's very basic and just vor testing purposes(i use the photon network engine). My problem is that if two or more players stand on a moving platform, the other players you are looking at with your own player shake back and fourth violently and appear a little bit behind the position they are on their own screen. This only happens on a moving object, on a firm ground everything works fine. Your own player doesnt shake, so i think its a problem with the network code. I tried many different things but I dont get it to work and really got no idea what the problem could be. I also used other methods like the Character Motor + FpsInput controller for the movement of the players, but that doesnt changed anything. I also tried to stream the movement of the ship the same way like the players and not with rpcs and I also parented the players to the ship(like you can see in the code below). I further tried to move the ship with add.relative force instead of transform.Translate. But none of this solved the problem. In the current version no rigidbody is attached to the platform or the players.

Code on the players:

using UnityEngine;
using System.Collections;

public class NetworkController : Photon.MonoBehaviour {

    MouseLook camScript;
    Firstpersoncontrol controllerScript;

    // Use this for initialization
    void Awake () {
       camScript = GetComponent<MouseLook>();
       controllerScript = GetComponent<Firstpersoncontrol>();
       GameObject Platform = GameObject.Find("PlatformPrefab");

       transform.parent = Platform.transform;
    }


    void Start() {
       //Either own player or a remote Instantisted player
       if (photonView.isMine)
       {
         camScript.enabled = true;
         Transform camTrans = Camera.main.transform;
         camTrans.parent = transform;
         camTrans.localPosition = new Vector3(0, 1, 0);
         camTrans.localEulerAngles = new Vector3(10, 0, 0);
       }
       else{
         camScript.enabled = false;
       }

        controllerScript.SetIsLocalPlayer(photonView.isMine);
    }


// Syncronisation von Position, Rotation usw.

    private Vector3 correctPosition = Vector3.zero;
    private Quaternion correctRotation = Quaternion.identity;

    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
       if (stream.isWriting)
       {     
         stream.SendNext(transform.position);
         stream.SendNext(transform.rotation);

       }
       else
       {
         correctPosition = (Vector3)stream.ReceiveNext();
         correctRotation = (Quaternion)stream.ReceiveNext();

       }

    }

    void FixedUpdate()
    {
       if(!photonView.isMine)         
       { 
         transform.position = Vector3.Lerp(transform.position, correctPosition, Time.deltaTime * 5);
         transform.rotation = Quaternion.Lerp(transform.rotation, correctRotation, Time.deltaTime * 5);

        }
    }

}

Code on the Platform:

using UnityEngine;
using System.Collections;

public class PlatformNetworkController : Photon.MonoBehaviour {
    public bool ja = false;
    public bool links = false; // move up, down, right etc.
    public bool rechts = false;
    public bool oben = false;
    public bool unten = false;
    public int geschwindigkeit = 0;


    // MouseLook camScript;
    // CharacterMotor controllerScript;
    // FPSInputController controllerScript2;


    // Use this for initialization

    void Awake () {

    }


    void Start() {

    }




// Syncronisation von Position, Rotation usw.

    [RPC]
    void SendMessage(int geschw, Vector3 pos, Quaternion rot)
    {
    transform.position = pos;
    transform.rotation = rot;
    geschwindigkeit = geschw;
    ja = !ja;
    }

    [RPC]
    void Links()
    {
    links = !links;
    }

    [RPC]
    void Rechts()
    {
    rechts = !rechts;
    }

    [RPC]
    void Oben()
    {
    oben = !oben;
    }

    [RPC]
    void Unten()
    {
    unten = !unten;
    }



    void FixedUpdate()
    {
       if ((Input.GetButtonDown("E") ))  {
       photonView.RPC("SendMessage", PhotonTargets.All, 5, transform.position, transform.rotation);
        }

       if (ja == true) {
        transform.Translate(0 , 0 , geschwindigkeit * Time.deltaTime) ;  // Z direction
        }

       if (Input.GetButtonDown("G")) {
        photonView.RPC("Rechts", PhotonTargets.All);
       }

       if (Input.GetButtonUp("G")) {
        photonView.RPC("Rechts", PhotonTargets.All);
       }

       if (rechts){       
        transform.Rotate(0 ,-30 * Time.deltaTime , 0);  
       }

       if (Input.GetButtonDown("J")) {
        photonView.RPC("Links", PhotonTargets.All);
       }

       if (Input.GetButtonUp("J")) {
        photonView.RPC("Links", PhotonTargets.All);
       }

       if (links){     
        transform.Rotate(0, 30 * Time.deltaTime, 0);  
       }

       if (Input.GetButtonDown("Z")) {
        photonView.RPC("Oben", PhotonTargets.All);
       }

       if (Input.GetButtonUp("Z")) {
        photonView.RPC("Oben", PhotonTargets.All);
       }

       if (oben){
        transform.Translate(0 ,4 * Time.deltaTime , 0);     
       }

       if (Input.GetButtonDown("H")) {
        photonView.RPC("Unten", PhotonTargets.All);
       }

       if (Input.GetButtonUp("H")) {
        photonView.RPC("Unten", PhotonTargets.All);
       }

       if (unten){
        transform.Translate(0, -4 * Time.deltaTime, 0);  // Z direction
        }


    }
}

Fps control script:

using UnityEngine;

using System.Collections;

[RequireComponent(typeof(CharacterController))]

public class Firstpersoncontrol : MonoBehaviour  {

    public float speed = 6.0F;

    public float jumpSpeed = 8.0F;

    public float gravity = 20.0F;

    private bool isLocalPlayer = false;

    public void SetIsLocalPlayer(bool val) {   

         isLocalPlayer = val;

    }

    private Vector3 moveDirection = Vector3.zero;

    void Update() {
       if (!isLocalPlayer) return;
       CharacterController controller = GetComponent<CharacterController>();     

       if (controller.isGrounded) {

       moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
       moveDirection = transform.TransformDirection(moveDirection);
       moveDirection *= speed;

       if (Input.GetButton("Jump"))
       moveDirection.y = jumpSpeed;   
       }

       moveDirection.y -= gravity * Time.deltaTime;
       controller.Move(moveDirection * Time.deltaTime);
    }

There are some german words in the code, but I hope it is clear. In the ship network code the button you push determines in which direction the platform moves(unten = up, links = left etc.). I hope someone can help me by reading the network code I posted :).

Back to top