2016-07-07 4 views
2

Я пытаюсь отправить массив различных базовых типов по сети, используя атрибут ClientRpc. В documentation состоянии, что я могу отправить их по сети без проблем:Отправка массива примитивных типов по вызову ClientRPC

  • основных типов (байты, целый, дробный, строка, uint64 и т.д.)
  • массивов основных типов

Однако, похоже, что их смешанные комбинации в массиве object[] не работают. У меня есть следующий пример:

[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?

+0

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

+0

Проблема в том, что я не знаю тип на стороне клиента. Обратите внимание, что 'GetType()' дает вам _actual тип во время выполнения_, который потерялся – Felk

+0

Пробовал ли вы 'if (o is System.String)', а затем его бросил? –

ответ

1

Возможный обходной путь будет вручную сериализации массив и отправить его в качестве byte[]:

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

выход на клиента и на стороне сервера одинаковы, то, как и следовало ожидать.

+0

Я тоже думал об этом. Спасибо - может быть полезно в будущем. –

+0

Обратите внимание, что этот подход является предельным, так как вы не можете включать некоторые типы Unity, которые в противном случае могут отправляться, например Networked GameObjects – Felk

+0

. Еще один недостаток заключается в том, что 'BinaryFormatter' из' System.Runtime.Serialization.Formatters.Binary' недоступен на множестве подмножеств .NET. Это можно исправить, используя другой, более широко доступный Serializer, такой как 'XmlSerializer' – Felk

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

  • Нет связанных вопросов^_^