Unity14 - ScriptableObject
通过ScriptableObject
实现了多个gameObject
共享同一套数据(节约内存)、在Unity编辑器Inspector窗口中修改非持久化开发配置(方便)的目的。
目录
ScriptableObject
解决的问题
- 数据复用:批量生成子弹时,所有子弹对象具有相同的成员属性(
speed
,atk
,lifespan
等),但每生成一个子弹就要开辟一块内存存储相同的内容,使用ScriptableObject
可以让所有子弹共用同一块内存空间来存储这些相同的内容 - 数据外显:让数据显示在
Inspector
窗口中,便于修改
创建数据文件
- 继承:
public class MyData : ScriptableObject {}
- 继承
ScriptableObject
后在类中public
的变量会显示在Inspector
窗口中
- 继承
- 添加到
Create
资源菜单:[CreateAssetMenu(fileName="添加后显示在目录上的文件名",menuName="Create菜单显示的名,/分隔多级目录",order=在菜单上显示的顺序)]
使用数据文件
- 本质是创建了一个类似
Material
一样的Unity资源文件,内容完全自定义。在go上添加脚本,public
一个MyData
属性,就可以将创建的自定义资源文件拖上去 Resources
/AB包
/Addressables
都支持添加该资源- 多个go添加同一个资源时共享一个数据,一处修改多处改变
编辑器中持久化
- 在
MyData
类中public
后赋值,每次运行都会运行赋值代码,等效于编辑器中持久化,但发布后不会加载 - 每次修改都会修改本地文件
- 不使用本地文件,而是动态创建,实现不读取本地的非持久化
1
2
3
4
5
6//与go关联的组件脚本中
public MyData data;
void Start()
{
data = ScriptableObject.CreateInstance<MyData>();
}
- 不使用本地文件,而是动态创建,实现不读取本地的非持久化
- 可以通过保存数据到
json
/xml
等文件实现持久化,但多此一举,不建议
应用
只用不改,可在Unity中编辑,不需要发布,不需要持久化的配置
1 |
|
复用数据
- 为所有用到的go添加一个包含自定义数据资源属性的脚本组件,调用同一个数据资源
单例模式获取基类
- 所有的go为了获得该数据,都需要
public关联
或动态CreateInstance<>()
,每一个go都需要获取一次。通过建立单例模式获取基类来获取数据,让子类获取数据更方便1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class SingleScriptableObject<T>:ScriptableObject where T:ScriptableObject
{
private T instance;
public static T Instance
{
get
{
//自定义数据资源的路径是 Resources/类名.asset
if(instance==null){
instance = Resources.Load<T>("ScriptableObject/" + typeof(T).Name);
}
if(instance==null){
instance = CreateInstance<T>();
}
return instance;
}
}
} - 所有的自定义数据资源类都可以通过继承
SingleScriptableObject<类名>
,然后go脚本组件通过访问自定义数据类.Instance
获得自定义数据资源的数据