繁体   English   中英

用protobuf-net反序列化字典

[英]Deserialize Dictionary with protobuf-net

由于BinaryFormatter给我在Ios上序列化字典的麻烦,因此我决定切换到protobuf-net。 并使用它来序列化我的Unity3d游戏中的内容。 下面是一些代码:这是保存所有数据的类:

using System;
using System.Collections.Generic;
using ProtoBuf;
using UnityEngine;
namespace SerializationLib
{
    [ProtoContract]
   public class GameData
    {
        [ProtoMember(1)]
        public int _coinAmount ;
        [ProtoMember(2)]
        public int _upgradeLevel;
        [ProtoMember(3)]
        public Level_Data[] _level_Data;
        [ProtoMember(4)]
        public CharacterUpgradeList _charUpgradeList;
        [ProtoMember(5)]
        public SerialVector2 serialVector;



    }
    [ProtoContract]
    public class CharacterUpgradeList
    {


        private List<UpgradeData>[] upgData;
        [ProtoMember(1,OverwriteList = true)]
        public Dictionary<string, List<UpgradeData>> upgradeList;

        public CharacterUpgradeList()
        {
            upgData = new List<UpgradeData>[4];
            for (int i = 0; i < upgData.Length; i++)
            {
                upgData[i] = new List<UpgradeData> { 
                        new UpgradeData(),
                        new UpgradeData(),
                        new UpgradeData(),
                        new UpgradeData(),
                        new UpgradeData(),
                        new UpgradeData()
                   };
            }

            upgradeList = new Dictionary<string, List<UpgradeData>>
        {
            {"Man",upgData[0]},
            {"Woman",upgData[1]},
            {"Boy",upgData[2]},
            {"Girl",upgData[3]}

        };
        }
    }


    [ProtoContract]
    public class Level_Data
    {
        [ProtoMember(1)]
        public int completion_status;
        [ProtoMember(2)]
        public int star_Rating;
    }
    [ProtoContract]
    public class UpgradeData
    {
        [ProtoMember(1)]
        public bool lockStatus;
        [ProtoMember(2)]
        public bool purchased;

    }
    [ProtoContract]
    public struct SerialVector2
    {
        [ProtoMember(1)]
        public float x;
        [ProtoMember(2)]
        public float y;

        public SerialVector2(Vector2 vect)
        {
            x = vect.x;
            y = vect.y;
        }
        public Vector2 returnVector2()
        {
            return new Vector2(x, y);
        }
    }


}

这是我正在使用的数据序列化器

using System;
using System.Collections.Generic;
using SerializationLib;
using ProtoBuf.Meta;

namespace DataSerializer
{
    class Program
    {
        static void Main(string[] args)
        {
            var Model = TypeModel.Create();
            Model.Add(typeof(GameData), true);
            Model.Add(typeof(CharacterUpgradeList), true);
            Model.Add(typeof(Level_Data), true);
            Model.Add(typeof(UpgradeData), true);
            Model.Add(typeof(SerialVector2), true);

            Model.AllowParseableTypes = true;
            Model.AutoAddMissingTypes = true;

            Model.Compile("DataSerializer", "DataSerializer.dll");
        }
    }
}

这是一个protobuf包装器,可在我的其他c#脚本中统一使用

using UnityEngine;
using System.IO;

public static class ProtoWraper {

    private static DataSerializer m_serialiezer = new DataSerializer();


    public static T LoadObjectFromResources<T>(string resourcePath)
    {
        TextAsset objectAsset = Resources.Load(resourcePath, typeof(TextAsset)) as TextAsset;
        if (objectAsset == null)
        {

            return default(T);
        }
        T deserializedObject = default(T);
        using (MemoryStream m = new MemoryStream(objectAsset.bytes))
        {
            deserializedObject = (T)m_serialiezer.Deserialize(m, null, typeof(T));
        }
        return deserializedObject;
    }
    public static T LoadObjectFromPath<T>(string path)
    {
        if (!File.Exists(path))
        {
            return default(T);
        }
        T deserializedObject = default(T);
        using(FileStream f = new FileStream(path,FileMode.Open))
        {
             deserializedObject = (T)m_serialiezer.Deserialize(f,null,typeof(T));
        }
        return deserializedObject;
    }
    public static void SaveObjectToPath<T>(string objectPath, string filename, T serializedObject)
    {
        if (!Directory.Exists(objectPath))
        {
            Directory.CreateDirectory(objectPath);
        }
        using (FileStream f = new FileStream(objectPath + filename, FileMode.OpenOrCreate))
        {
            m_serialiezer.Serialize(f, serializedObject);
        }
    }
}

现在的问题是当我调用data = ProtoWraper.LoadObjectFromPath<GameData>(filename); 我收到ArgumentException: An element with the same key already exists in the dictionary.

没关系,我是一个完全傻瓜,对Serializationlib:D进行更改后没有重新编译数据串行器。 现在一切都很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM