关于Unity3d ScriptableObject储存的问题

关于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方法。做事情之前,一定要先想好,不然后面有大麻烦。

发布了1 篇原创文章 · 获赞 1 · 访问量 17

猜你喜欢

转载自blog.csdn.net/achivieme/article/details/103949800