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*, bytes, ref index);*
  •   }*
    
  •   ExitGames.Client.Photon.Protocol.Deserialize(out team.playersJoined, bytes, ref index);*
    
  •   return team;*
    
  • }*

Take a look at this page: Fusion Introduction | Photon Engine

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.

View this document friend : Serialization in Unity | Unity Blog

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 2.