Unity3d 通过ClientRPC调用发送基元类型数组

Unity3d 通过ClientRPC调用发送基元类型数组,unity3d,rpc,unity5,unity3d-unet,Unity3d,Rpc,Unity5,Unity3d Unet,我试图使用ClientRpc属性通过网络发送各种基本类型的数组。我可以通过网络毫无问题地发送这些信息的状态: 基本类型(字节、整数、浮点、字符串、UInt64等) 基本类型数组 但是,将它们混合在对象[]数组中似乎不起作用。我举了以下例子: [Command] void CmdForwardEvent(string eventName, object[] args) { Debug.Log ("Broadcasting event: " + eventName); forea

我试图使用
ClientRpc
属性通过网络发送各种基本类型的数组。我可以通过网络毫无问题地发送这些信息的状态:

  • 基本类型(字节、整数、浮点、字符串、UInt64等)
  • 基本类型数组
但是,将它们混合在
对象[]
数组中似乎不起作用。我举了以下例子:

[Command]
void CmdForwardEvent(string eventName, object[] args) {
    Debug.Log ("Broadcasting event: " + eventName);
    foreach (var o in args) {
        Debug.Log ("arg-class: " + o.GetType() + ": " + o);
    }
    RpcForwardEvent (eventName, args);
}

[ClientRpc]
void RpcForwardEvent(string eventName, object[] args) {
    Debug.Log ("Received event " + eventName);
    foreach (var o in args) {
        Debug.Log ("arg-class: " + o.GetType() + ": " + o);
    }
}

void Update() {
    if (Input.GetKeyDown (KeyCode.P)) {
        CmdForwardEvent("Testevent", new object[]{"some string", 1, false});
    }
}
在服务器上,我获取输出

Broadcasting event: Testevent
arg-class: System.String: some string
arg-class: System.Int32: 1
arg-class: System.Boolean: false
在客户机上,此消息不会出现任何错误:

Received event: Testevent
arg-class: System.Object: System.Object
arg-class: System.Object: System.Object
arg-class: System.Object: System.Object

如何通过ClientRpc调用发送具有不同基本类型的各种数量的参数?

一种可能的解决方法是手动序列化数组并将其作为
字节[]发送。

// new code

private BinaryFormatter bf = new BinaryFormatter();

private byte[] objectToBytes(object os) {
    MemoryStream stream = new MemoryStream ();
    bf.Serialize (stream, os);
    return stream.ToArray ();
}

private object bytesToObject(byte[] bytes) {
    MemoryStream stream = new MemoryStream (bytes);
    return bf.Deserialize (stream);
}

// modified code:

[Command]
void CmdForwardEvent(string eventName, byte[] argsAsBytes) {
    object[] args = bytesToObject(argsAsBytes) as object[];  // deserialize
    Debug.Log ("Broadcasting event: " + eventName);
    foreach (var o in args) {
        Debug.Log ("arg-class: " + o.GetType() + ": " + o);
    }
    RpcForwardEvent (eventName, argsAsBytes);
}

[ClientRpc]
void RpcForwardEvent(string eventName, byte[] argsAsBytes) {
    object[] args = bytesToObject(argsAsBytes) as object[];  // deserialize
    Debug.Log ("Received event " + eventName);
    foreach (var o in args) {
        Debug.Log ("arg-class: " + o.GetType() + ": " + o);
    }
}

void Update() {
    if (Input.GetKeyDown (KeyCode.P)) {
        // serialize
        byte[] bytes = objectToBytes(new object[]{"some string", 1, false});
        CmdForwardEvent("Testevent", bytes);
    }
}

客户端和服务器端的输出与预期一样。

但它正在工作,不是吗?您可以通过强制转换将这些值取消绑定到客户端上所需的任何基元类型。我真的不知道问题出在哪里。问题是我不知道客户端的类型。请注意,
GetType()
在运行时为您提供了实际的类型,该类型在您尝试
if(o是System.String)
然后强制转换时丢失了?
o是System.String
返回false。接收端上的对象似乎是空对象,因为它们的ToString产生
System.object
。我更新了问题以包含每个对象的字符串表示。我看到了。谢谢,现在我看到了问题。我会想办法的,我也在想。谢谢-可以在将来使用。请注意,这种方法是有局限性的,因为您不能包括Unity可以以其他方式本机发送的某些类型,如网络游戏对象。另一个缺点是,
System.Runtime.Serialization.Formatters.Binary
中的
BinaryFormatter
在许多.NET子集上都不可用。这可以通过使用另一个更广泛可用的序列化程序(如
XmlSerializer