为什么C#使用[System.Serializable]来保存实例?(Unity3D)

use*_*445 1 c# serialization unity-game-engine

我想制作一个程序,如果从检查器获取TextAsset(它放在'ExampleEditor'中),它会创建一个自定义数据实例以使用混合形状动画.

起初我使用[System.Serializable]创建自定义数据类.

public class Matrix {
    public int row;
    public int col;
    public double[,] mat;
}
Run Code Online (Sandbox Code Playgroud)

我的策略是使用TextAsset,从TextAsset解析字符串,最后将Matrix实例转换为'Example.cs'中的字段变量.我想当它初始化并首先分配时,我能够在Example实例中使用该变量.但是,它没有用,它抛出'NullReferenceException'.

所以我找到了使用'[System.Serializable]'的解决方案.它确实有效.(我知道Unity3D不为它们的序列化方法提供多维数组.)

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

[System.Serializable]
public class Matrix {
    [System.Serializable]
    public class mRow {
        public List<float> aRow = new List<float>();
    }

    [HideInInspector]
    [SerializeField]
    public int row;

    [HideInInspector]
    [SerializeField]
    public int col;

    //[HideInInspector]
    [SerializeField]
    public List<mRow> mat = new List<mRow>();
}
Run Code Online (Sandbox Code Playgroud)

最后,我知道解决方案,但我不知道为什么会出现这个问题.它与GC有关吗?

Hei*_*bug 8

你的问题不是很清楚,但我想知道你不理解什么.

我的策略是使用TextAsset,从TextAsset解析字符串,最后将Matrix实例转换为'Example.cs'中的字段变量.

您没有解释您是如何做到的(可能从自定义检查器调用解析函数?).但是,尽管您如何设法从编辑器初始化字段,但如果字段不可序列化,则从编辑器切换到播放模式时它将为null.

这是因为进入播放模式时,Unity3D序列化所有C#填充C++引擎相关类的类.如果字段不是Unity可以序列化的类型的公共字段(或者甚至是标记为a的私有字段SerializeFieldAttribute,总是Unity可以序列化的类型),Unity3D则不会将其序列化.

因此,当您切换到播放模式时,引用将为null.

换句话说,您想要从编辑器初始化的所有字段必须是可序列化的,以便在播放模式下使用.

[SerializeField]
public List<mRow> mat = new List<mRow>();
Run Code Online (Sandbox Code Playgroud)

上面的代码没有多大意义.如果您计划从检查器初始化可序列化字段,请不要通过代码初始化它,否则您最终可能会丢失引用.这种错误的一个例子:

[SerializeField]
private List<int> aList;

public void Start()
{
  aList = new List<int>();
} 
Run Code Online (Sandbox Code Playgroud)

上面的代码会引起麻烦.如果你已经aList从督察员初始化,它将被正确序列化,但当你切换到播放模式时,Start回调被调用,aList将重新初始化,你最终会得到一个空列表的引用.

这是一篇很好的博客文章,解释了如何Unity3D处理对象序列化的细节.阅读!

  • 这里有[其他](http://forum.unity3d.com/threads/155352-Serialization-Best-Practices-Megapost)好[资源](http://docs.unity3d.com/Documentation/ScriptReference/SerializeField. html)对任何其他感兴趣的人. (2认同)