很早就看到有這個東西了,但是一直沒有去好好看,一看不知道,看了就愛上他了,真的是一個好用的東西。
是什么
用來存儲數(shù)據(jù)的一個資源文件,像是JSON、XML、文本文件這樣的存儲文件,可以用來存儲數(shù)據(jù)。但是這里他在最開始的時候不需要再次讀文件,就像是JSON在游戲開始時,我們需要加載JSON文件中的數(shù)據(jù),我們就需要讀取這個文件,然后在賦值給對象。他就可以直接使用其中的數(shù)據(jù)。因為他是資源文件,所以他有著資源文件的特性,我們Resource.Load他就可以使用他了。
其實可以簡單的理解為把你所有的數(shù)據(jù)都用變量在一個類中聲明,然后我們使用的時候,直接實例化這個類就好了。
好處
●他可以作為一個引用在腳本上,因為他是資源文件。
●不會被unity序列化機制影響,所以可以多場景共有。(序列化文章)
●在實例化對象時用它來做配置文件降低了內(nèi)存的消耗
●有自己的回調(diào)OnEnable、OnDisable、OnDestroy。
怎么用
用簡單的例子來看看怎么用。
數(shù)據(jù)體類:
[Serializable]
public class MyObj
{
public int age;
public string name;
}
創(chuàng)建:
[CreateAssetMenu]//可以直接在Project右鍵創(chuàng)建
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));
}
}



當(dāng)然你也可以用菜單創(chuàng)建這個,如下:
[MenuItem("MyMenu/Do CreatMyObj")]
private static void CreatMyObj()
{
ScriptableObject.CreateInstance<MySciptObj>();
}
今天就簡單說說這個吧,其實他的用處和好處不僅僅是這么一點點,還有很多很多,今天就不一一說到了。
突然覺得這篇寫的好水,雖然一直都好水。哈哈,見諒見諒。
2017/5/3更新
腳本文件名稱一定要與繼承ScriptableObject的類名一樣。不然會出現(xiàn)腳本為空的情況。

這樣會導(dǎo)致你現(xiàn)在序列化存儲的數(shù)據(jù)在,等你修改了場景或者打包的時候數(shù)據(jù)就不會存在了。就會出現(xiàn)下面這種情況。

如果你這個時候再次指定腳本為None,這個問題就解決了。但還是會想上一張圖那樣,但是數(shù)據(jù)就是一直序列化了,修改場景然后保存都不會出現(xiàn)第二張圖的情況。
但是嚴謹?shù)乃季S,還是把腳本文件名稱一定要與繼承ScriptableObject的類名弄成一樣。這樣的話那個script上就不是None,出錯的概率會少一些。