unity——ScriptableObject相关知识点【学习笔记/不足之处欢迎斧正/个人复习向/侵删】

一、相关简介

1.ScriptableObject是什么:Unity提供的一个数据存储基类

2.ScriptableObject的好处有哪些:文件配置、数据复用、更好的处理数据带来的多态性为

二、ScriptableObject的创建

1.自定义ScriptableOject数据容器

        继承ScriptableObject类

        在该类中声明成员(变量、方法等)

public class StudyUnity : ScriptableObject
{//可以在其中声明任何一种类型的变量,//如果想要在Inspector窗口中能够编辑它,那么//声明变量的规则应该与MonoBehavior的public变量规则相同public bool a;public float b;public GameObject c;public Material d;
}

        通过这种方式,我们能在Inspector窗口中看到变化,其中数据的关联信息是通过脚本文件unity配置的meta文件进行记录的,之后我们可以利用他的信息创建对应的数据资源文件

2.根据自定义ScriptableObject数据容器创建数据文件

本质上是根据自定义数据容器类创建了一个配置文件,该文件中记录了对应的数据容器类信息,以及其中变量关联的信息,我们在使用的过程中,本质上也是通过反射创建对象进行使用的

具体的方式有两种:

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

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[CreateAssetMenu(fileName ="a文件",menuName ="b菜单",order =0)]public class StudyUnity : ScriptableObject
{//可以在其中声明任何一种类型的变量,//如果想要在Inspector窗口中能够编辑它,那么//声明变量的规则应该与MonoBehavior的public变量规则相同public bool a;public float b;public GameObject c;public Material d;
}

这时我们回到unity可以看到

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

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class Study2
{[MenuItem("a/Tostudy")]//using UnityEditor;public static void ToStudy(){}
}

在此之后,回到unity中我们可以看到:

我们只需要在静态函数中数次额创建资源文件的代码即可

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class Study2
{[MenuItem("a/ToStudy")]//using UnityEditor;public static void ToStudy(){StudyUnity s=ScriptableObject.CreateInstance<StudyUnity>();//通过编译器API,可以根据数据创建一个数据资源文件AssetDatabase.CreateAsset(s, "Assets/Studt2data.asset");//在Assets路径下创建Studt2data.asset//保存创建的资源AssetDatabase.SaveAssets();//刷新界面AssetDatabase.Refresh();}
}

3.使用ScriptableObject的好处体现在哪里?

        可以更方便的配置数据,可以直接在Inspector中进行数据的配置

        可以在项目之间进行复用,可以拷贝继承ScriptableObject的脚本到任何工程之中

三、ScriptableObject数据文件

        1.ScriptableObject如何使用:

                通过Inspector窗口中的public变量进行关联:可以用上述方法创建数据文件,同时在继承MonoBehaviour类中申明数据容器类型的成员,最后在Inspector窗口中进行关联

                通过资源加载的信息关联:加载数据文件资源,需要注意的是,Resources\AB包、Addressables都支持加载继承ScriptableObject的数据文件(如果同时有多个对象关联同一个数据容器文件,他们贡献的是一个对象,因为是引用对象,所以在任何地方进行修改后,其他地方也会发生改变)

        2.ScriptableObject的生命周期函数

                类似于MonoBehavior,但是ScriptableObject的生命周期函数更少

                Awake 数据文件创建时调用

                OnDestroy对象将要被销毁时调用

                OnDisable对象销毁时,即将重新把加载脚本程序集时调用

                OnEnable创建或者加载对象时调用

                Onvalidate 编译器才会进行调用的生命周期函数,Unity在加载脚本或者Inspector窗口中更改值时调用

        3.使用的好处:

                通过代码修改对象中的内容后,会影响到数据文件,相当于达到了编译器中数据持久化的目的,注意该数据持久化,只会在编译模式下持久,发布运行时并不会保留数据;同时,如果多个对象关联了同一个数据文件,相当于他们服用了一组数据,更加节约内存

四、非持久数据

        1.非持久化数据指的是什么:不管是编辑器模式还是发布后都不会持久化的数据,我们可以根据需求随时创建对应数据对象进行使用,,如同直接new一个数据结构类对象一样

        2.如何利用ScriptableObject生成非持久化的数据:利用ScriptableObject中的静态方法CreateInstance<>(),该方法可以运行时创建出指定继承ScriptableObject的对象,且该对象只存在于内存当中,可以被GC,每调用一次便创建一次

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Study4 : MonoBehaviour
{public StudyUnity studyUnity;void Start(){//为了不想要数据持久化,不加载数据资源文件studyUnity = ScriptableObject.CreateInstance<StudyUnity>();studyUnity=ScriptableObject.CreateInstance("Studyunity") as StudyUnity;//创建出来的对象是一个基类对象,父类装子类,需要as//以上方式创建出来的对象,它的默认值不会受到脚本中设置的影响}//studyUnity = ScriptableObject.CreateInstance<StudyUnity>();//会发生报错}

        3.ScriptableObject非持久化数据存在的意义:

                如果希望在运行时能有一组唯一的数据可以使用,但是这个数据又不太希望保存为数据资源文件浪费空间,那么非持久化数据的好处便可以体现,其特点为:只是在运行时使用,在编辑器模式下也不会保存在本地(停止运行后,数据便会丢失)

五、如何让其拥有真正意义上的持久

        数据持久化本质上是读取硬盘上的内容到内存当中,需要的时候将内存当中的内容存储到硬盘上,游戏退出程序关闭后,数据信息就会被储存在硬盘上,达到持久化的目的

        持久化一般采用 PlayerPrefs/XML/Json/2进制的方式

        实际上ScriptableObject并不适合用来做数据持久化的功能,但我们可以利用学过的数据持久化方案令其持久化

        例如利用Json

                   存储数据:

studyData.i=10086;
studyData.f=8.8f;
studyData.b=false;string str=JsonUtility.ToJson(studyData);File.WriteAllText(Application.persistentDataPath+"/test.json",str);
//File需要引用命名空间

                   读取数据:

string str =File.ReadAllText(Application.persistentDataPath+"/test.json");
//反序列化数据文件

                   从本地读取Json字符串,根据json字符串反序列化出数据,将内容覆盖到数据对象之中

JsonUtility.FromJsonOverwrite(str,data);

             实际上,使用ScriptableObject来做持久化并非是好的选择,更有一种画蛇添足的意思

六、 使用ScriptableObject来配置数据

        为什么要使用ScriptableObject数据文件来作配置文件?

        配置文件的数据在游戏发布之前便已经定好了规则,配置数间的数据在游戏运行时只会读出来使用,并不会改变其内容。同时在untiy的Inspector窗口进行配置更加的方便(不需要使用第三方软件)

适用范围:只用不改,经常配置的数据,例如untiy内置的技能编译器,关卡编译器等(内置编译器只会在编译模式下进行,编译模式下ScriptableObject具备数据持久化的特性)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[CreateAssetMenu(fileName = "StudyInfo",menuName ="ScriptableObject/信息")]
public class StudyInfo : ScriptableObject
{//自定义类型想要可编辑,需要添加下行代码[System.Serializable]public class StudyData{public string Name;public string Description;}public List<StudyData> studyList;
}

之后回到unity,在窗口创建后,我们可以看到

        

想获取以此法创建出来的数据,可以在一个脚本中创建一个对应对象,将脚本挂载到物体上进行关联,便可以获取到对应数据

七、使用ScriptableObject来复用数据

        使用预设体可能存在内存浪费,例如创建一个子弹,其速度是相同的,但是在实际上子弹速度在每次创建时都要占用一定内存(只用不变的数据)

        对于不同的对象,使用相同的数据,可以使用ScriptableObject节约内存(即使游戏被发布,也是使用一块内存空间)

八、数据带来的多态性为

        某些行为的变化是因为数据的不同带来的,我们可以利用面向对象的特性和原则,以及设计模式的知识点,结合ScriptableObject做出更方便的功能,比如随机音效(利用里氏替换和依赖倒转原则),物品拾取和AI等

例如

        

public  abstract class AudioPlayBase : ScriptableObject
{public abstract void Play(AudioSource source);}

          

[CreateAssetMenu()]
public class RandomPlay : AudioPlayBase
{public List<AudioClip> clips;//随机播放的音效文件public override void Play(AudioSource source){if (clips.Count == 0) return;//设置音效切片文件source.clip = clips[Random.Range(0,clips.Count)];//进行播放source.Play();}}

九、单例模式化的数据获取

        对于只用不变并且要复用的数据,我们往往要在很多地方获取他们,如果我们直接在public关联或者动态加载。如果多处使用,会存在多处重复代码,开发效率较低。如果我们将此类数据通过但理论模式化的去获取,可以提升效率,减少代码量

        实现ScriptableObject数据单例模式基类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SingleScriptableObject<T>:ScriptableObject where T:ScriptableObject
{private static T instance;//数据基类,不能直接去newpublic static T Instance {get { if(instance == null){//如果为空,首先去资源路径下加载对应的数据资源文件instance=Resources.Load<T>("ScriptableObject/" + typeof(T).Name);//Load需要继承Object类,由于ScriptableObject已经继承过了//因此只需补充where T:ScriptableObject即可}//防止没有这个文件从而发生错误if(instance == null){instance = CreateInstance<T>();}//甚至可以在这里 从json当中读取数据return instance;}}}

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2775218.html

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

相关文章

二十多篇文献带你读懂分布式学习与联邦学习优化思路 调度优化 压缩算法 聚合算法

前言 文中增加了引用跳转&#xff0c;如果想要细度哪一篇文章&#xff0c;只需通过引用跳转到结尾的Reference便可以获得文章的标题&#xff0c;通过Google Scholar搜索便可以获取原文。 本文为作者原创&#xff0c;转载请注明作者kaiserqzyue。 摘要 联邦学习的提出是为了…

Spring GateWay

概述简介 能干什么 反向代理 鉴权 流量控制 熔断 日志监控 Spring Cloud Gateway 与Zuul的区别 在SpringCloud Finchley正式版之前&#xff0c;Spring Cloud推荐的网关是 Netflix提供的Zuul: 1、Zuul 1.x&#xff0c;是一个基于阻塞Ⅳ/O的APl Gateway 2、Zuul 1.x基于Servl…

stable_diffusion提示词编写笔记(1)

stable_diffusion提示词编写笔记(1) start 总结一下AI绘画学到的知识。 一.提示词分两种&#xff1a; 1.正向提示词&#xff1b; 2.反向提示词&#xff1b; 一个对应你希望图形包含的内容提示词&#xff0c;一个对应你不希望图形出现的内容提示词。 二.如何书写提示词 1.内…

6.0 Zookeeper session 基本原理详解教程

客户端与服务端之间的连接是基于 TCP 长连接&#xff0c;client 端连接 server 端默认的 2181 端口&#xff0c;也就 是 session 会话。 从第一次连接建立开始&#xff0c;客户端开始会话的生命周期&#xff0c;客户端向服务端的ping包请求&#xff0c;每个会话都可以设置一个…

类加载器的三种+双亲委派机制大概了解

类加载器有哪几种分别是加载哪些类的 类加载一共可以分为三种&#xff1a; 分别为&#xff1a; 启动类加载器&#xff08;Bootstrap Class Loader&#xff09;&#xff1a;负责加载Java的核心类库&#xff0c;如java.lang包中的类。扩展类加载器&#xff08;Extension Class …

桌面显示器应用Type-C接口有什么好处

随着科技的不断发展&#xff0c;桌面显示器作为我们日常工作中不可或缺的设备之一&#xff0c;也在不断更新换代。其中&#xff0c;Type-C接口的应用成为了桌面显示器发展的一个重要趋势。那么&#xff0c;桌面显示器应用Type-C接口究竟有什么好处呢&#xff1f; 首先&#xff…

Optimism Collective 为 Covalent Network(CQT)提供价值 20 万美元的生态系统资助

Covalent Network&#xff08;CQT&#xff09; 是 Web3 生态系统中关键的“数据可用性”层&#xff0c;在与 Optimism Collective 多年的合作中取得了骄人的成果。Covalent Network&#xff08;CQT&#xff09;对于 Optimism 跨链数据的增长产生了直接的影响&#xff0c;而这一…

一个 SpringBoot 项目能同时处理多少请求?

目录 1 问题分析 2 Demo 3 答案 4 怎么来的&#xff1f; 5 标准答案及影响参数一Tomcat配置 6 影响参数二 Web容器 7 影响参数三 Async 1 问题分析 一个 SpringBoot 项目能同时处理多少请求&#xff1f; 不知道你听到这个问题之后的第一反应是什么&#xff1f; 我大概…

2024年【天津市安全员B证】考试内容及天津市安全员B证模拟考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 天津市安全员B证考试内容参考答案及天津市安全员B证考试试题解析是安全生产模拟考试一点通题库老师及天津市安全员B证操作证已考过的学员汇总&#xff0c;相对有效帮助天津市安全员B证模拟考试题学员顺利通过考试。 1…

parse库,一个优雅的python库

前言 在Python中&#xff0c;format方法和f-strings是两种常用的字符串插值方法。 name "Haige" age "18" print(f"{name} is {age} years old.")# Haige is 18 years old.而如果是要从字符串中提取期望的值呢&#xff1f;相信很多人的第一或…

WordPress函数wptexturize的介绍及用法示例,字符串替换为HTML实体

在查看WordPress你好多莉插件时发现代码中使用了wptexturize()函数用来随机输出一句歌词&#xff0c;下面boke112百科就跟大家一起来学习一下WordPress函数wptexturize的介绍及用法示例。 WordPress函数wptexturize介绍 wptexturize( string $text, bool $reset false ): st…

如何用python进行数据分析?

前言 很多人可能会有这样的疑问&#xff0c;数据分析Excel挺强大的&#xff0c;会Excel就行&#xff0c;为什么还要去学python&#xff1f; 是的&#xff0c;Excel和python对于数据分析而言&#xff0c;这两者都只是不同的工具而已。 但&#xff0c;有一点我们要考虑&#x…

常见云计算服务模式( IaaS基础架构即服务、PaaS平台即服务、SaaS软件即服务)

常见云计算服务模式 &#xff08; IaaS基础架构即服务、PaaS平台即服务、SaaS软件即服务&#xff09; 零、00时光宝盒 世界并不完美&#xff0c;面对很多事情我们都很无奈甚至悲哀&#xff0c;但生活总要继续下去&#xff0c;不止是为了自己。抱怨没有用&#xff0c;顾影自怜也…

VPP学习-VPP初始化流程

概念 VPP作为一个开源的、高性能的用户态网络协议栈&#xff0c;以进程的形式运行于Linux或&#xff08;类unix&#xff09;系统下&#xff0c;即VPP实际是一个用户进程&#xff0c;VPP启动后可通过"ps -ef | grep vpp"命令查看。 VPP启动 用户态进程启动都有一个ma…

【网络】:序列化和反序列化

序列化和反序列化 一.json库 二.简单使用json库 前面已经讲过TCP和UDP&#xff0c;也写过代码能够进行双方的通信了&#xff0c;那么有没有可能这种通信是不安全的呢&#xff1f;如果直接通信&#xff0c;可能会被底层捕捉&#xff1b;可能由于网络问题&#xff0c;一方只接收到…

分享88个行业PPT,总有一款适合您

分享88个行业PPT&#xff0c;总有一款适合您 88个行业PPT下载链接&#xff1a;https://pan.baidu.com/s/1BBvTepkj_BHq0rjtJ-lgLQ?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易…

【华为云】云上两地三中心实践实操

写在前面 应用上云之后&#xff0c;如何进行数据可靠性以及业务连续性的保障是非常关键的&#xff0c;通过华为云云上两地三中心方案了解相关方案认证地址&#xff1a;https://connect.huaweicloud.com/courses/learn/course-v1:HuaweiXCBUCNXI057Self-paced/about当前内容为华…

高级数据结构与算法 | 布谷鸟过滤器(Cuckoo Filter):原理、实现、LSM Tree 优化

文章目录 Cuckoo Filter基本介绍布隆过滤器局限变体 布谷鸟哈希布谷鸟过滤器 实现数据结构优化项Victim Cache备用位置计算半排序桶 插入查找删除 应用场景&#xff1a;LSM 优化 Cuckoo Filter 基本介绍 如果对布隆过滤器不太了解&#xff0c;可以看看往期博客&#xff1a;海量…

【QT+QGIS跨平台编译】之三十一:【FreeXL+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、FreeXL介绍二、文件下载三、文件分析四、pro文件五、编译实践一、FreeXL介绍 【FreeXL跨平台编译】:Windows环境下编译成果(支撑QGIS跨平台编译,以及二次研发) 【FreeXL跨平台编译】:Linux环境下编译成果(支撑QGIS跨平台编译,以及二次研发) 【FreeXL跨平台…

【驱动】块设备驱动(二)-通用块层

前言 通用块层是一个内核组件&#xff0c;处理来自系统其他组件发出的块设备请求。换句话说&#xff0c;通用块层包含了块设备操作的一些通用函数和数据结构&#xff0c;如通用磁盘结构gendisk&#xff0c;请求队列结构request_queue、请求结构request、块设备I/O操作结构bio和…