在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语法

  

?