简体   繁体   中英

Unity3d: How to store Dictionary as object in JSON?

I'm new to the Unity3d and C#. I want to store some data in JSON files, so they are easy to edit in text editor .

So far I used JsonUtility because its build in Unity, and it worked great. Possibility to use it as easy as:

string json = JsonUtility.ToJson(foo);
Foo foo = JsonUtility.FromJson<Foo>(json);

was great for me.

But now, I added some Dictionaries. They are later converted for more afficient data structures, but I want to serialize them to JSON as named objects.

Here is sample of my code. The Objects structure in my case is set and known. Single Dictionary keeps one type of objects, and Dictionary is set deeper in hierarchy of serializable objects.

[System.Serializable]
public struct Bar{
    public int x;
    public int y;
}

[System.Serializable]
public class Foo{
    public int otherData = 43;
    public Dictionary<string,Bar> bar = new Dictionary<string,Bar>(){
        {"spaceship", new Bar{x = 7, y = 11}},
        {"pirates", new Bar{x = 5, y = -3}},
    };
}

What I want to achieve:

{
   "otherData": 43,
   "bar": {
        "spaceship": {"x": 7, "y": 11},
        "pirates": {"x": 5, "y": -3}
   }
}

Is it any way to make that work?

Maybe is a way that I can write my on serialization/deserialization methods for Dictionary?

According this this answer , JsonUtility only supports simple types, and that excludes dictionaries (this is explicitly mentioned in the answer).

Your best bet would be to switch to Json.NET , which is available as a NuGet package , which supports more complex use cases such as this one.

Use the following code:

 static string ConvertFooClassToJson()
    {
        List<string> jsonStrings = new List<string>();
        foreach (FieldInfo field in typeof(Foo).GetFields())
        {
            string fieldName = field.Name;
            Foo fieldsInstant = new Foo();
            var fieldValue = field.GetValue(fieldsInstant);
            if (field.FieldType.IsValueType)
            {
                string valueType = $"{fieldName}:{fieldValue}";
                jsonStrings.Add(valueType);
            }
            else
            {
                dynamic dynamicDic = fieldValue;
                List<string> dicValues = new List<string>();

                foreach (var dicItem in dynamicDic)
                {
                    var itemKey = dicItem.Key;
                    var itemValue = dicItem.Value;

                    List<string> barClassLst = new List<string>();
                    Bar barValue = itemValue;
                    foreach (var barItem in barValue.GetType().GetProperties())
                    {
                        var barPropertyName = barItem.Name;
                        var barPropertyValue = barItem.GetValue(barValue);
                        barClassLst.Add($"{barPropertyName}:{barPropertyValue}");
                    }

                    var barPropertiesString = "{" + string.Join(',', barClassLst.ToArray()) + "}";

                    string dicString = $"{itemKey}:{barPropertiesString}";
                    dicValues.Add(dicString);
                }
                var fooString = "{" + string.Join(',', dicValues.ToArray()) + "}";
                string finalString = $"{fieldName}:{fooString}";
                jsonStrings.Add(finalString);
            }
        }
        string jsonResult = "{" + string.Join(',', jsonStrings.ToArray()) + "}";
        return jsonResult;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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