什么是ScriptableObject呢?
ScriptableObject是一个可以让你在不运行游戏的同时,修改你的数据的一个类,你可以拿他做数据的存储。它可以不附加到游戏对象上。例如你想存储一个字符串用于显示敌人的名称,在脚本里写了个string字段,但是游戏结束后这个字段就会被回收掉,它没办法保存我们想保存的东西,这时候你可以试试使用ScriptableObject,因为它不受游戏运行状态的影响。
在使用ScriptableObject我们首先要使用CreateAssetMenu来为它提供一个入口:
[CreateAssetMenu(fileName ="gg", menuName = "选我!!!/asdas", order = 1)]
public class ss : ScriptableObject
{
public int cc;
}
这里的order是层级的意思,越小值在越上面。当点击asdas就会生成一个默认名称为gg的asset(因为fileName ='gg')。
需要注意的是[CreateAssetMenu]下只能写class不能写方法。必须是class。
假设这里的cc是子弹的个数,我想动态的修改子弹个数,这里如何判断cc的值被修改了呢?
我们需要使用到CustomEditor。
[CustomEditor(typeof(ss))]
public class sw : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
ss test = (ss)target;
if (GUI.changed)
{
Debug.Log("GUI.changed --> " + test.cc);
EditorUtility.SetDirty(test);
}
}
}
CustomEditor是一个绑定类的过程, [CustomEditor(typeof(ss))]意思是针对ss这个类做出反应,如果这段代码不加上 [CustomEditor(typeof(ss))]的话就无法响应到OnInspectorGUI这个方法。其中的target就是我们typeof(ss)进来的类。
GUI.changed是当ss这个类里的值发生了改变就会被标记为true,意思为有改变,我们就可以做出对应的操作,并使用EditorUtility.SetDirty(test);将test改变后的信息保存到磁盘里,如果用代码修改test.cc的值并且不调用 EditorUtility.SetDirty(test);重开unity客户端数值将还是之前的值并没真正的保存下来。
继承Editor这个类后OnInspectorGUI就好像我们Mono里的OnGUI,还有OnEnable当点击asset时会触发这个,离开这个asset(点击了其他的资源)会触发OnDestroy。
如果我想获得ss里的cc,我还可以利用序列化的方式得到。
[CustomEditor(typeof(ss))]
public class sw : Editor
{
SerializedProperty cc;
private void OnEnable()
{
Debug.Log("sw OnEnable");
cc = serializedObject.FindProperty(nameof(ss.cc));
}
}
通过serializedObject.FindProperty找到ss里的cc变量这里填的是变量名称。
然后通过
Debug.Log(cc.intValue);
可以得到cc的值因为他是int,如果是bool对应的就是boolValue,如果是数组的话可以使用arraySize得到长度。
如果对象是类的话
(cc.serializedObject).targetObject as Sheep
就可以吧他转成一个对象(Sheep 是我的类名)