Зачем получать исключения при попытке сохранить данные значений переменных и загрузить их? - PullRequest
0 голосов
/ 07 июля 2019

Я создал класс SaveData:

using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEditor.TreeViewExamples;

public class SaveData
{
    public static void Save(MyTreeElement treeElement)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        string path = Application.persistentDataPath + "/Data.bin";
        FileStream stream = new FileStream(path, FileMode.Create);

        formatter.Serialize(stream, treeElement);
        stream.Close();
    }

    public static MyTreeElement myelement()
    {
        string path = Application.persistentDataPath + "/Data.bin";
        if(File.Exists(path))
        {
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream stream = new FileStream(path, FileMode.Open);

            MyTreeElement data = formatter.Deserialize(stream) as MyTreeElement;
            stream.Close();

            return data;
        }
        else
        {
            Debug.Log("Save file not found in " + path);
            return null;
        }
    }
}

Это класс MyTreeElement с переменными, которые я хочу сохранить / загрузить:

using System;
using UnityEngine;
using Random = UnityEngine.Random;

namespace UnityEditor.TreeViewExamples
{
    [Serializable]
    public class MyTreeElement : TreeElement
    {
        public float floatValue1, floatValue2, floatValue3;
        public Material material;
        public string text = "";
        public bool enabled;

        public MyTreeElement (string name, int depth, int id) : base (name, depth, id)
        {
            floatValue1 = Random.value;
            floatValue2 = Random.value;
            floatValue3 = Random.value;
            enabled = false;
        }
    }
}

И использовать его в другом скрипте внутри OnGUI:

OnGUI()
{

  if(GUI.Button(new Rect(10,500,100,20), "Save"))
            {
                for (int i = 0; i < MyTreeElementGenerator.treeElements.Count; i++)
                {
                    SaveData.Save(MyTreeElementGenerator.treeElements[i]);
                }
            }

            if (GUI.Button(new Rect(10, 600, 100, 20), "Load"))
            {
                SaveData.myelement();
            }
}

А это класс MyTreeElementGenerator:

using System.Collections.Generic;
using Random = UnityEngine.Random;

namespace UnityEditor.TreeViewExamples
{
    static class MyTreeElementGenerator
    {
        static int IDCounter;
        static int minNumChildren = 0;
        static int maxNumChildren = 2;
        static float probabilityOfBeingLeaf = 0.5f;

        public static List<MyTreeElement> treeElements = new List<MyTreeElement>();


        public static List<MyTreeElement> GenerateRandomTree(int numTotalElements)
        {
            int numRootChildren = numTotalElements;// / 4;
            IDCounter = 0;
            treeElements = new List<MyTreeElement>(numTotalElements);

            var root = new MyTreeElement("Root", -1, IDCounter);
            treeElements.Add(root);
            for (int i = 0; i < numRootChildren; ++i)
            {
                int allowedDepth = 6;
                AddChildrenRecursive(root, /*Random.Range(minNumChildren, maxNumChildren)*/1, true, numTotalElements, ref allowedDepth, treeElements);
            }

            return treeElements;
        }
        public static void AddChildrenRecursive(TreeElement element, int numChildren, bool force, int numTotalElements, ref int allowedDepth, List<MyTreeElement> treeElements)
        {
            if (element.depth >= allowedDepth)
            {
                allowedDepth = 0;
                return;
            }

            for (int i = 0; i < numChildren; ++i)
            {
                if (IDCounter > numTotalElements)
                    return;

                var child = new MyTreeElement("Test " + IDCounter, element.depth + 1, ++IDCounter);
                treeElements.Add(child);

                if (!force && Random.value < probabilityOfBeingLeaf)
                    continue;

                AddChildrenRecursive(child, /*Random.Range(minNumChildren, maxNumChildren)*/0, false, numTotalElements, ref allowedDepth, treeElements);
            }
        }
    }
}

Но при нажатии на кнопку Сохранить я получаю в редакторе следующее исключение:

SerializationException: Тип 'UnityEngine.Material' в сборке 'UnityEngine.CoreModule, версия = 0.0.0.0, Culture = нейтральный, PublicKeyToken = null' не помечен как serializabl

Полное сообщение об исключениях:намного дольше, если потребуется, я добавлю его.

1 Ответ

0 голосов
/ 07 июля 2019

Чтобы сериализовать объекты с помощью BinaryFormatter, класс должен быть помечен как сериализуемый.Чтобы сериализовать объект, BinaryFormatter также будет сериализовать его члены, и кажется, что Материал не помечен как сериализуемый.Вы можете использовать другие библиотеки сериализации для сохранения данных, например, Newtonsoft.Json, который сериализует ваш объект как json.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...