使用protobuf-net生成的预编译dll序列化unity3d类型时出现“不期望类型”错误

时间:2014-10-08 10:09:08

标签: unity3d protobuf-net

我使用protobuf-net为我的unity3d项目创建静态序列化dll。像这样:

    RuntimeTypeModel model = RuntimeTypeModel.Create();

    model.Add(typeof(UnityEngine.Vector3), true).Add("x", "y", "z");
    model.Add(typeof(UnityEngine.Quaternion), true).Add("x", "y", "z", "w");
    model.Add(typeof(MyClass), true);

    model.AllowParseableTypes = true;
    model.AutoAddMissingTypes = false;
    model.AutoCompile = false;
    model.UseImplicitZeroDefaults = false;
    model.Compile("GameDataSerializer", "GameDataSerializer.dll");

对于MyClass,我使用[ProtoContract]标签,它可以正常工作。然而,它不适用于像Vector3这样的统一类型。

        System.Type type = System.Type.GetType("GameDataSerializer, GameDataSerializer");
        TypeModel serializer = (RuntimeTypeModel)type.GetMethod("Create", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy).Invoke(null, null);
        Vector3 v = new Vector3(1f, 2f, 3f);
        using (FileStream f = new FileStream("testser.bin", FileMode.OpenOrCreate))
        {
            serializer.Serialize(f, v);
        }

当我尝试保存或加载Vector3对象时出现以下错误:

InvalidOperationException: Type is not expected, and no contract can be inferred: UnityEngine.Vector3

如何正确序列化预编译dll的unity3d类型?

1 个答案:

答案 0 :(得分:1)

我发现了问题。

简单回答:

使用"新的GameDataSerializer()"构造运行时序列化器对象而不是" type.GetMethod(" Create",...)"。这可以按预期工作。

详细说明:

首先,我尝试构建运行时序列化程序,就像最终解决方案一样

GameDataSerializer serializer = new GameDataSerializer()

但是,unity3d脚本无法编译错误"无法加载文件或程序集Assembly-CSharp ..."。所以我将代码更改为

System.Type type = System.Type.GetType("GameDataSerializer, GameDataSerializer");
TypeModel serializer = (RuntimeTypeModel)type.GetMethod("Create", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy).Invoke(null, null);

并且一切正常,直到我在原始问题中遇到问题。

真正的问题是预编译的串行器dll被认为是unity3d中的一个插件。 unity3d在其他用户脚本(Assembly-csharp)之前编译插件。预编译的序列化程序dll引用了Assembly-csharp,因为" MyClass",并且在插件编译阶段无法解析。

因此决议是重构" MyClass"和其他可序列化的数据结构到一个单独的dll,然后编译一个序列化程序DLL而不引用Assembly-csharp。这两个dll都可以使用单独的visual studio项目(.net 2.0)生成。

如果您的数据结构与其他代码有很强的耦合并且处理单独的项目很烦人,那么这可能会很不方便。所以我尝试了其他一些方法:

  • 将数据结构源文件放入plugins文件夹,生成带编辑器脚本的序列化器dll
  • 使用数据结构dll,但使用编辑器脚本
  • 生成序列化程序DLL
  • 将序列化程序DLL反编译为源代码

但它们都不起作用。似乎使用编辑器脚本生成的序列化程序DLL总是引用Assembly-csharp。并且没有反编译器足以生成编译源代码。所以目前我已经与单独的vs项目解决方案达成了协议。