2016-03-07 40 views
0

我試圖通過網絡同步玩家的位置和旋轉角度。我已經有部分工作了。在Unity3d中通過UNET進行同步

我有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)? 也看[this](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; 
    } 
} 

}