0

I'm trying to sync a player's position and rotation over the network. I've got things partially working.

I have 2 players a Host and Remote. When looking at the Host's screen I see the correct location for the local and network player. When on the Remote I see the correct location for the local but not the networked player.

This is my sync script:

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(NetworkIdentity))]
public class SyncRigidbody : NetworkBehaviour {

    public float positionLerpSpeed = 10f;
    public float positionThreshold = 0.0025f;
    public float rotationLerpSpeed = 10f;
    public float rotationThreshold = 2f;

    private Rigidbody _rigidbody;
    private Vector3 _requestedPos;
    private Vector3 _lastPos;
    private Quaternion _requstedRot;
    private Quaternion _lastRot;

    void Start () {
        _rigidbody = gameObject.GetComponent<Rigidbody> ();
        if (!isLocalPlayer) {
            _rigidbody.isKinematic = true;
        }
    }

    void Update () {
        TransmitPosition ();
        TransmitRotation ();
        LerpPosition ();
        LerpQuaternion ();
    }

    void LerpPosition () {
        if (!isLocalPlayer) {
            _rigidbody.MovePosition (_requestedPos);
        }
    }

    void LerpQuaternion () {
        if (!isLocalPlayer && _requstedRot.w != 0) {
            _rigidbody.MoveRotation (_requstedRot);
        }
    }

    [Command]
    void CmdUpdateTransformPosition (Vector3 pos) {
        Debug.Log ("CmdUpdateTransformPosition: For " + gameObject.name + " to " + pos);
        _requestedPos = pos;
    }

    [Command]
    void CmdUpdateTransformRotation (Quaternion rot) {
        Debug.Log ("CmdUpdateTransformRotation: For " + gameObject.name + " to " + rot);
        _requstedRot = rot;
    }

    [Client]
    void TransmitPosition () {
        if (isLocalPlayer && Vector3.Distance (_rigidbody.position, _lastPos) > positionThreshold) {
            Debug.Log ("TransmitPosition: For " + gameObject.name + " to " + _rigidbody.position);
            CmdUpdateTransformPosition (_rigidbody.position);
            _lastPos = _rigidbody.position;
        }
    }

    [Client]
    void TransmitRotation () {
        if (isLocalPlayer && Quaternion.Angle (_rigidbody.rotation, _lastRot) > rotationThreshold) {
            Debug.Log ("TransmitRotation: For " + gameObject.name + " to " + _rigidbody.rotation);
            CmdUpdateTransformRotation (_rigidbody.rotation);
            _lastRot = _rigidbody.rotation;
        }
    }
}

The idea is I should be able to toss this script on any object with a Rigidbody and it should automatically sync over the network, with the local player being source.

Why is it on the Remote connections I'm not seeing the synced object on on the Host I see them all correctly?

Justin808
  • 20,859
  • 46
  • 160
  • 265
  • Why you don't use [NetworkTransform](http://docs.unity3d.com/ScriptReference/Networking.NetworkTransform.html)? And look at [this](http://docs.unity3d.com/Manual/class-NetworkTransform.html) also. – Barış Çırıka Mar 07 '16 at 11:39

1 Answers1

0

I do not know if this will help you but here is two script for position and rotation synchronization that i am using that works for me. Maybe not the most optimised but they work:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Player_SyncPosition : NetworkBehaviour {

private Transform myTransform;
[SerializeField] float lerpRate = 15;
[SyncVar] private Vector3 syncPos;

private Vector3 lastPos;
private float threshold = 0.5f;

void Start () {
    myTransform = GetComponent<Transform> ();
}


void FixedUpdate () {
    TransmitPosition ();
    LerpPosition ();
}

void LerpPosition () {
    if (!isLocalPlayer) {
        myTransform.position = Vector3.Lerp (myTransform.position, syncPos, Time.deltaTime * lerpRate);
    }
}

[Command]
void Cmd_ProvidePositionToServer (Vector3 pos) {
    syncPos = pos;
}

[ClientCallback]
void TransmitPosition () {
    if (isLocalPlayer && Vector3.Distance(myTransform.position, lastPos) > threshold) {
        Cmd_ProvidePositionToServer (myTransform.position);
        lastPos = myTransform.position;
    }
}
}

Rotation:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Player_SyncRotation : NetworkBehaviour {

private Transform myTransform;

// Object rotation vars
[SyncVar] private Quaternion syncObjectRotation;
public float rotationLerpRate = 15;

private Quaternion lastRot;
private float threshold = 5f;


private void Start() {
    myTransform = GetComponent<Transform> ();
}

private void FixedUpdate () {
    LerpRotation ();
    TransmitRotation (); 
}

private void LerpRotation() {

    if (!isLocalPlayer) {
        myTransform.rotation = Quaternion.Lerp (myTransform.rotation, syncObjectRotation, Time.deltaTime * rotationLerpRate);
    }

}

[Command]
private void Cmd_ProvideRotationToServer (Quaternion objectRotation) {
    syncObjectRotation = objectRotation;
}

[ClientCallback]
private void TransmitRotation() { // Send rotation to server
    if (isLocalPlayer && Quaternion.Angle(myTransform.rotation, lastRot) > threshold) {
        Cmd_ProvideRotationToServer (myTransform.rotation);
        lastRot = myTransform.rotation;
    }
}

}
PeterK
  • 4,243
  • 4
  • 44
  • 74