本文目录 15 个章节
ScriptableObject
创建时间:2020/6/9 17:02
ScriptableObject
- ScriptableObject
- 作用
- 特点
- 优点
- Method
- 使用方法
- MenuItem
- CreateAssetMenu
- 动态创建
- CreateAssets & FindAssets & ScriptableObject
- 生命周期
- 其他高级应用Demo
- 保存信息
- 用作配置文件
- Ref:
文档:https://docs.unity3d.com/ScriptReference/ScriptableObject.html https://docs.unity3d.com/Manual/class-ScriptableObject.html
ScriptableObject类直接继承自Object类;它和MonoBehaviour是并列的,都继承自Object(但MonoBehaviour并不是直接继承自Object)
是一个 数据容器 ,可以用来存储大量的数据,它是可序列化的。
作用
存储数据:在游戏运行时创建脚本化对象实例,然后可以将数据保存到本地(如果不保存,它会在游戏结束后销毁);
减少内存:将数据存储在ScriptableObject对象中,在代码中可以进行引用,来减少工程以及游戏运行时因拷贝值所造成的内存占用;
ScriptableObject与预制体 :当你有一个预制体,它附加了一些mono脚本,包含了一些数据,每次我们实例化预制体的时候它都会拷贝assets下原预制体的值生成一份自己的拷贝,然后我们可以修改场景内预制体的值而并不影响assets下预制体的值,这是prefab的特性,对于我们从一个prefab模板生成属性不同的游戏对象是很有用的,但是如果prefab里的脚本数据是不需要修改的,它就会造成很大的资源浪费,尤其在数据很多的时候;为了避免这种问题,我们可以在不需要修改prefab里的脚本数据时,考虑使用ScriptableObject来存储这些重复的数据,然后其它所有预制体都可以使用引用的方式来访问这份数据,这就意味着不管场景中实例了多少预制体,在内存中就只需要有一份数据;它所带给我们的启示就是, 当预制体中的脚本里有大量重复数据时,我们要想着将数据抽离,单独保存在本地
特点
- Unity编辑器外不可操作 :仅在编辑器中才可以保存修改的数据(因为ScriptableObject对象虽然声明在UnityEngine中,但是它的Scriptable是通过UnityEditor命名空间下的类例如Editor类等来实现的),所以在部署构建的时候不可以用于存储游戏运行时更改的数据,但是可以使用之前存储好的数据。也就是ScriptableObject生成的数据资源文件 在Editor外具有只读属性 ,如果你需要在游戏中修改数据并存储下来,就不推荐使用ScriptableObject了;
就像我们不可以在游戏运行时修改一个shader资源的代码、不可以修改一个纹理资源的像素内容一样,而在Unity Editor里可以修改ScriptableObject是因为Unity的编辑器对它格式的支持
继承自UnityEngine.Object,不必附着在对象上也无需/不能赋给Gameobject或Prefab
可以被serialize,可以在资源面板创建一个对应的.asset文件,把数据存储在资源文件中,通过属性面板可修改数值。该文件表示一个ScriptableObject的对象实例的序列化文件,退出之后也不会丢失。
本身是个类,可以引用,在项目之间共享
回调少 :OnEnable 、OnDisable、OnDestroy
persistent:当它被绑定到.asset文件或者AssetBundle等资源文件中的时候(它可以通过Resources.UnloadUnusedAssets来被unload出内存。可以通过脚本引用或其他需要的时候被再次load到内存) 非persistent:通过CreateInstance<>来创建的时候(它可以通过GC被直接destroy掉(如果没有任何引用的话)。如果不想被GC的话,可以使用HideFlags.HideAndDontSave)
优点
unity内置的一种储存容器
PlayMode储存数据更改(再也不怕更改数据没保存了) 3
Method
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
??? ScriptableObject内部实现上也继承自MonoBehavior,它只有四个消息函数,Awake()、OnDestroy()、OnEnable()、OnDisable();
使用方法
MenuItem
需要指定创建的目录和资源名称,如果资源已经存在,则不会创建新资源;
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
CreateAssetMenu
可以在Assets下任意目录创建资源,而且可以创建多个资源;
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
在Assets下创建一个可编程对象资源,设置好所需数据;如果需要在其它脚本中获取该数据,是需要声明一个该类型变量,然后为其赋值或加载该数据资源;然后,就像使用用一个类中的公有变量一样使用即可;
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
动态创建
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
CreateAssets & FindAssets & ScriptableObject
对于ScriptableObject,使用CreateInstance来创建Asset实例对象
testI = (ScriptObj)ScriptableObject.CreateInstance(typeof(ScriptObj));对于其他资源类型,使用new来创建对象
然后调用
AssetDatabase.CreateAsset函数,将实例对象作为资源存储在Assets路径当中。最后使用
AssetDatabase.FindAssets获取相应资源的GUID由
AssetDatabase.GUIDToAssetPath获取相应资源的路径。
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
生命周期
ScriptableObject的生命周期和其他资源都是类似的:
当它是被绑定到.asset文件或者AssetBundle等资源文件中的时候,它就是persistent的,这意味着 它可以通过Resources.UnloadUnusedAssets来被unload出内存 可以通过脚本引用或其他需要的时候被再次load到内存 如果是通过CreateInstance<>来创建的,它就是非persistent的,这意味着 它可以通过GC被直接destroy掉(如果没有任何引用的话) 如果不想被GC的话,可以使用HideFlags.HideAndDontSave
其他高级应用Demo
https://blog.csdn.net/candycat1992/article/details/52181814
保存信息
step1.创建你用于共享数据的类(例如EnemyData)
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
step2.新建一个脚本扩展Editor,使编辑器能够创建自定义的ScriptableObject对象
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
step3. 在需要引用的脚本中引用
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
用作配置文件
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
Ref:
https://blog.csdn.net/qq_36383623/article/details/99649941 https://blog.csdn.net/candycat1992/article/details/52181814