• 在Unity中使用Protobuf-net
    • 一、Protobuf-net安装
    • 二、示例
    • 三、标识符说明
    • 四、类型说明
    • 五、高级主题
      • 1、继承
      • 2、.proto文件

    在Unity中使用Protobuf-net

    1. Protobuf-net可以通过C#脚本直接序列化与反序列化

    一、Protobuf-net安装

      1、新建VS控制台项目。

      2、选择项目,右键菜单选择“管理NuGet程序包”。

      3、浏览 -> Protobuf-net -> 安装。

        安装后,在项目的同级目录会生成 packages文件夹。

      4、拷贝protobuf-net.dll到Unity中。

        1)、确认Unity中使用的.NET版本。    Editor菜单 -> PlayerSettings -> Player -> Other Settings -> Scripting Runtime Version -> Stable (.NET 3.5 Equivalent)

        2)、根据Unity中使用的.NET版本,拷贝packages/protobuf-net.2.4.0/lib/net35/protobuf-net.dll到Unity中。

    二、示例

    1. /*
    2. * Author : shenjun
    3. */
    4. using System.Collections;
    5. using System.Collections.Generic;
    6. using UnityEngine;
    7. using System.IO;
    8. #if UNITY_EDITOR
    9. using UnityEditor;
    10. #endif
    11. public class LessonProtobuf_CSharpFile : MonoBehaviour {
    12. string filePath { get { return Application.streamingAssetsPath + "/ProtobufData/"; } }
    13. void Start () {
    14. PlayerInfo playerInfo = new PlayerInfo();
    15. playerInfo.id = 1;
    16. playerInfo.name = "shenjun";
    17. playerInfo.listInfo = new List<string>
    18. {
    19. "a", "b", "c"
    20. };
    21. playerInfo.dicInfo = new Dictionary<int, string>();
    22. playerInfo.dicInfo.Add(1, "zhangsan");
    23. playerInfo.dicInfo.Add(2, "lisi");
    24. playerInfo.dicInfo.Add(3, "wangwu");
    25. // 序列化
    26. using (FileStream stream = File.OpenWrite(filePath + "test.dat"))
    27. {
    28. ProtoBuf.Serializer.Serialize(stream, playerInfo);
    29. }
    30. #if UNITY_EDITOR
    31. AssetDatabase.Refresh();
    32. #endif
    33. // 反序列化
    34. using (FileStream stream = File.OpenRead(filePath + "test.dat"))
    35. {
    36. PlayerInfo info = ProtoBuf.Serializer.Deserialize<PlayerInfo>(stream);
    37. Debug.Log(info.name);
    38. }
    39. }
    40. }
    41. [ProtoBuf.ProtoContract] //表示这个类要作为ProtoBuf数据格式来进行传输
    42. public class PlayerInfo
    43. {
    44. [ProtoBuf.ProtoMember(1)] // 必须选择一个整数来标识每个成员
    45. public int id;
    46. [ProtoBuf.ProtoMember(2)]
    47. public string name;
    48. [ProtoBuf.ProtoMember(3)]
    49. public List<string> listInfo;
    50. [ProtoBuf.ProtoMember(4)]
    51. public Dictionary<int, string> dicInfo;
    52. }

      

    三、标识符说明

      • 它们必须是正整数

      • 它们在单个类型中必须是唯一的,但如果启用了继承,则可以在子类型中重复使用相同的数字

      • 标识符不得与任何继承标识符冲突(稍后讨论)

      • 较低的数字占用较少的空间 - 不要启动100,000,000

      • 标识符很重要; 您可以更改成员名称,或在属性和字段之间切换它,但更改标识符会更改数据

      

    四、类型说明

      支持的:

    1. 自定义类:
    2. 被标记为ProtoBuf.ProtoContract
    3. 有一个无参数的构造函数
    4. public
    5. 单维数组:T []
    6. List / IList
    7. Dictionary <TKeyTValue> / IDictionary <TKeyTValue>
    8. 任何实现IEnumerable并具有AddT)方法的类型
    9. 不支持自定义结构。

    五、高级主题

      1、继承

      必须以类似的方式显式声明继承,如果必须用于XmlSerializer和DataContractSerializer。这是通过[ProtoInclude(…)]在已知子类型的每种类型上完成的:

    1. [ProtoContract]
    2. [ProtoInclude(7, typeof(SomeDerivedType))]
    3. class SomeBaseType {...}
    4. [ProtoContract]
    5. class SomeDerivedType {...}

      上述7没有特别的意义;它是一个整数键,就像每个[ProtoMember(…)]一样。它在SomeBaseType方面必须是唯一的(SomeBaseType中没有其他[ProtoInclude(…)][ProtoMember(…)]可以使用7),但不需要全局唯一。

      2、.proto文件

      作为编写类和装饰它们的替代方法,您可以使用.proto模式生成类型protogen; 该protogen工具可从该位置以zip形式提供,或作为“全局工具”(多平台)提供。

    注:.proto使用Proto2语法

      

    ?