Unity游戏开发入门征服Unity3dU3D技术采集

【Unity】简单说说ScriptableObject

2016-12-26  本文已影响1331人  黒可乐

很早就看到有这个东西了,但是一直没有去好好看,一看不知道,看了就爱上他了,真的是一个好用的东西。

是什么

用来存储数据的一个资源文件,像是JSON、XML、文本文件这样的存储文件,可以用来存储数据。但是这里他在最开始的时候不需要再次读文件,就像是JSON在游戏开始时,我们需要加载JSON文件中的数据,我们就需要读取这个文件,然后在赋值给对象。他就可以直接使用其中的数据。因为他是资源文件,所以他有着资源文件的特性,我们Resource.Load他就可以使用他了。
其实可以简单的理解为把你所有的数据都用变量在一个类中声明,然后我们使用的时候,直接实例化这个类就好了。

好处

●他可以作为一个引用在脚本上,因为他是资源文件。
●不会被unity序列化机制影响,所以可以多场景共有。(序列化文章
●在实例化对象时用它来做配置文件降低了内存的消耗
●有自己的回调OnEnable、OnDisable、OnDestroy。

怎么用

用简单的例子来看看怎么用。

数据体类:

[Serializable]
public class MyObj
{
    public int age;
    public string name;
}

创建:

[CreateAssetMenu]//可以直接在Project右键创建
public class MySciptObj : ScriptableObject
{
    public List<MyObj> myObjs;

    public void Print()
    {
        for (int i = 0, iMax = myObjs.Count; i < iMax; i++)
        {
            Debug.Log("Name:" + myObjs[i].name + "Age:" + myObjs[i].age);
        }
    }

    public void Save(string name, int age)
    {
        myObjs.Add(new MyObj {name = name, age = age});
    }
}

使用:

    private string age = string.Empty;
    private string name = string.Empty;

    private void OnGUI()
    {
        if (GUILayout.Button("Print"))
        {
            var data = Resources.Load<MySciptObj>("myObj");
            data.Print();
        }

        name = GUILayout.TextField(name);
        age = GUILayout.TextField(age);
        if (GUILayout.Button("Save"))
        {
            var data = Resources.Load<MySciptObj>("myObj");
            data.Save(name, int.Parse(age));
        }
    }
初始数据 加载并存储 在停止运行后再运行加载到数据

当然你也可以用菜单创建这个,如下:

    [MenuItem("MyMenu/Do CreatMyObj")]
    private static void CreatMyObj()
    {
        ScriptableObject.CreateInstance<MySciptObj>();
    }

今天就简单说说这个吧,其实他的用处和好处不仅仅是这么一点点,还有很多很多,今天就不一一说到了。
突然觉得这篇写的好水,虽然一直都好水。哈哈,见谅见谅。

2017/5/3更新

脚本文件名称一定要与继承ScriptableObject的类名一样。不然会出现脚本为空的情况。


脚本为空

这样会导致你现在序列化存储的数据在,等你修改了场景或者打包的时候数据就不会存在了。就会出现下面这种情况。

如果你这个时候再次指定脚本为None,这个问题就解决了。但还是会想上一张图那样,但是数据就是一直序列化了,修改场景然后保存都不会出现第二张图的情况。
但是严谨的思维,还是把脚本文件名称一定要与继承ScriptableObject的类名弄成一样。这样的话那个script上就不是None,出错的概率会少一些。

上一篇 下一篇

猜你喜欢

热点阅读