Unity开发利器:ScriptableObject的数据容器设计与内存优化原理

系列文章目录

unity知识点


文章目录


👉前言

ScriptableObject核心特性与应用

  1. 数据独立性‌:作为资源文件(.asset)存储,不依赖GameObject或场景。‌
  2. ‌内存优化‌:通过单一数据源引用,避免预制体实例化时的重复内存占用(如敌人属性配置)。‌
  3. 编辑器集成‌:支持在Unity编辑器中直接创建和修改数据,实现非代码驱动的资源配置。‌

博客将会介绍ScriptableObject的数据容器设计与内存优化原理。希望这篇博客对Unity的开发者有所帮助。

大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

欢迎点赞评论哦.下面就让我们进入正文吧 !


提示:以下是本篇文章正文内容,下面案例可供参考

👉一、ScriptableObject是什么?

ScriptableObject 是一个可独立于类实例来保存大量数据的数据容器。ScriptableObject 的一个主要用例是通过避免重复值来减少项目的内存使用量。如果项目有一个预制件在附加的 MonoBehaviour 脚本中存储不变的数据,这将非常有用。

每次实例化预制件时,都会产生单独的数据副本。这种情况下可以不使用该方法并且不存储重复数据,而是使用 ScriptableObject 来存储数据,然后通过所有预制件的引用访问数据。这意味着内存中只有一个数据副本。

就像 MonoBehaviour 一样,ScriptableObject 派生自基本 Unity 对象,但与 MonoBehaviour 不同,不能将 ScriptableObject 附加到游戏对象。正确的做法是需要将它们保存为项目中的资源。

如果使用 Editor,可以在编辑时和运行时将数据保存到 ScriptableObject,因为 ScriptableObject 使用 Editor 命名空间和 Editor 脚本。但是,在已部署的构建中,不能使用 ScriptableObject 来保存数据,但可以使用在开发期间设置的 ScriptableObject 资源中保存的数据。

从 Editor 工具作为资源保存到 ScriptableObject 的数据将写入磁盘,因此将在会话之间一直保留。

👉二、使用 ScriptableObject

ScriptableObjects 的主要用例为:

  • 在 Editor 会话期间保存和存储数据
  • 将数据保存为项目中的资源,以便在运行时使用
    要使用 ScriptableObject,必须在应用程序的 Assets 文件夹中创建一个脚本,并使其继承自 ScriptableObject 类。您可以使用 CreateAssetMenu 属性,从而使用您的类轻松创建自定义资源。

如下代码所示:

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu (fileName = "ItemDatas",menuName = "Settings/ItemDatas")]
public class ItemDatas : ScriptableObject
{
    public string itemName;
    public Sprite icon;

    [TextArea] public string description;


    public int maxSize = 1;
    public float weight = 0.1f;


    public GameObject prefab;


    [Header("速度")]
    public int speed;


}

第二步就是创建ScriptableObject 的实例

在Project页面右键选择生成Create/Settings/ItemDatas

生成之后可以重新起名字,也可以默认名字,生成之后的如下图

第三步使用脚本如下:

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CreateModelss : MonoBehaviour
{
    public ItemDatas modelPrefabs;
   

    // Start is called before the first frame update
    void Start()
    {
        GameObject sdasd = Instantiate(modelPrefabs.prefab, this.transform);
    }

}

第四步,把资源拖入脚本中如下图

最后运行就可以看到模型生成出来了。

👉三、解析ScriptableObject的生命周期函数

ScriptableObject和MonoBehavior很类似

它也存在生命周期函数

但是生命周期函数的数量不多

主要了解,一般我们使用较少

csharp 复制代码
 /// <summary>
    /// 数据文件创建时调用
    /// </summary>
    private void Awake()
    {
        
    }
    /// <summary>
    /// 创建或者加载对象时调用
    /// </summary>
    private void OnEnable()
    {
        
    }
    /// <summary>
    /// 对象销毁时、即将重新加载脚本程序集时 调用
    /// </summary>
    private void OnDisable()
    {
        
    }
    /// <summary>
    /// 对象将被销毁时调用
    /// </summary>
    private void OnDestroy()
    {
        
    }
    /// <summary>
    /// 编辑器才会调用的函数,Unity在加载脚本或者Inspector窗口中更改值时调用
    /// </summary>
    private void OnValidate()
    {
        
    }

👉四、ScriptableObject好处的体现

编辑器中的数据持久化

通过代码修改数据对象中内容,会影响数据文件

相当于达到了编辑器中数据持久化的目的

(该数据持久化 只是在编辑模式下的持久,发布运行时并不会保存数据)
复用数据

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

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

ScriptableObject数据文件为什么非常适合用来做配置文件?

  • 配置文件的数据在游戏发布之前定规则
  • .配置文件的数据在游戏运行时只会读出来使用,不会改变内容
  • 在Unity的Inspector窗口进行配置更加的方便

代码设置一下速度参数,对比没运行之前

运行之后显示,取消运行之后也不会变化


👉壁纸分享

👉总结

ScriptableObject的本质

ScriptableObject是Unity引擎中的一个特殊基类,允许你创建不依附于游戏对象的数据容器,以资产(Asset)形式存储在项目中。这些资产:

  • 可在编辑器中创建和配置
  • 在构建后作为资产打包
  • 可通过Resources或AssetBundle加载
  • 不需要实例化即可访问其数据

ScriptableObject在内存管理上与MonoBehaviour根本不同 - 它们不绑定到场景层次结构,而是作为独立资产存在。

本次总结的就是 ScriptableObject的数据容器设计与内存优化原理, 有需要会继续增加功能

如能帮助到你,就帮忙点个赞吧,三连更好哦,谢谢

你的点赞就是对博主的支持,有问题记得留言评论哦!

不定时更新Unity开发技巧,觉得有用记得一键三连哦。么么哒!

相关推荐
.NET修仙日记4 小时前
.NET WinForms + WPF 综合学习路线:从传统到现代的.NET桌面开发
学习·c#·.net·wpf·.net core·winforms
至善迎风4 小时前
将跨平台框架或游戏引擎开发的 Windows 应用上架 Microsoft Store
windows·microsoft·游戏引擎
worxfr4 小时前
小游戏引擎架构设计案例分析
游戏引擎
WangMing_X4 小时前
C#上位机软件:2.5 体验CLR实现多语言混合编程
java·开发语言·c#
唐青枫7 小时前
C#.NET Configuration 全面解析:从多环境到强类型绑定实战
c#·.net
YuanlongWang11 小时前
C# 基础——装箱和拆箱
java·开发语言·c#
Cool-浩17 小时前
【征文计划】Rokid 语音指令开发教程 【包含工程源码 和体验包APK】
unity·ar·语音识别·rokid·语音指令
QQ129584550417 小时前
C# 如何能够创建一个MVC的WEB项目
c#·mvc
星河队长19 小时前
VS创建C++动态库和C#访问过程
java·c++·c#