Unity 内部类的属性序列化问题

来源:互联网 发布:淘宝开两家店 编辑:程序博客网 时间:2024/05/17 06:14

前段时间 要做个 基于地图生成工具tileworld 的一些扩展。。 找了不少关于扩展编辑器的资料。 解决了一些问题 这里记录一下。


问题: 内部类的属性序列化问题

关于修改自定一的MonoBehaviour , 这里 遇到这样一个类

public class TileWorldCreator : MonoBehaviour{         // ----------  省略的代码        [System.Serializable]        public class Maps        {                // ----------  省略的代码            public GameObject[,] gameObjectsMap = new GameObject[0,0];            public GameObject[] gameObjectsMapSingle = new GameObject[0];             // ----------  省略的代码            public Maps(){}            public Maps(int _x, int _z, bool _invert, bool _useMask, int _selectedMask)            {                gameObjectsMap = new GameObject[_x, _z];                gameObjectsMapSingle = new GameObject[_x * _z];                gameObjectsInstanceID = new int[_x * _z];                for (int i = 0; i < _z; i++)                {                    for (int j = 0; j < _x; j++)                    {                         // ----------  省略的代码                        gameObjectsMap[j, i] = null;                    }                }            }            // ----------  省略的代码        }        public int mapIndex = 0;        int lastMapIndex = 0;        public List<Maps> worldMap = new List<Maps>();}  // ----------  省略的代码

在MonoBehaviour类中的一个内部类 Map 我们知道 mono的类中public 的属性是可以 自动序列化的(也就是说下次在打开工程的时候 之前改过的属性 不会被重置) 当然还需一个设置 在 edit -> project setting -> Editor 中 设置 asset serialization 为 ForceText, 这个似乎是默认的。

理论是这样 但是 我有需求 通过代码初始化和设置这两个队对象。。
public GameObject[,] gameObjectsMap = new GameObject[0,0];
public GameObject[] gameObjectsMapSingle = new GameObject[0];

但经过一些列的测试 惊奇的发现 这样操作竟然不行 这个数组的内容竟然没有存住, 于是乎便进行了各种测试。 差了不少资料。得出一下几点需要注意 这里记下备忘。

首先 需要注意的是 如果 需要存储内部类对象的数据 首先类就要加上修饰 [System.Serializable]
这里写图片描述
再有就是 public List worldMap = new List(); 这里的public 也要注意的 不然还需要在加修饰 我这里就直接用 public了。

我检查了代码发现都有啊。 这就奇怪了。 为什么存不住呢。。 之后 我又做了一系列测试。

测试代买 在这
这里写图片描述
这里有个说明 好像是 unity 5.3以上 还是 5以上 就不需要对 mono类进行 修饰了 。[System.Serializable] 也就是这里不写也是一样。
这里 所有的属性的 设置都是 通过 代码实现的。 我扩展了检视面板 。
这里写图片描述

在 OnEnable() 中 为data 初始化 data = (TestSerializableData)target;
在 OnInspectorGUI() 这里 绘制几个按钮来调用 data中的函数 方便 测试。

通过测试 发现 通过new出来的数组 在这是之后是存不住的。 但是基础类型可以。 反复测试发现。 如果在数组赋值之后 手动通过编辑器 修改基础数据类型就可以存住。。 这下就明白了 验证了一下 果然 只是初始化 new 出来的数组 本应该有的 ‘*’这里写图片描述 并没有出现。 这就是存不住的原因 因为编辑器压根就没觉得需要存。。(真是日了狗了!花了我好多时间!!) 问题找到了 肯定是要告知untiy 一下,之后就好办了 网上翻了一圈 于是找到了一个函数
这里写图片描述

将这个函数放到修改数组的地方加入传入当前场景。
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
试了下 虽然一维数组没问题了 但是2维的还是不行。 之后我去翻了tileworld的源码 终于明白 为什么他要用两个数组去存了。。 似乎2维的存不住 他这里用1维的还原2维的以便继续使用
这里写图片描述
原本的代码有点问题 稍微修改了一下就好了。 至于2维数组的为什么不好用的问题。 没有进一步研究 这里就这样了。

0 0
原创粉丝点击