Serializing a Class

Hey, I know I am asking a lot of questions and I am sorry about that (I hope it's not causing too much trouble). I have been trying to send a class via RPC. I know of this article:
http://forum.exitgames.com/viewtopic.php?f=17&t=880
but I would still be VERY thankful for an example of this.

Take for example the following (simplified) class...how would I convert it so that it could be sent over the Network?

[code2=csharp][System.Serializable]
public class Player
{
public string Name;
public PhotonPlayer PLid;
transform PLview;
int health;
}[/code2]

I think that in order for me to compltly get this, I would need an example in code. Thank you in advance (if you could take the time to set up an example)!

Comments

  • Tobias
    Tobias admin
    edited October 2017
    It's totally fine to ask questions. We learn from those what we have to explain better while we answer.

    The Serializable attribute does not affect Photon's serialization. It's simply ignored from our side.
    You will have to write 2 methods to write and read the essential values of your class and then have to register those in Photon.

    I hope the description at the bottom of this page helps you:
    http://doc.exitgames.com/en/realtim ... -in-photon

    Keep in mind: If you send nothing but a few bytes, you might want to NOT use a custom type. Once you serialized the data to a byte[], you have something that you can send anyways. Lets say you use it for an RPC, then you can either call the RPC as:
    RPC("something", ... (YourClass)variable)
    or with the byte[] as:
    RPC("something", ... (byte[])variable)

    The difference is then how your "something" method is handling the parameter: If it knows the byte[] resembles YourClass, it can do the conversion.
  • Wow...that looks complicated ^.^ but thanks for the reference sheet, I will give it a shot! Maybe a Vector2 was not the best thing to use as an example though, as I have only used a Vector2 once in my life :D
  • :lol:
    PUN already covers Vector3. You can find that in CustomTypes.cs after you imported PUN.
  • Yeah haha, I have already used Vector3 in many RPC's (pretty hard not to). I gave making my own serializable a shot but I am not sure if this would work..in addition, I am getting a compile error because "Protocol" does not exist in the current context. Basically, I tried to send the class (MyPlayer) over the Network to be deserialized.

    [code2=csharp]private static byte[] SerializePlayer(object customobject)
    {
    Player pl = (Player)customobject;
    byte[] bytes = new byte[2 * 4];
    pl = NetworkManager.Instance.MyPlayer;
    Protocol.Deserialize(out pl);
    return pl;
    }

    private static object DeserializeVector2(byte[] bytes)
    {
    Player pl = new Player();
    pl = NetworkManager.Instance.MyPlayer;
    Protocol.Deserialize(out pl);
    return pl;
    }[/code2]

    Sorry if I did something idiotic, not very familiar with this type of function...
  • Again: Please ask yourself why you would need this.
    The PhotonPlayers have a name, which you can use. All objects with PhotonViews know their owner, so do you really need a MyPlayer class which tried to identify the player and the character for that??
  • No, I don't, but I thought this would be more efficient than sending 13 parameters via an RPC. The "Player" class is not just there to identify each player, it also contains all the information for that player (score, deaths, ping, etc.). The reason I want to send the "MyPlayer" class via the network is the following: while players who join the match at the beginning are fully updated on everyone else's character and game info, players who join the game at a later stage have no idea what the score, kills, deaths, etc. of the other players is. By sending a class, I can easily update each player to the current state. From your questions, I am guessing that you don't know how to help me...?
  • The idea of my questions was to find out how to help you. I don't understand where the description lost you and without that understanding i could only re-write parts of the documentation to randomly try to help you.

    Conceptually you are right: It's often easier to pass data as a custom type instead of a bunch of variables.

    I actually can't help you by writing your serialization code for custom classes. That's simply beyond the scope of free support (even if you bought some of our packages or have a subscription).
    Please read the documentation about it once more and maybe start experimenting with a simpler class. Maybe even try to re-implement Vector2 in your own code. Then you have a reference.
  • I cant really do anything if using the "Protocol" class gives me a compile error....
  • Where are you stuck right now? What's your progress on this?
  • I tried using the code above (reply 4), but I get an error message from the console:
    Assets/Scripts/Networking/NetworkManager.cs(650,9): error CS0103: The name `Protocol' does not exist in the current context
    So thats about as far as I got.... :mrgreen:
  • You have to "import" it.
    [code2=csharp]using ExitGames.Client.Photon;[/code2]

    Do this at the top of your file, outside the class.
    Again, the CustomTypes file in the package is a good blueprint. Copy a pair of fitting write and read methods plus the code that actually registers them. When you change the write method, you also have to change the read method accordingly and you have to assign a new code character in the actual registration call.
  • Okay, that has gotten me a lot further haha :D I started trying to create the class, but I ran into some errors when trying so deserialize bools and PhotonPlayers.

    [code2=csharp]private static byte[] SerializePlayer(object customobject)
    {
    Player pl = (Player)customobject;

    byte[] bytes = new byte[2 * 4];
    pl = NetworkManager.Instance.MyPlayer;
    int index = 0;
    Protocol.Deserialize(out pl.OnlinePlayer, bytes, ref index);
    Protocol.Deserialize(out pl.health, bytes, ref index);
    Protocol.Deserialize(out pl.armor, bytes, ref index);
    Protocol.Deserialize(out pl.Score, bytes, ref index);
    Protocol.Deserialize(out pl.Deaths, bytes, ref index);
    Protocol.Deserialize(out pl.Kills, bytes, ref index);
    Protocol.Deserialize(out pl.IsAlive, bytes, ref index);
    return bytes;
    }[/code2]

    I get the following errors:
    Argument `#1' cannot convert `PhotonPlayer' expression to type `short'
    Argument `#1' cannot convert `bool' expression to type `short'

    Do you know how I could convert them to "type short" :?: Thank you in advance for your reply!
  • You do know that short is one of the basic types C# has, right? Do you know how to "cast" types to other types in C#?
    If not: Please consult google. You will need this more or less all the time. Also read up what "short" is and what sort of values it stores.

    This will help more in the long run than giving you the code.
    Hope you don't mind "tutoring" :)
  • Meh not really, thanks for the info.

    Edit: So a short is basically just a number based variable (int, float, double, etc.)? That didn't seem like it would be very hard to explain :D I think I might have an idea of how to get things working now, thank you. Just one quick question: Where do I drop the line that registers the class?
  • You can register the class anywhere more or less. Just make sure you do before you send the stuff.
    My favorite place for this is in an Awake() method. Check out CustomTypes.cs.