- Home /
Serialize an array of custom objects
I'm currently using Photon Network and I need to send an RPC to the connected players with the teams. I created a Team object that defines a team, and all the teams are stored in an array.
Since arrays and custom objects are not serialized automatically, how can I do it? I have no experience in this field and I have googled a lot with no sucess. All I need is some directions on how to do it.
P.S- Actually I read something about converting it all to a byte array an then send it. Any guidelines on how to do this?
Here is my Team object:
public class Team {
private int teamID;
private string[] players;
private int playersJoined;
}
EDIT - I folowed @ArkaneX sugestion and got this:
private static byte[] serializeTeam (object o)
{
Team team = (Team)o;
byte[] bytes = new byte[3 * 4];
int index = 0;
ExitGames.Client.Photon.Protocol.Serialize(team.getID(), bytes, ref index);
ExitGames.Client.Photon.Protocol.Serialize(team.getPlayerList(), bytes, ref index);
ExitGames.Client.Photon.Protocol.Serialize(team.getSize(), bytes, ref index);
return bytes;
}
private static object deserializeTeam(byte[] bytes)
{
Team team = new Team();
int index = 0;
ExitGames.Client.Photon.Protocol.Deserialize(out team.teamID, bytes, ref index);
ExitGames.Client.Photon.Protocol.Deserialize(out team.players, bytes, ref index);
ExitGames.Client.Photon.Protocol.Deserialize(out team.playersJoined, bytes, ref index);
return team;
}
I tought that arrays of strings would spare me these troubles but I'm getting this:
Argument `#1' cannot convert `string[]' expression to type `short'
Also I'm not sure about bytes array length.
EDIT 2 - I have this another idea, but the same error
private static byte[] serializeTeam (object o)
{
Team team = (Team)o;
byte[] bytes = new byte[3 * 4];
int index = 0;
ExitGames.Client.Photon.Protocol.Serialize(team.teamID, bytes, ref index);
ExitGames.Client.Photon.Protocol.Serialize(team.players.Length, bytes, ref index);
foreach(string s in team.players)
{
ExitGames.Client.Photon.Protocol.Serialize(s, bytes, ref index);
}
ExitGames.Client.Photon.Protocol.Serialize(team.playersJoined, bytes, ref index);
return bytes;
}
private static object deserializeTeam(byte[] bytes)
{
Team team = new Team();
int index = 0;
ExitGames.Client.Photon.Protocol.Deserialize(out team.teamID, bytes, ref index);
int lenght = 0;
ExitGames.Client.Photon.Protocol.Deserialize(out lenght, bytes, ref index);
team.players = new string[lenght];
for (int i = 0; i < team.playersJoined; ++i)
{
ExitGames.Client.Photon.Protocol.Deserialize(out team.players[i], bytes, ref index);
}
ExitGames.Client.Photon.Protocol.Deserialize(out team.playersJoined, bytes, ref index);
return team;
}
Answer by ArkaneX · Jan 05, 2015 at 04:31 PM
Take a look at this page: http://doc.exitgames.com/en/realtime/current/reference/serialization-in-photon
It is inside 'Photon realtime' section, but contains a sample related to PUN.
EDIT:
Serialize method works by converting passed values to bytes, and filling the bytes array with result of the conversion. There's no overload of the three parameters method accepting string or array of strings, but there's a Serialize method accepting an object and returning array of bytes, so you can use it. Working code for your case should look like this:
private static byte[] serializeTeam(object o)
{
Team team = (Team)o;
var playerBytes = ExitGames.Client.Photon.Protocol.Serialize(team.players);
byte[] bytes = new byte[playerBytes.Length + 12];
int index = 0;
ExitGames.Client.Photon.Protocol.Serialize(team.teamID, bytes, ref index);
ExitGames.Client.Photon.Protocol.Serialize(playerBytes.Length, bytes, ref index);
System.Array.Copy(playerBytes, 0, bytes, index, playerBytes.Length);
index += playerBytes.Length;
ExitGames.Client.Photon.Protocol.Serialize(team.playersJoined, bytes, ref index);
return bytes;
}
private static object deserializeTeam(byte[] bytes)
{
Team team = new Team();
int index = 0;
int playerBytesLength;
ExitGames.Client.Photon.Protocol.Deserialize(out team.teamID, bytes, ref index);
ExitGames.Client.Photon.Protocol.Deserialize(out playerBytesLength, bytes, ref index);
var playerBytes = new byte[playerBytesLength];
System.Array.Copy(bytes, index, playerBytes, 0, playerBytesLength);
team.players = (string[])ExitGames.Client.Photon.Protocol.Deserialize(playerBytes);
index += playerBytes.Length;
ExitGames.Client.Photon.Protocol.Deserialize(out team.playersJoined, bytes, ref index);
return team;
}
Total length of result bytes array is equal to the length of serialized array of players + 12 (three int). Please note that although playerBytes.Length is not a part of your team data, it must be stored, so that during deserialization we know how many bytes we need to copy in order to deserialize string array.
I quickly tested above code by creating Team instance, passing it to first method and then passing resulting array to the second method. I think it should work during Photon (de)serialization as well.
Hi Bruno. I see that you accepted the answer, but edits of your question indicates you had some problems. Were you able to solve them?
Nope buddy I'm having some troubles. I should have "unaccepted" it but I completly forgot. The problem is I can't serialize the array of strings directly. I tried another way of doing it but now I can't serialize the strings. In the documentation it says that is possible so I must be doing something wrong.
Goddamit I'm pretty sure I tried that before, maybe I forgot to save the script in $$anonymous$$onoDevelop... This happens so many times!
I'am really glad for all your help! I have been stuck in this for so much time and I would be even worse if it weren't for your effort. I just have 1 more thing to ask if you dont $$anonymous$$d:
I have seen some people using external libraries for Serialize/Deserialize objects. Due to the complexity of using them, Im not thinking of adopting them right now, but it got me thinking - Is it worth?
It depends. You can serialize objects to many formats, for example X$$anonymous$$L, JSON, array of bytes, like in your Photon code, or some proprietary formats. Any of these has their own pros and cons, e.g. X$$anonymous$$L or JSON data might be easily edited, while binary data takes less space.
In your case, serializing to byte array is required, but in fact, you don't need to use serialization mechanism provided by ExitGames. You can for example serialize your Team instance using BinaryFormatter class, and then your serialization/deserialization code would be a few lines only, no matter how many fields your class would contain. But size of a byte array produced by BinaryFormatter would be much bigger than the one produced by code from my answer.
In your case, size of data sent over the network might be important, so you probably want to stick with custom code. But in other situation, you might want a general solution, and then BinaryFormatter might be better. At the end it's up to you :)
Answer by Kamuiyshirou · Jan 05, 2015 at 04:30 PM
View this document friend : http://blogs.unity3d.com/pt/2014/06/24/serialization-in-unity/
I think OP is asking about serialization specific to Photon Unity Networking.
I have already tried everything in that page, I just can't get it to work :x
I will try @ArkaneX doc when I get home and lets see if can do it. Thanks (:
Answer by Voxel-Busters · Aug 07, 2015 at 12:04 PM
You can also try this. Serialize custom object and send that serialization data (string/byte[] format) to other Photon clients. On receiving this serialization data, other clients can deserialize it and retrieve back original object. However, there is some limit on message size while sending over photon network. So its better to share lightweight data only.
For serializing you can choose c# Binary formatter or else third party plugin from asset store. I would also recommend you to check out our plugin Runtime Serialization for Unity which can serialize c# objects as well as Unity objects like GameObjects, Transform, MonoBehaviours etc. For complete list of supported types, please check this link.
Your answer
Follow this Question
Related Questions
Serialize unity classes 0 Answers
JsonUtility not working with Arrays 2 Answers
Very Strange RPC error 1 Answer