关于Unity3d ScriptableObject储存的问题
无法保存的类型
1 二维以上的数组(list包含一个数组也不行)
2未标记为可序列化的类 结构体等或者不可序列化的对象
3 字典
4 泛型
解决办法
1 把二维以上的数组或者list转换为1维
2 加上[Serializable],加上这个还不够,因为如果这个类或者结构体等等里面的内容有部分无法序列化,这一部分依然无法储存。
3 把字典转换为1维数组等若干数据
4 不要出现泛型
具体解决方法
二维数组
[Serializable]
public struct TwoDimensionAlarray<T1>
{
T1[] array1;
int[] index;
int total;
public void Save(T1[][] data)
{
index = new int[data.Length] ;
for (int i=0;i<data.Length;i++)
{
total += data[i].Length;
index[i] = data[i].Length;
}
array1 = new T1[total];
var nowindex = 0;
for (int i = 0; i < data.Length; i++)
{
for (int j = 0; j < data[i].Length; j++)
{
array1[nowindex] = data[i][j];
nowindex++;
}
}
Debug.Log("储存" + array1);
}
public void ReLoad(ref T1[][] data)
{
data = GetTheArray();
}
public T1[][] GetTheArray()
{
Debug.Log("读取" + array1);
T1[][] data;
if (index == null)
{
Debug.LogWarning("好歹你得先save再读取吧!");
data = null;
}
else
{
var nowindex = 0;
data = new T1[index.Length][];
for (int i = 0; i < index.Length; i++)
{
data[i] = new T1[index[i]];
for (int j = 0; j < index[i]; j++)
{
data[i][j] = array1[nowindex];
nowindex++;
}
}
}
return data;
}
}
这样子可以将2维数组转为1维,但是问题来了,因为表达为泛型的话,他是无法保存的。所以使用的时候,我们必须要把泛型具体化。比如我要转换二维int。
[Serializable]
public struct TwoDimensionAlarrayint
{
int[] array1;
int[] index;
int total;
public void Save(int[][] data)
{
index = new int[data.Length];
for (int i = 0; i < data.Length; i++)
{
total += data[i].Length;
index[i] = data[i].Length;
}
array1 = new int[total];
var nowindex = 0;
for (int i = 0; i < data.Length; i++)
{
for (int j = 0; j < data[i].Length; j++)
{
array1[nowindex] = data[i][j];
nowindex++;
}
}
Debug.Log("储存" + array1);
}
public void ReLoad(ref int[][] data)
{
data = GetTheArray();
}
public int[][] GetTheArray()
{
Debug.Log("读取" + array1);
int[][] data;
if (index == null)
{
Debug.LogWarning("好歹你得先save再读取吧!");
data = null;
}
else
{
var nowindex = 0;
data = new int[index.Length][];
for (int i = 0; i < index.Length; i++)
{
data[i] = new int[index[i]];
for (int j = 0; j < index[i]; j++)
{
data[i][j] = array1[nowindex];
nowindex++;
}
}
}
return data;
}
}
这样子就可以将二维保存为1维,但是就是每储存一种类型就要写一个 ,很不方便。list的话可以用表达式的tolist()转换。
未标记序列化
。。那就加上去。。。[Serializable]
字典
因为泛型不能使用,所以,字典的储存也是比较麻烦的。
但是思路是和二维数组差不多,把字典转换为1维数组就可以了。
三维数组的一个技巧。若要三维数组的话,只要在二维数组的转换对象基础上TwoDimensionAlarrayxx,声明一个数组。如
TwoDimensionAlarrayObject[] valueser2;
储存
for (int i = 0; i < valueser2.Length; i++)
{
valueser2[i].Save(values2[i]);
}
读取
for (int i=0;i<values2.Length;i++)
{
values2[i] = valueser2[i].GetTheArray();
}
values2是一个三维数组。
更多维度的就以此类推。
实际上,学好数据结构是很重要的,我没有学过数据结构,而且之前对这个也不是很了解,所以导致游戏的一个编辑器系统做到后期储存出现了这种重大问题,懒得重构系统框架,只能用这种耗费内存的办法来适配。也就是代码里面的save 和 load方法。做事情之前,一定要先想好,不然后面有大麻烦。