Unity进阶-ScriptableObject
ScriptableObject概述
1.ScriptableObject说明:ScriptableObject是Unity提供的一个数据配置存储基类,它是一个可以用来保存大量数据的数据容器,就像是可以自定义的数据预制物资源文件,需要我们继承它来进行使用,它的主要作用是如下:
- 数据复用(多个对象用同一个数据)
- 配置文件(配置游戏中的数据)
- 编辑模式下的数据持久化
2.ScriptableObject优点:如下
- 我们可以直接在Inspector窗口编辑配置数据,可以利用它来做配置文件;
- 处理重复数据,减少数据拷贝时造成的内存占用,可以利用它来做公共数据;
- 可以更方便的处理数据带来的多态行为;
3.ScriptableObject持久化注意点:通过代码修改数据对象中内容,会影响数据文件,相当于达到了编辑器中数据持久化的目的(该数据持久化 只是在编辑模式下的持久,发布运行时并不会保存数据);
ScriptableObject数据文件创建
1.自定义ScriptableObject数据容器
//1.继承ScriptableObject类
//2.在该类中声明成员(变量、方法等)
//注意:声明后,我们边可以在Inspector窗口中看到变化
// 我们可以在其中进行设置,但是这些设置都是默认数据,并没有真正使用他们
// 这些关联信息都是通过脚本文件对应的Unity配置文件meta进行记录的
// 目前该数据只是一个数据容器模板
// 有了它我们之后才能根据它的信息创建对应的数据资源文件
2.根据自定义的ScriptableObject数据容器创建数据文件
//注意:
//该创建功能,其实就是根据自定义数据容器类创建了一个配置文件
//该文件中记录了对应的数据容器类信息,以及其中变量关联的信息
//之后我们在使用它时,本质上也是通过反射创建对象进行使用
//具体的方法有两种:
//1.为类添加CreateAssetMenu通过菜单创建资源特性
//[CreateAssetMenu(fileName = "默认文件名", menuName = "在Asset/Create菜单中显示的名字", order = 再Asset/Create菜单中的位置(多个时可以通过它来调整顺序))]
//2.利用ScriptableObject的静态方法创建数据对象
//书写创建数据资源文件的代码
MyData asset = ScriptableObject.CreateInstance<MyData>();
//通过编辑器API 根据数据创建一个数据资源文件
AssetDatabase.CreateAsset(asset, "Assets/Resources/MyDataTest.asset");
//保存创建的资源
AssetDatabase.SaveAssets();
//刷新界面
AssetDatabase.Refresh();
ScriptableObject数据文件使用
1.ScriptableObject数据文件的使用
//1.通过Inspector中的public变量进行关联
//1-1.创建一个数据文件
//1-2.在继承MonoBehaviour类中申明数据容器类型的成员
// 在Inspector窗口进行关联
//2.通过资源加载的信息关联
//加载数据文件资源
//注意:Resources、AB包、Addressables都支持加载继承ScriptableObject的数据文件
data = Resources.Load<MyData>("MyDataTest");
//注意:如果多个对象关联同一个数据容器文件,他们共享的是一个对象
// 因为是引用对象,所以在其中任何地方修改后,其它地方也会发生改变
2.ScriptableObject的生命周期函数
//ScriptableObject和MonoBehavior很类似
//它也存在生命周期函数
//但是生命周期函数的数量更少
//主要做了解,一般我们使用较少
//Awake 数据文件创建时调用
//OnDestroy ScriptableObject 对象将被销毁时调用
//OnDisable ScriptableObject 对象销毁时、即将重新加载脚本程序集时 调用
//OnEnable ScriptableObject 创建或者加载对象时调用
//OnValidate 编辑器才会调用的函数,Unity在加载脚本或者Inspector窗口中更改值时调用
ScriptableObject的非持久化和持久化
1.ScriptableObject的非持久化数据说明:指的是不管在编辑器模式还是在发布后都 不会持久化的数据,我们可以根据自己的需求随时创建对应数据对象进行使用,就好像直接new一个数据结构类对象;
2.利用ScriptableObject生成非持久化的数据:利用ScriptableObject中的静态方法 CreateInstance<>(),通过这种方式创建出来的数据对象 它里面的默认值 不会受到脚本中设置的影响,该对象只存在于内存当中,可以被GC;
3.非持久化数据存在的意义:只是希望在运行时能有一组唯一的数据可以使用,但是这个数据又不太希望保存为数据资源文件浪费硬盘空间,那么ScriptableObject的非持久化数据就有了存在的意义(只在运行时使用,在编辑器模式下也不会保存在本地)
4.ScriptableObject真正意义的持久化:持久化(硬盘<=>内存),首先要理解的是ScriptableObject的主要意义并不是用来进行持久化的,但是我们也可以利用持久化的相关知识来进行运行时读取;
ScriptableObject的应用
配置数据
1.ScriptableObject配置说明:ScriptableObject适合用来作配置文件,结合List使用或者字典使用(集合类型遵守Unity规则,加上序列化标签),也可以在Excel中作配置,然后编辑器导出ScriptableObject文件;
复用数据
1.ScriptableObject复用数据说明:游戏实体中定义的数据是不同地址的,但是对于只用不变的数据,以面向对象的思想去声明是会存在内存浪费的,特别是像子弹这种类型,所以我们刻意利用ScriptableObject静态数据来进行共享使用,更加节约内存;
数据带来的多态行为
1.ScriptableObject的多态:当数据不一样时带来的多态行为,依赖于抽象,而不依赖于实现,调用继承自ScriptableObject的数据类方法,但是实际调用的子类的多态方法(例如角色碰撞道具获得效果,基类只管获取道具的方法,具体是加血还是加攻击由子类决定)