尝试保存变量值数据并加载它们时,为什么会出现异常?

时间:2019-07-07 15:00:24

标签: c# unity3d

我创建了一个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.CoreModule,版本= 0.0.0.0,文化=中性,PublicKeyToken =空”中的类型“ UnityEngine.Material”未标记为serializabl

如果需要,完整的例外消息会更长,我会添加它。

1 个答案:

答案 0 :(得分:0)

要使用BinaryFormatter序列化对象,必须将该类标记为可序列化。 为了序列化一个对象,BinaryFormatter也将序列化其成员,并且似乎Material并未标记为可序列化的。您可以使用其他序列化库来保存数据,例如Newtonsoft.Json,它将对象序列化为json。