Unity ScriptableObject 使用方法详解

这篇具有很好参考价值的文章主要介绍了Unity ScriptableObject 使用方法详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述:

ScriptableObject类直接继承自Object类;它和MonoBehaviour是并列的,都继承自Object(但MonoBehaviour并不是直接继承自Object);

ScriptableObject 就是一个数据容器,可以用来存储大量的数据,它是可序列化的,这个特点也正决定了它的主要用途;一个主要用处就是通过将数据存储在ScriptableObject对象中来减少工程以及游戏运行时因拷贝值所造成的内存占用;

ScriptableObject与预制体:
当你有一个预制体,它附加了一些mono脚本,包含了一些数据,每次我们实例化预制体的时候它都会 拷贝 assets下原预制体的值生成一份自己的拷贝,然后我们可以修改场景内预制体的值而并不影响assets下预制体的值,这是prefab的特性,对于我们从一个prefab模板生成属性不同的游戏对象是很有用的,但是如果prefab里的脚本数据是不需要修改的,它就会造成很大的资源浪费,尤其在数据很多的时候;为了避免这种问题,我们可以在不需要修改prefab里的脚本数据时,考虑使用ScriptableObject来存储这些重复的数据,然后其它所有预制体都可以使用引用的方式来访问这份数据,这就意味着不管场景中实例了多少预制体,在内存中就只需要有一份数据;它所带给我们的启示就是,当预制体中的脚本里有大量重复数据时,我们要想着将数据抽离,单独保存在本地;

举一个子弹的例子:

1、我们要先做一个子弹的预制体,为了体现它的属性,我们会写一个派生自MonoBehaviour的脚本Bullet,在里面添加一些属性,然后将其附加到一个子弹游戏对象上,完成了一个子弹预制体的制作;
2、在场景中实例化新的子弹的时候,这个实例也会有一个Bullet实例,而且最重要的是这些子弹都会有这样一份Bullet而且它们的数据是相同的,这就是之前讲到的因为拷贝值产生新的实例导致了大量的内存占用;
3、我们这个时候我们就可以把这个派生自MonoBehaviour的脚本里的数据放置在派生自ScriptableObject的脚本,然后就可以在创建Assets下创建一份数据文件,设置完数据后,在Bullet中我们就定义一个指向ScriptableOjbect对象的引用,这样它就由原来的拷贝大量值并存储重复的值变成了拷贝一个引用并存储一个引用;

应用场景及方式
当使用编辑器运行游戏的时候,可以将数据保存到ScriptableObject里(当创建一个脚本化对象实例后使用AssetDatabase.CreateAsset()保存该资源),退出之后也不会丢失,因为它是作为Assets下的资源存在的;它是仅在编辑器中才可以保存修改的数据(因为ScriptableObject对象虽然声明在UnityEngine中,但是它的Scriptable是通过UnityEditor命名空间下的类例如Editor类等来实现的),所以在部署构建的时候不可以用于存储游戏运行时更改的数据,但是可以使用之前存储好的数据,也就是ScriptableObject生成的数据资源文件在Editor外具有只读属性,这是非常需要注意的一点,如果你需要在游戏中修改数据并存储下来,就不推荐使用ScriptableObject了;

总结:
它就是用来在编辑器模式下保存和存储数据到本地Assets下的,数据保存以后是可以共享的,就像纹理、shader等资源一样,是可以共享于当前整个工程和其它工程的;这个ScriptableObject在真机上不可修改的,就像我们不可以在游戏运行时修改一个shader资源的代码、不可以修改一个纹理资源的像素内容一样,而在Unity Editor里可以修改ScriptableObject是因为Unity的编辑器对它格式的支持,就像使用vs code修改shader和使用ps修改一张纹理一样;

ScriptableObject的特点

  • ScriptableObject 数据存储在 asset 资源文件中,类似 unity 材质或纹理资源
  • ScriptableObject 资源在实例化时是被引用,而非像 Prefab 或其他 GameObject 一样是复制(实际场景中会存在多个 GameObject),所有 ScriptableObject 可以节省 memory

基本使用

using UnityEngine;

[CreateAssetMenu(menuName="MySubMenue/Create ScritableTest")]
public class ScritableTest: ScriptableObject
{
    public int someVariable;
}

其中,[CreateAssetMenu(menuName="MySubMenue/Create MyScriptableObject ")]可以让我们在资源创建菜单中添加创建这个ScriptableObject的选项,类似创建脚本、材质等其他资源。

我们也可以在脚本中动态创建一个ScriptableObject:

ScriptableObject.CreateInstance<ScritableTest>();

这会在内存中创建一个新的实例,用作临时修改等用途,然后在不使用的时候可以让GC回收。其中MyScriptableObject 是自定义的类型,并继承于ScriptableObject

保存创建的数据:

  var test = ScriptableObject.CreateInstance<ScritableTest>();
  Debug.Log(test.someVariable);

  string fullPath = "Assets/TestData.asset";
  AssetDatabase.CreateAsset(test, fullPath);
  AssetDatabase.Refresh();

Unity ScriptableObject 使用方法详解
加载数据
可以将保存的文件放在Resources文件夹中,然后使用Resources.LoadAll去加载,当然还有很多其他加载方式。文章来源地址https://www.toymoban.com/news/detail-474016.html

 var preferencesFiles = Resources.LoadAll<ScritableTest>("TestData");
   if(preferencesFiles.Length == 0)
   {
       Debug.Log("null");
   }
   else
   {
       Debug.Log(preferencesFiles[0].someVariable);
   }

到了这里,关于Unity ScriptableObject 使用方法详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [005] [蓝桥杯物联网] LoRa模块通信原理概述与API使用方法

    MCU型号: STM32L071KBU SDK:HAL库 工具:CubeMX + MDK LoRa ( Long Range , 远距离)模块收发器型号为 SX1278 ,可以完成 点对点 的数据通信功能,属于 半双工 通信,其原理图与引脚描述如下图所示: ▲ Lora模块原理图 ▲ Lora模块引脚描述 Lora竞赛板中引出了以下引脚: PA5~7:一般配置为

    2023年04月16日
    浏览(20)
  • unity NGUI使用方法

    很多基本模块比如按钮、slider等都能从Prefab中直接拖拽到场景中实现,但都需要有一个Collider(Prefab已经自带) 因为不仅是UI,所有带有Collider的游戏物体都能接收到OnClick, OnPress这样的事件——前提是需要在Main Camera里面添加上event System组件,然后自定义脚本添加以下函数:

    2024年02月05日
    浏览(25)
  • Unity——触摸方法的使用

            首先在start()中开启触摸方法的使用:         然后在每一帧中对触摸方式进行判断:

    2024年01月16日
    浏览(26)
  • Unity中常用函数使用方法

    Update() 正常更新,创建 JavaScript 脚本时默认添加这个方法,每一帧都会由系统调用一次该方法。 LateUpdate() 推迟更新,此方法在 Update() 方法执行完后调用,每一帧都调用一次。 FixedUpdate() 置于这个函数中的代码每隔一定时间执行一次。 Awake() 脚本唤醒,用于脚本的初始化,在

    2024年02月08日
    浏览(18)
  • unity 2D射线的使用方法

    Ray2D ray;     void Update()     {         ray = new Ray2D(transform.position, Vector2.right);         RaycastHit2D info = Physics2D.Raycast(ray.origin, ray.direction,10);         //Debug.DrawRay(ray.origin,ray.direction,Color.blue);         if (info.collider != null)         {             if (info.transform.gameO

    2024年02月15日
    浏览(25)
  • Unity——各种特效的基本使用方法

    特效是游戏制作不可或缺的一环,作为游戏开发者最重要的工作就是将特效添加到游戏中,并在合适的时机、合适的位置将特效播放出来,同时还要注意特效的管理和销毁。 某些种类的特效,如动效、贴花,还要编写脚本代码以实现更细节的控制。因此本文将简单介绍各种特

    2024年02月08日
    浏览(19)
  • Unity——DOTween插件使用方法简介

      缓动动画既是一种编程技术,也是一种动画的设计思路。从设计角度来看,可以有以下描述 事先设计很多基本的动画样式,如移动、缩放、旋转、变色和弹跳等。但这些动画都以抽象方式表示,一般封装为程序函数 动画的参数可以在使用时指定,如移动的起点和终点、旋

    2024年02月05日
    浏览(27)
  • Unity Render Streaming使用方法,WebRTC的基础搭建使用

    Unity渲染流包含构建在Unity Render Streaming之上的公共 API 和项目示例。可以使用Unity Render Streaming包快速开发一个点对点的流媒体解决方案。 该软件包提供的功能包括视频流、音频流和操作控制。 Render Streaming所需环境:WebRTC,nodejs, 我们先安装WebRTC 参考链接:Install package | W

    2024年02月15日
    浏览(18)
  • unity,Mathf.Clamp方法的使用

    Mathf.Clamp是Unity引擎中的一个静态方法,用于将一个值限制在指定的范围内。它可以用于限制数值、位置和旋转等属性的取值范围,以确保它们不会超出指定的范围。 Mathf.Clamp方法的语法如下: 其中,value表示要限制的值,min表示限制范围的最小值,max表示限制范围的最大值。

    2024年02月07日
    浏览(24)
  • Unity中的Vector2的使用方法

    (1).判断两个向量是否相等(Equals) (2).设置Vector2的值 a. transform.position不可以单独赋值,需要整体赋值 通过查看底层代码可以看到Transform中的position是属性而不是公有字段 position的类型是Vector3,而Vector3是struct结构体 结论1:用属性和方法返回的结构体是不能修改其字段的 结论2:

    2024年02月08日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包