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的数据类方法,但是实际调用的子类的多态方法(例如角色碰撞道具获得效果,基类只管获取道具的方法,具体是加血还是加攻击由子类决定)