- Home /
The question is answered, right answer was accepted
Is there a more flexible method of sending data over network than RPC?
I've asked a similar question before and got a "working" solution but it is not ideal and has it's limitations. I'm wondering if there's another way to send data over the network aside from RPC or perhaps a more powerful way of using RPC? Ideally I'd like to be able to send any object across the network. Right now I have a PlayerData object that I want to send to the server and other clients, this contains all the information about a player (name, level, avatar, etc) and it not be ideal to send this information individually. Any help would be appreciated but it'll need to be fairly efficient both in speed and data size. Thanks in advance!
Answer by harleywinks · May 21, 2015 at 06:17 PM
Protobuf is a good way to send serialized objects over the wire.
Nice properties include fast serialization/deserialization, support on many platforms, good support for backwards/forwards compatibility
Here's a good quick start tutorial for protobuf in unity:
http://purdyjotut.blogspot.com/2013/10/using-protobuf-in-unity3d.html
This worked perfectly, thanks. Also didn't know that you can send byte arrays with RPC. Interesting that it isn't documented.
Glad that helped. One additional tip since it took me a bit to figure it out:
In Unity/C# impl of protobuf it's more straightforward to define your types using Attributes as opposed to having a protobuf message file and compiling from that.
The problem is that you can't add Attributes to Unity struct types that you problably want to use, like Vector3.
The way to get around this is to add the unity types manually to your build script.
I'm building my protobuf serializer dll from a Unity Editor script (as opposed to my types dll, which I build from $$anonymous$$onoDevelop).
The script looks like this:
using UnityEngine;
using ProtoBuf;
using ProtoBuf.$$anonymous$$eta;
using UnityEditor;
public class BuildDLL
{
[$$anonymous$$enuItem("Tools/Beat That/Serialization/Build ProtoBuff dll")]
public static void Build()
{
var model = Type$$anonymous$$odel.Create();
// some unity types
model.Add(typeof($$anonymous$$eyframe), false).Add("time", "value", "inTangent", "outTangent");
model.Add(typeof(Vector3), false).Add("x", "y", "z");
// my custom types here
model.AllowParseableTypes = true;
model.AutoAdd$$anonymous$$issingTypes = true;
model.Compile("ProtoSerializer", "ProtoSerializer.dll");
}
}
Oh, does this mean I can use this technique to serialize unity types like NetworkPlayer, because that'd be really useful. I've tried some techniques but I'm not able to reproduce the same object on the other end. I'll have to try this. Also, if it required to compile it into a DLL? I've been using it so far without compiling to a DLL.
The NetworkPlayer is a struct with just one single integer field. However this field is internal:
public struct NetworkPlayer
{
internal int index;
//...
}
ToString returns this index as string but there's no way (beside using reflection) to "set" this internal value. So if you want to serialize the value you have to use reflection.
I'm not sure if this value does work on all clients or if they have some kind of local representation. This needs some further testing ^^.
If you want to serializa a Networ$$anonymous$$ViewID "manually", it also is just a struct however with 3 integer fields (called a, b and c)
public struct NetworkViewID
{
private int a;
private int b;
private int c;
// ...
}