Форум программистов, компьютерный форум, киберфорум
Unity, Unity3D
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/34: Рейтинг темы: голосов - 34, средняя оценка - 4.82
9 / 9 / 0
Регистрация: 16.03.2014
Сообщений: 136
1

Как сериализовать Список списков списков?

22.01.2019, 22:06. Показов 6155. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
У меня есть игра, в ней пользователь может сохранять уровни и играть их в будующем. На каждом уровне есть одна или несколько линий состоящийх из точек.Количество точек зависит от того какой длинны линию нарисовал игрок. Линии создаються с помощью компонента LineRenderer. Сначала для теста я решил сохраниять точки при помощи списка списков. Также пришлось разбивать точку Vector3 на три переменные float так как сериализатор не сохраняет Vector3 так как это класс unity а не C#. Однако потом пришлось расширить до списка списков списков так как нужно сохранять точки каждой линии для каждого уровня. Но теперь сериализатор отказалься сохранять списки списков списков. Видимо максимум он может только список списков сохранять. И как же чёрт побери мне сохранить этот список данных.
В общем сейчас сериализованный клас выглядит вот так.

C#
1
2
3
4
5
6
7
8
9
10
11
[Serializable]
public class SavedData
{
     byte Progress;                                                  // The number of the last passed level is stored here.
     public List<int> NumberMapsScreenshots;                         // Numbers of screenshots of maps are stored here.
 
     // We split the list of ListSelectionPoints into 3 parts     1) Step[Level], 2) Step[NomberLine] 3) Step[NomberDotInLine]
     public List<List<List<float>>> XLSelPoints = new List<List<List<float>>>();     // The list of points lists "X" of the parsed list of lists "ListSelectionPoints"
     public List<List<List<float>>> YLselPoints = new List<List<List<float>>>();     // The list of points lists "Y" of the parsed list of lists "ListSelectionPoints"
     public List<List<List<float>>> ZLselPoints = new List<List<List<float>>>();     // The list of points lists "Z" of the parsed list of lists "ListSelectionPoints"
}
В коментарии кода указанно для чего нужна каждая ступень спсиска
Помогите плиз с этой проблемой если кто знает решение..
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.01.2019, 22:06
Ответы с готовыми решениями:

Как из двух списков сделать один список кортежей/списков
Доброго времени суток! Буду очень благодарен, если поможете из двух списков, к примеру a и b,...

Объединение 2 и более списков в список списков по индексу без использования циклов
Уважаемые товарищи, подскажите есть ли способ объединения 2 и более списков в список списков по...

Копирование данных двумерного массива состоящего из списков в список списков.
Для нахождения МСТ (минимального остового дерева) написал функцию, которая принимает масив - гарф....

Написать программу, которая получает список из списков из списков чисел
Всем привет, мне нужно написать программу, которая получает список из списков из списков чисел,...

14
Эксперт .NET
6507 / 4084 / 1605
Регистрация: 09.05.2015
Сообщений: 9,548
22.01.2019, 22:16 2
Как сериализуете? Используете Newtonsoft.Json для сериализации? Что-то другое?
1
753 / 600 / 204
Регистрация: 06.08.2015
Сообщений: 2,432
23.01.2019, 01:02 3
Встроенный JsonUtility должен принимать
1
Эксперт .NET
6507 / 4084 / 1605
Регистрация: 09.05.2015
Сообщений: 9,548
23.01.2019, 01:10 4
Цитата Сообщение от Cr0c Посмотреть сообщение
Встроенный JsonUtility
Мусор, даже классы со свойствами не сериализует. Не говоря уже о классах с полями в виде массивов или списков.
1
753 / 600 / 204
Регистрация: 06.08.2015
Сообщений: 2,432
23.01.2019, 09:35 5
Someone007, может АВТОсвойства, а не свойства? У меня нормально массив Vector3 сериализовался. И массив классов, где классы с массивами Vector3 - тоже сериализовался.
1
9 / 9 / 0
Регистрация: 16.03.2014
Сообщений: 136
23.01.2019, 10:49  [ТС] 6
Я использую баннерную серриализацию. Так как давно еще знающие люди ее советовали. Да и читал я про нее много хорошего.

Добавлено через 17 минут
Тфу ты, бинарную. Сорри за кламбур пишу с телефона.
0
Эксперт .NETАвтор FAQ
10418 / 5148 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
23.01.2019, 11:03 7
SERG__ZV,
Во-первых, что значит "сериализатор отказалься сохранять"? Выдается ошибка? Приведите полный текст ошибки. А лучше, выложите тестовый проект, который можно запустить и увидеть ошибку.
У меня например ваш класс сериализуется нормально.

Во-вторых, почему у вас класс для сериализации такой уродливый?
Вы разве сами не чувствуете, что List<List<List<float>>> - это мягко говоря не очень?
Почему не сделать нормальные классы, с нормальными именами, по правилам ООП?
Тем более у вас же в коментах уже написано как это должно примерно выглядеть.
На верхнем уровне должен быть класс Levels, который будет содержать список уровней:
C#
1
2
3
4
5
[Serializable]
class Levels
{
     public List<Level> Items;
}
Далее, класс Level должен содержать список линий Line. А класс Line должен содержать список точек Point.
А класс Point должен реализовать кастомную сериализацию, которая сможет сериализовать Vector3.
И тогда ваша модель станет более красивой, расширяемой, и глядишь и ошибка сериализации уйдет.
1
9 / 9 / 0
Регистрация: 16.03.2014
Сообщений: 136
23.01.2019, 14:57  [ТС] 8
Хорошо домой приду выложу ошибку. Тот пример что вы привели это сериализация списка.
Список float у меня тоже сериализуеться. Список списков тоже сериализуеться. А когда я вложил это в еще одну конструкцию. То есть сделал список списков списков как на примере выше то стала появляться ошибка.
List exception не возможно преобразовать list ..... В list...
Домой приду выложу ошибку. Могу даже пример собрать в котором эта ошибка будет.

Добавлено через 8 минут
Во-вторых, почему у вас класс для сериализации такой уродливый?
Вы разве сами не чувствуете, что List<List<List<float>>> - это мягко говоря не очень?

Чувствую. Но я не знаю как реализовать более удобным способом.. Как это должно выглядеть я не знаю потому как сериализатор не хочет сохранять никакой класс созданный мной в ручную а только те что есть изначально в c#. Гуглил на тему как сериализовать класс GameObject и vector3 там писали что этот классы юнити и их целиком не сериализовать.

Добавлено через 4 минуты
Ах да игра собирается и запускаеться под андроид возможно это тоже как то влияет..

Добавлено через 1 час 20 минут
Я тогда лучше сразу сделаю пример того как вы сказали и если что-то не получится выложу сюда. И правда если есть лучший путь зачем исправлять баги на худшем решении задачи...
0
753 / 600 / 204
Регистрация: 06.08.2015
Сообщений: 2,432
23.01.2019, 17:09 9
SERG__ZV, лучше опишите смысл тройных вложенных списков
1
9 / 9 / 0
Регистрация: 16.03.2014
Сообщений: 136
23.01.2019, 21:45  [ТС] 10
Я использовал тройной список для того чтобы сохранить все точки всех линий на всех уровнях созданных игроком.
Первая ступень списка означает уровень, вторая ступень означает линию, третяя ступень означает точку.
Но я так делал потому что думал что бинарная сериализация может использовать лишь стандартные классы библотеки C# но не описанные мной лично или в unity. Сейчас попробую реализовать пример который мне предложили выше.

Добавлено через 41 минуту
Проблема со списками решена, оказываеться ошибка была потому что я переписал списки списков в списки списков списков. Но при этом пыталься загрузить старое сохранение где были сохранены списки списков. Естественно нужно было всего лишь создать новое сохранение с обновлённым классом.
Однако раз тут предложили лучшую и более удобную систему я всё таки доделаю её и выложу сюда пример так как скорее всего он работать не будет( Поэтому вопрос отстаёться открытым.

Добавлено через 25 минут
А класс Point должен реализовать кастомную сериализацию, которая сможет сериализовать Vector3.
Вот эту часть я не понял. Как сделать чтобы этот класс сериализовывалься?
Что такое кастомная сериализация?
Разве не нужно сериализовывать верхний класс целиком? А именно класс Levels так было бы удобнее если это возможно...

Вот что у меня получилось. Так как с классами я не совсем понял осталься пустой код.
0
9 / 9 / 0
Регистрация: 16.03.2014
Сообщений: 136
23.01.2019, 21:48  [ТС] 11
https://www.cyberforum.ru/atta... 1548269255
Вложения
Тип файла: 7z TestBS.7z (9.60 Мб, 8 просмотров)
0
Эксперт .NETАвтор FAQ
10418 / 5148 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
23.01.2019, 22:15 12
Лучший ответ Сообщение было отмечено SERG__ZV как решение

Решение

Цитата Сообщение от SERG__ZV Посмотреть сообщение
Вот эту часть я не понял. Как сделать чтобы этот класс сериализовывалься?
Что такое кастомная сериализация?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
[Serializable]
class SavedData
{
    byte Progress;                                                  // The number of the last passed level is stored here.
    public List<int> NumberMapsScreenshots;                         // Numbers of screenshots of maps are stored here.
    public Levels Levels = new Levels();
}
 
[Serializable]
class SerializableVector3 : ISerializable
{
    Vector3 vector;
 
    public SerializableVector3(Vector3 v)
    {
        this.vector = v;
    }
 
    public SerializableVector3(SerializationInfo info, StreamingContext context)
    {
        var x = (float)info.GetValue("x", typeof(float));
        var y = (float)info.GetValue("y", typeof(float));
        var z = (float)info.GetValue("z", typeof(float));
        vector = new Vector3(x, y, z);
    }
 
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("x", vector.x);
        info.AddValue("y", vector.y);
        info.AddValue("z", vector.z);
    }
 
    public static implicit operator Vector3(SerializableVector3 p)
    {
        return p.vector;
    }
 
    public static implicit operator SerializableVector3(Vector3 v)
    {
        return new SerializableVector3(v);
    }
}
 
[Serializable]
class Line
{
    public List<SerializableVector3> Points = new List<SerializableVector3>();
}
 
[Serializable]
class Level
{
    public List<Line> Lines = new List<Line>();
}
 
[Serializable]
class Levels
{
    public List<Level> Items = new List<Level>();
}
Тестовый скрипт:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
 
public class Test : MonoBehaviour
{
    void Start ()
    {
        var point = new Vector3(1, 2, 3);
        var line = new Line();
        line.Points.Add(point);
        var level = new Level();
        level.Lines.Add(line);
        var data = new SavedData();
        data.Levels.Items.Add(level);
 
        //serialize
        using (var fs = File.Create(Application.persistentDataPath + "/GameData.bs"))
        {
            new BinaryFormatter().Serialize(fs, data);
        }
 
        //deserialize
        using (var fs = File.OpenRead(Application.persistentDataPath + "/GameData.bs"))
        {
            data = (SavedData)new BinaryFormatter().Deserialize(fs);
        }
 
        //check Vector3
        Vector3 v = data.Levels.Items[0].Lines[0].Points[0];
        Debug.Log("Point: " + v);
    }
}
1
9 / 9 / 0
Регистрация: 16.03.2014
Сообщений: 136
23.01.2019, 22:40  [ТС] 13
Спасибо завтра прийду с работы буду разбирать.
0
9 / 9 / 0
Регистрация: 16.03.2014
Сообщений: 136
25.01.2019, 22:31  [ТС] 14
Почти разобрал первый скрипт) Ну и сложнющий он для меня. Пришлось подучиться). У меня вопрос к вашему коду.
Почему метод с названием Получить данные объекта по сути добавляет данные в него, ведь судя по названию он должен оттуда их получать...

C#
1
2
3
4
5
6
7
    // The method that sets the data in the repository, (This method must exist as it is declared in the interface of the ISerializable, from which the class SerializableVector3 is inherited)
    public void GetObjectData(SerializationInfo info, StreamingContext context)     
    {
        info.AddValue("x", vector.x);                               // Добавляем значение х из поля вектор в хранилище            
        info.AddValue("y", vector.y);                               // Добавляем значение х из поля вектор в хранилище  
        info.AddValue("z", vector.z);                               // Добавляем значение х из поля вектор в хранилище  
    }
Добавлено через 16 минут
Насчёт интерфейса неправильный коментарий выше, оказываеться их не наследуют а реализуют)

Добавлено через 30 секунд
Но вопрос о методе в силе)
0
9 / 9 / 0
Регистрация: 16.03.2014
Сообщений: 136
28.01.2019, 21:55  [ТС] 15
Наконецто всё разобрал. Код работает, сериализация десериализация прописанна у вас гораздо короче чем я делал с помошью streamwriter и streamrider. И создание своих классов тоже круто помогло. Код выглядит гораздо красивее и короче. Пришлось подучиться и разобрать то что было неясно но это даэе хорошо теперь я чуть больше понимаю. Ещё раз спасибо за ваши труды.
1
28.01.2019, 21:55
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.01.2019, 21:55
Помогаю со студенческими работами здесь

Список списков после добавления списков остается пустым
Здравствуйте имеется код: def lookup_main_url(driver): subjects = .... for county...

Список списков списков чисел
Всем привет) Задание: l1 - список списков списков чисел. Необходимо получить список чисел l2,...

Как сложить сумму из чисел сотен списков и узнать количество списков?
Доброго времени суток! Не могу понять как сложить сумму из несколько тысяч списков. Подскажите...

Как сравнить значения списков, внутри других списков?
Имею переменную, которая содержит в списке другой список двух карт: table = , ] Хочу вывести...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru