很早就看到有这个东西了,但是一直没有去好好看,一看不知道,看了就爱上他了,真的是一个好用的东西。
是什么
用来存储数据的一个资源文件,像是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,出错的概率会少一些。