2023-06-04 Unity ScriptableObject1——ScriptableObject数据文件

news/2024/11/8 9:38:05/

文章目录

        • 一、创建数据模板
        • 二、创建数据文件
        • 三、使用数据文件
        • 四、非持久化特性

​ ScriptableObject 是 Unity 提供的一个数据配置存储基类,可以用来保存大量数据的数据模板,类似于可以自定义的数据资源文件模板

​ 它是一个类似 MonoBehavior 的基类,需要继承来进行使用

​ 主要作用:

  1. 数据复用(多个对象用同一个数据)

  2. 配置文件(配置游戏中的数据)

  3. 编辑模式下的数据持久化

​ 优点:

  1. 直接在 Inspector 窗口编辑配置数据,利用它来做配置文件

  2. 处理重复数据,减少数据拷贝时造成的内存占用,利用它来做公共数据

  3. 更方便的处理数据带来的多态行为

一、创建数据模板

​ 创建 ScriptableObject 数据模板,需要进行的操作为:

  1. 创建 C# 脚本,继承 ScriptableObject 类
  2. 在该类中声明成员(变量、方法等)
public class MyData : ScriptableObject
{// 可以声明任何类型的成员变量// 如果希望在 Inspector 窗口中能够编辑它,需要声明为 public 或添加 SerializeField 特性public int   i;public float f;public bool  b;public GameObject obj;public Material   m;public AudioClip  audioClip;public VideoClip  videoClip;public void PrintInfo() {Debug.Log(i);Debug.Log(f);Debug.Log(b);}
}

​ 声明后,我们边可以在 Inspector 窗口中看到变化

​ 我们可以在其中进行设置,但是这些设置都是默认数据,并没有真正使用他们

image-20230604144929256

​ 这些关联信息都是通过脚本文件对应的 Unity 配置文件 meta 进行记录的,打开该脚本同目录下的 .meta 文件可看到:

image-20230604145315888

​ 目前该数据只是一个数据容器模板,只是规定了需要创建的数据格式,并没有创建数据文件

二、创建数据文件

​ 具体的方法有两种:

  1. 为类添加 CreateAssetMenu 特性,通过菜单创建资源

    • [CreateAssetMenu(fileName, menuName, order)]

      fileName:创建出来的默认数据文件名

      menuName:在 Asset / Create 菜单中显示的名字

      order:在 Asset / Create 菜单中的顺序,通过数字指定排列优先级

    [CreateAssetMenu(fileName = "MyData", menuName = "ScriptableObject/我的数据", order = 0)]
    public class MyData : ScriptableObject 
    {...
    }
    

    ​ 在 Project 窗口中右键即可找到对应目录创建数据文件:

    image-20230604150235308

    ​ 创建出来的文件是实实在在的独立数据文件 .asset,可以在 Inspector 面板中编辑其数据。

    image-20230604150321416
  2. 利用 ScriptableObject 的静态方法创建数据对象,然后将数据对象保存在工程目录下

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class ScriptableObjectTool
{[MenuItem("ScriptableObject/CreateMyData")]public static void CreateMyData(){// 书写创建数据资源文件的代码MyData asset = ScriptableObject.CreateInstance<MyData>();// 通过编辑器API 根据数据创建一个数据资源文件AssetDatabase.CreateAsset(asset, "Assets/Resources/MyDataTest.asset");// 保存创建的资源AssetDatabase.SaveAssets();// 刷新界面AssetDatabase.Refresh();}
}

​ 在菜单窗口中即可创建,效果和方法 1 一样。

​ 但是由于引用了 UnityEditor 命名空间,需要将该脚本放在 Editor 文件夹下,否则项目打包会失败。

image-20230604150744685

​ 方法 1 在项目使用中更常用,方法 2 在 Unity 编辑器开发中更常见。

三、使用数据文件

(一)直接关联使用

​ 在继承 MonoBehaviour 类中申明数据容器类型的成员,在 Inspector 窗口进行关联

public class Lesson2 : MonoBehaviour
{public MyData data;
}
image-20230604151604644

(二)加载数据使用

​ 使用代码加载数据文件资源

​ Resources、AB包、Addressables 都支持加载继承 ScriptableObject 的数据文件

​ 以 Resources 为例,将数据文件放入 Resources 文件夹下,之后使用代码加载。

image-20230604151857695
public class Lesson2 : MonoBehaviour
{public MyData data;private void Start() {data = Resources.Load<MyData>("ScriptableObject/MyDataTest");data.PrintInfo();}
}

(三)生命周期函数

​ ScriptableObject 和 MonoBehavior 类似,也存在生命周期函数

​ 但是生命周期函数的数量更少,主要做了解,一般使用较少

  • Awake:数据文件创建时调用
  • OnDestroy:ScriptableObject 对象将被销毁时调用
  • OnDisable:ScriptableObject 对象销毁时、即将重新加载脚本程序集时调用
  • OnEnable:ScriptableObject 创建或者加载对象时调用
  • OnValidate:编辑器才会调用的函数,Unity 在加载脚本或者 Inspector 窗口中更改值时调用
public class MyData : ScriptableObject
{// 可以声明任何类型的成员变量// 如果希望在 Inspector 窗口中能够编辑它,需要声明为 public 或添加 SerializeField 特性public int   i;public float f;public bool  b;public GameObject obj;public Material   m;public AudioClip  audioClip;public VideoClip  videoClip;private void Awake() {Debug.Log("数据文件创建时会调用");}private void OnEnable() { }private void OnDisable() { }private void OnDestroy() { }private void OnValidate() {Debug.Log("123");}public void PrintInfo() {Debug.Log(i);Debug.Log(f);Debug.Log(b);}
}
image-20230604152516958

用途:

  1. 编辑器中的数据持久化

    通过代码修改数据对象中内容,会影响数据文件,相当于达到了编辑器中数据持久化的目的
    (该数据持久化只是在编辑模式下的持久,发布运行时并不会保存数据)

  2. 复用数据

    如果多个对象关联同一个数据文件

    相当于他们复用了一组数据,内存上更加节约空间

​ 创建出来的数据资源文件,可以理解成一种记录数据的资源

​ 它的使用方式,和 Unity 中其它资源规则是一样的,比如:预设体、音频文件、视频文件、动画控制器文件、材质球等等

​ 只不过通过继承 ScriptableObject 类生成的数据资源文件,它主要是和数据相关的

四、非持久化特性

​ ScriptableObject 的非持久化指的是不管在编辑器模式还是在发布后,下次运行程序后之前修改的数据都不会存储下来

​ 通过 ScriptableObject 中的静态方法 ScriptableObject.CreateInstance() 创建数据文件来使用,就好像直接 new 一个数据结构类对象,其构造函数在 ScriptableObject 模板中定义。

data = ScriptableObject.CreateInstance("MyData") as MyData;
data = ScriptableObject.CreateInstance<MyData>();
data.PrintInfo();
  • 该方法可以在运行时创建出指定继承 ScriptableObject 的对象
  • 该对象只存在于内存当中,可以被 GC 回收,调用一次就创建一次

意义:

  • 只希望在运行时能有一组唯一的数据可以使用,但又不希望保存为数据资源文件浪费硬盘空间
  • 只在运行时使用,在编辑器模式下也不会保存在本地

​ 对于 ScriptableObject 的数据,由于它在游戏发布运行过程中无法被持久化,可以利用 PlayerPrefs、XML、Json、2进制等等方式,让其可以达到被真正持久化的目的。

但是并不建议使用 ScriptableObject 来做数据持久化,有点画蛇添足


http://www.ppmy.cn/news/206401.html

相关文章

iPhone 6s 进水后 黑屏 闪屏 如何解决?

iPhone 6s 进水后 黑屏、闪屏 等 如何解决&#xff1f; 提供一个 可行的思路&#xff0c;亲测有效。 先将手机 放在 通风的地方 一天左右&#xff0c; 然后开机&#xff0c; 开机后 如果黑屏 或者 闪屏&#xff0c;基本是由于 iPhone的 光线感应 出现了问题。 那么 将 手机 置…

5s进水不开机怎么办 苹果5s进水后无法开机的维修方法

5s进水不开机怎么办 苹果5s进水后无法开机的维修方法&#xff0c;这个教程仅供参考&#xff0c;故障出现后的问题为进水&#xff0c;不能开机&#xff0c;以及手机会出现大电流&#xff0c;并且出现灰屏&#xff0c;还会漏电。 一般此类问题的导致&#xff0c;为手机刷坏&#…

苹果手机突然黑屏_手机突然黑屏该怎么办?别慌张,你可以这样解决!

随着网络信息化时代的高速发展&#xff0c;手机支付和各种app产品进入我们的实现&#xff0c;人们越来越依赖手机&#xff0c;但长期的使用手机难免会让机器出现这样那样的问题&#xff0c;比如卡顿、发烫、黑屏等情况的发生&#xff0c;尤其在我们进行通话或娱乐游戏的时候&am…

苹果xsmax怎么开机_苹果XSMAX进水不开机维修

【故障机型】&#xff1a;苹果XSMAX 【故障现象】&#xff1a;进水不开机维修 【维修过程】&#xff1a;收到客户发来的一台苹果XSMAX故障描述为进水不开机&#xff0c;已经进水20多天了&#xff0c;在进水当天已经给手机维修店拆出来吹干了&#xff0c;用了几天不开机了&#…

苹果手机黑屏了怎么办_来电话手机黑屏怎么办

使用手机的用户大家可能遇到过打电话黑屏的问题&#xff0c;在通话时黑屏虽说通话还能进行&#xff0c;但是如录音、挂断电话、增减音量等等操作是无法进行的&#xff0c;这种情况很是麻烦。有些人可能会选择直接关机&#xff0c;但经常这样也不好。那么&#xff0c;来电话手机…

手机进水开机android,手机进水了闪退的解决方法

闪退&#xff0c;多指在移动设备中&#xff0c;在打开应用程序时出现的突然退出中断的情况。手机进水了闪退的解决方法&#xff0c;我们来看看。 手机应用闪退是怎么办&#xff1f; 手机闪退原因一、缓存垃圾太多 手机应用闪退是怎么回事 常见的修复方法介绍 由于安卓系统的特性…

苹果手机更新后开不了机_苹果7突然黑屏,苹果7开不了机

当苹果手机遇到黑屏会令人十分困扰&#xff0c;那苹果7突然黑屏&#xff0c;苹果7开不了机怎么办&#xff1f;我们应该如何处理iPhone7黑屏故障呢&#xff1f;遇到苹果手机黑屏首先我们需要辨别手机黑屏是硬件问题造成的&#xff0c;还是软件问题造成的。下面带大家一起去了解苹…

手机进水了怎么办,手机进水声音怎么变了怎么处理比较好

科技的发展改变了生活&#xff0c;像智能手机、智能汽车等&#xff0c;而说到手机&#xff0c;现在人们的生活已经离不开手机&#xff0c;像在购买东西都是通过手机支付、生活缴费、沟通等&#xff0c;相信很多人有过这样的经历&#xff0c;就是手机不小心掉进水里了&#xff0…