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

news2024/11/27 0:23:10

文章目录

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

​ 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.coloradmin.cn/o/608143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简单易懂的基础封装模块,让Web测试更简单!

目录 前言&#xff1a; 1. 环境配置 2. 创建基础封装模块的类 3. 运行测试用例 4. 结论 前言&#xff1a; 在当今互联网时代&#xff0c;Web应用程序的开发变得越来越重要。随着Web应用程序数量的增加&#xff0c;需要进行测试的Web应用程序也日益增加。为了加速测试过程&…

京东太狠:100W数据去重,用distinct还是group by,说说理由?

背景说明&#xff1a; Mysql调优&#xff0c;是大家日常常见的调优工作。所以&#xff0c;Mysql调优是一个非常、非常核心的面试知识点。在40岁老架构师 尼恩的读者社群(50)中&#xff0c;其相关面试题是一个非常、非常高频的交流话题。 近段时间&#xff0c;有小伙伴面试京东…

【论文】——Robust High-Resolution Video Matting with Temporal Guidance浅读

视频matting 时序监督 摘要 我们介绍了一种稳健、实时、高分辨率的人类视频抠图方法&#xff0c;该方法取得了新的最先进性能。我们的方法比以前的方法轻得多&#xff0c;可以在Nvidia GTX 1080Ti GPU上以76 FPS处理4K&#xff0c;以104 FPS处理HD。与大多数现有的逐帧作为独…

118.【微信小程序 - 02】

微信小程序-02 (六)、小程序基础加强1.自定义组件-组件的创建与引用(1).创建自定义组件(2).引用组件(全局和局部)(3).局部引用组件(4).全局引用组件(5).全局引用和局部引用的建议(6).组件和页面的区别 2.自定义组件-样式(1).组件样式隔离(2).组件样式隔离的注意点(3).修改组键的…

【2023】Redis哨兵模式集群

目录 &#x1f3b6; 哨兵模式&#x1f3b6; 搭建哨兵模式集群&#x1f3b6; 搭建一主二从复制集群&#x1f3b6; 创建哨兵节点 &#x1f3b6; 哨兵节点的其他配置&#x1f3b6; 哨兵模式下故障自动恢复效果&#x1f3b6; 通过日志查看故障恢复过程 &#x1f3b6; 哨兵模式 一般…

华为OD机试真题 Java 实现【获取字符串中连续出现次数第k多的字母的次数】【2023Q1 100分】,附详细解题思路

一、题目描述 给定一个字符串&#xff0c;只包含大写字母&#xff0c;求在包含同一字母的子串中&#xff0c;长度第 k 长的子串的长度&#xff0c;相同字母只取最长的那个子串。 二、输入描述 第一行有一个子串(1<长度<100)&#xff0c;只包含大写字母&#xff1b;第二…

Zinx框架学习 - 多路由实现

Zinx - V0.6 多路由实现 之前在已经给Zinx配置了路由模式&#xff0c;但是之前的Zinx只能绑定一个路由的处理业务方法显然这是无法满足基本的服务器需求&#xff0c;需要给Zinx添加多路由的方案查看之前的Server定义&#xff0c;路由Router只有一个&#xff0c;当我们想要再添…

七个很好的 Python 工具,让你的生活更轻松

有一句谚语“你不必重新发明轮子”。工具就是最好的例子。它可以帮助您以简单的方式实现复杂且耗时的功能。在我看来&#xff0c;为了提高生产力和效率&#xff0c;我们需要使用一些可用的最佳工具。在这里&#xff0c;我整理了 7 个工具&#xff0c;可以帮助您完成开发之旅。 …

【网络】TCP通讯(三次握手、四次挥手;滑动窗口;TCP状态转换;端口复用;TCP心跳检测机制)

前言&#xff1a;建议看着图片&#xff0c;根据文字描述走一遍TCP通讯过程&#xff0c;加深理解。 目录 TCP通信时序&#xff1a; 1&#xff09;建立连接&#xff08;三次握手&#xff09;的过程&#xff1a; 2&#xff09;数据传输的过程&#xff1a; 3&#xff09;关闭连…

java的IP组播

文章目录 1. 简介2. 组播地址和组3. 客户端和服务器4. 路由器和路由5. 使用组播Socket6. 构造函数7. 与组播组通信8. 案例实战 1. 简介 前面介绍的Socket都是单播Socket&#xff0c;它们提供点对点的通信。单播Socket在两个明确的端点之间创建一个连接&#xff0c;有一个发送方…

LNMP平台搭建

文章目录 安装 Nginx 服务安装 MySQL 服务安装配置 PHP 解析环境 安装 Nginx 服务 systemctl stop firewalld systemctl disable firewalld setenforce 0安装依赖包 yum -y install pcre-devel zlib-devel gcc gcc-c make创建运行用户 useradd -M -s /sbin/nologin nginx编译…

ArduPilot之H743+BMI270x2+First Normal Takeoff

ArduPilot之H743BMI270x2First Normal Takeoff 1. 源由2. 正常起飞3. 问题汇总3.1 机架构型3.2 IMU对齐3.3 接收机3.4 GPS3.5 VTX3.6 电调3.7 PID 4. 总结5. 参考资料6. 附录6.1 补充AcroTrainer视频6.2 补充Acro视频 1. 源由 鉴于目前该飞控板子在ArduPilot开源社区尚未得到官…

Photoshop 批量照片转格式

Photoshop 批量照片转格式 文章目录 Photoshop 批量照片转格式前言一、打开Photoshop软件二、打开图像处理器三、参数设置四、运行 前言 在工作和学习中&#xff0c;我们可能会遇到需要处理多张图片、更改多张图片格式的情况&#xff0c;如果一张一张的进行处理是很麻烦浪费时…

一步一步从功能测试到测试开发,我这一路的坎坷谁能懂?

读者提问&#xff1a; 测试开发工程师到底是测试&#xff0c;还是开发 &#xff1f; 鱼鱼回答&#xff1a; 既是测试&#xff0c;也是开发。 首先&#xff0c;测试开发是测试工程师&#xff0c;他们是服务于业务测试同学的&#xff0c;目标是解决业务测试工程师的具体问题。…

基于flask的web应用开发——接受post请求

目录 0. 前言1. 了解post方法2. 在flask中实现3. 具体讲解 0. 前言 操作系统&#xff1a;Windows10 家庭版 开发环境&#xff1a;Pycahrm Comunity 2022.3 Python解释器版本&#xff1a;Python3.8 第三方库&#xff1a;flask 1. 了解post方法 POST是HTTP协议定义的一种请…

尚硅谷JUC极速版笔记

尚硅谷JUC极速版笔记 1、JUC概述1.1 进程和线程1.2 线程的状态&#xff08;6个&#xff09;1.3 wait和sleep1.4 并发与并行1.5 管程&#xff08;锁&#xff09;1.6 用户线程和守护线程 2、Lock接口2.1 复习synchronized&#xff08;java内置同步锁&#xff09;2.2 什么是Lock接…

03使用IDEA快速开发一个WEB应用的具体流程

使用集成开发环境实现web开发 集成开发工具很多&#xff0c;其中目前使用比较多的是IntelliJ IDEA和Eclipse IntelliJ IDEA(居多): JetBrain公司开发的收费软件, IDEA在提示功能方面要强于Eclipse使用起来更加智能更好用Eclipse(较少):Eclipse是IBM团队开发的, Eclipse寓意是…

ChatGPT 国内镜像网站独家汇总:发现最优秀的人工智能对话体验!

欢迎来到我们的 ChatGPT 镜像网站汇总博客&#xff01;在这个令人激动的人工智能时代&#xff0c;ChatGPT 作为一款顶尖的语言模型&#xff0c;已经引起了全球范围内的热议。但是&#xff0c;您是否曾经为了找到最佳的 ChatGPT 使用体验而苦苦搜寻&#xff1f;别担心&#xff0…

电商业务逻辑总结

一、后台模块:商品管理 1. 基本概念 ① spu: 标准化产品单元 不是一件具体的商品 eg iphone14 ② sku: 库存量单元 指的就是一件具体的商品 eg iphone14 128G 蓝色 ③ 销售属性 出现了商品详情页右侧的商品属性信息 ④ 平台属性 出现了商品详情页下…

vue 实现微信扫码登录的方法

一、准备工作&#xff1a; 1.微信公众号&#xff0c;扫码登录 2.域名&#xff0c;也就是域名解析&#xff08;public_domain&#xff09; 3.微信登录验证 4.配置微信扫码登录页面的代码&#xff0c;有了上面的准备工作&#xff0c;下面就可以开始编码了。 二、开发环境&#xf…