0

ネットワーク経由でプレーヤーの位置と回転を同期しようとしています。部分的に機能しています。

ホストとリモートの 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、ローカル プレーヤーをソースとして、ネットワーク経由で自動的に同期できるようにすることです。

リモート接続上にあるのはなぜですか? ホスト上に同期されたオブジェクトが表示されません。それらはすべて正しく表示されます。

4

1 に答える 1

0

これが役立つかどうかはわかりませんが、私が使用している位置と回転の同期用の 2 つのスクリプトを次に示します。おそらく最も最適化されていませんが、機能します:

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

}
于 2016-03-20T15:03:32.227 に答える