2016-03-07 99 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; 
    } 
} 

}