Unity сериализовать / де-сериализовать список списка списка

В настоящее время я борюсь с синтаксическим анализом JSON.

Мой файл json был сгенерирован с помощью Construct 2, он содержит файлы json (карты) внутри этого одного json (пакета карт)

Вот пример пакета карт (содержит только одну карту)

{"c2array":true,"size":[1,1,1],"data":[[["{\"c2array\":true,\"size\":[22,9,1],\"data\":[[[\"wall\"],[0],[0],[10],[480],[0],[0],[0],[0]],[[\"wall\"],[0],[470],[860],[10],[0],[0],[0],[0]],[[\"wall\"],[850],[0],[10],[470],[0],[0],[0],[0]],[[\"wall\"],[10],[0],[840],[10],[0],[0],[0],[0]],[[\"wall\"],[160],[190],[110],[140],[0],[0],[0],[0]],[[\"wall\"],[340],[280],[140],[130],[0],[0],[0],[0]],[[\"wall\"],[520],[120],[190],[150],[0],[0],[0],[0]],[[\"plateform\"],[415],[140],[0],[0],[0],[0],[0],[0]],[[\"plateform\"],[195],[160],[0],[0],[0],[1],[5],[5]],[[\"launcher\"],[415],[280],[0],[0],[0],[0],[5],[1]],[[\"ray\"],[15],[90],[0],[0],[0],[0],[5],[1]],[[\"spawn\"],[365],[265],[0],[0],[0],[0],[0],[0]],[[\"mine\"],[465],[280],[0],[0],[0],[0],[5],[0]],[[\"plateformspike\"],[65],[350],[0],[0],[0],[0],[0],[0]],[[\"plateformspike\"],[185],[390],[0],[0],[0],[1],[10],[2]],[[\"spike\"],[520],[185],[0],[0],[270],[0],[0],[0]],[[\"spike\"],[545],[270],[0],[0],[180],[0],[0],[0]],[[\"spike\"],[635],[270],[0],[0],[180],[0],[0],[0]],[[\"spike\"],[710],[175],[0],[0],[90],[0],[0],[0]],[[\"spike\"],[645],[120],[0],[0],[0],[0],[0],[0]],[[\"spike\"],[615],[470],[0],[0],[0],[0],[0],[0]],[[\"flag\"],[225],[190],[0],[0],[0],[0],[0],[0]]]}"]]]}

Теперь, чтобы загрузить этот файл json, я использую следующий сценарий C#:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System;

public class mapLoad : MonoBehaviour {
    public string jsonString;
    public C2Map valeur;


    public bool c2array;
    public List<int> size;
    public List<List<List<string>>> data;

    // Use this for initialization
    void Start () {
        jsonString = File.ReadAllText(Application.dataPath + "/Maps/MapFiles/Test/document.json");
        C2Map valeur = C2Map.CreateFromJSON(jsonString);
        c2array = valeur.c2array;
        size = valeur.size;
        data = valeur.data;
    }

    // Update is called once per frame
    void Update () {

    }
}
[System.Serializable]
public class C2Map
{

    public bool c2array;
    public List<int> size;
    public List<List<List<string>>> data;

    public static C2Map CreateFromJSON(string jsonString)
    {
        return JsonUtility.FromJson<C2Map>(jsonString);

    }
}

Все, что до поля «данные» работает, но как только оно переходит в данные, общедоступная переменная уничтожается, я пробовал разные методы, но он либо возвращает значение null, либо уничтожает переменную, без ошибок, ничего

Вероятно, проблема не связана с вашим json. Часть чтения, вероятно, не работает, так как она возвращает ноль. Куда вы положили json-файл, который пытаетесь прочитать?

Programmer 21.05.2018 20:40

Привет! спасибо за ответ, мой файл находится внутри моей единой папки, файл действительно читается, потому что он заполняет c2array и размер bool / list, но не данные (полное удаление переменной инспектора)

Michael Fontaine 21.05.2018 20:43

у вашего json-файла есть некоторые проблемы с данными, на самом деле это массив массива из одной строки, вы можете сами убедиться, используя онлайн-инструменты, такие как jsoneditoronline.org

Hesamom 21.05.2018 20:50

Это было сделано специально, в основном, я сохраняю карты как одну строку, а затем загружаю строку как новый json из массива; Прямо сейчас в Unity я просто хочу загрузить строку как строку, а не сериализовать ее

Michael Fontaine 21.05.2018 20:53
«общедоступная переменная уничтожается, я пробовал разные методы, но она либо возвращает значение null, либо уничтожает переменную, ошибок нет, ничего». Какие?
Programmer 21.05.2018 20:58

Использовали такие вещи, как string [] [] []; честно говоря, я не очень хорошо помню, что я использовал, чтобы получить пустую строку

Michael Fontaine 21.05.2018 21:04

если ваш файл json содержит только одни данные карты, почему вы сериализуете его таким образом, а не простой строкой?

Hesamom 21.05.2018 21:21

Привет, это "тестовый" json только для загрузки одной карты, все мои "пакеты карт" содержат до 8 карт (вместо одной в данном случае)

Michael Fontaine 21.05.2018 21:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
1 753
2

Ответы 2

выполнение некоторого обратного проектирования выясняет, что JsonUtility of Unity ведет себя странно с вложенными массивами и возвращает значения NULL. но вы можете использовать десериализатор newtonsoft json, он поддерживает широкий спектр версий .Net, включая 3.5 для единства.

просто поместите файл dll в папку Plugins, и он больше не вернет null:

public static C2Map CreateFromJSON(string jsonString)
    {
        return JsonConvert.DeserializeObject<C2Map>(jsonString);
    }

https://www.newtonsoft.com/json

У вас есть список переменных списка List:

public List<List<List<string>>> data;

API JsonUtility не поддерживает это. JsonUtility поддерживает только простые типы. Если вы попытаетесь сериализовать класс, содержащий эту переменную выше, вы получите [] и, вероятно, нулевое значение, когда попытаетесь десериализовать его.

У вас есть два варианта:

1. Напишите обертку для List<List<List<string>>>

[System.Serializable]
public class ListWrapper
{
    public List<ThirdList> secondList;
}

[System.Serializable]
public class ThirdList
{
    public List<string> thirdList;
}

тогда

объявите его как public List<ListWrapper> data; в своем классе C2Map.

2. Используйте Newtonsoft.Json разветвленную версию для Unity. Вы можете получить этот здесь. Стандартный Newtonsoft.Json не работал бы в Unity.

Другие вопросы по теме