2016-03-07 3 views
0

Я пытаюсь синхронизировать позицию игрока и вращать его по сети. У меня есть частичная работа.Проблемы синхронизации по UNET в Unity3d

У меня есть 2 игрока - хост и удаленный. При просмотре экрана хоста я вижу правильное расположение локального и сетевого плеера. Когда на пульте дистанционного управления я вижу правильное расположение локального, но не сетевого игрока.

Это моя синхронизация сценарий:

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; 
     } 
    } 
} 

Идея заключается в том, я должен быть в состоянии бросить этот скрипт на любом объекте с Rigidbody и он должен автоматически синхронизировать по сети, с локальным игроком является источником.

Почему это на удаленных подключениях Я не вижу синхронизированный объект на хосте, я вижу их все правильно?

+0

Почему вы не используете [NetworkTransform] (http://docs.unity3d.com/ScriptReference/Networking.NetworkTransform. HTML)? И посмотрите на [это] (http://docs.unity3d.com/Manual/class-NetworkTransform.html). –

ответ

0

Я не знаю, поможет ли это вам, но вот два сценария для синхронизации положения и вращения, которые я использую для меня. Может быть, не самый оптимизированный, но они работают:

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; 
    } 
} 
} 

Вращение:

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; 
    } 
} 

} 
Смежные вопросы