官方是这么介绍ScriptabelObject的:

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

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

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

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

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


但是在实际项目中,如果遇到需要配置很多个同类型ScriptableObject对象,但是ScriptableObject具体数据不同的情况下,如果全部保存成单个文件,看下来会比较乱。

于是我们可以把归属于同一个模块的ScriptabelObject放入同一个大的模块下,在后期查找修改也比较方便。

1.想要获得上方的效果,首先我们需要一个最外层ScriptabelObject对象

using System.Collections;
using System.Collections.Generic;
using UnityEngine; [CreateAssetMenu(fileName = "ItemTemplate", menuName = "Custom/ItemTemplate")]
public class ItemTemplate : ScriptableObject
{
public List<SubItemTemplate> subItems = new List<SubItemTemplate>();
}

通过这个类,我们可以点击菜单栏的Assets→Creat→Custem→ItemTemplate创建一个ScriptabelObject对象。

2.最外层ScriptabelObject需要包含若干子对象,具备一个折叠效果

using System.Collections;
using UnityEngine; [CreateAssetMenu(fileName = "SubItem", menuName = "Custom/SubItem")]
public class SubItemTemplate : ScriptableObject
{ public int ID; }

  

3.需要自己定义一个Editor编辑器拓展,使得在Inspector界面上具备一定的功能。

using UnityEditor;
using UnityEngine; [CustomEditor(typeof(ItemTemplate))]
public class ItemTemplateEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI(); GUILayout.Space(10); ItemTemplate mainObject = (ItemTemplate)target; if (GUILayout.Button("Add Child Object"))
{
SubItemTemplate childObject = ScriptableObject.CreateInstance<SubItemTemplate>();
childObject.name = "SubItem"; Undo.RegisterCreatedObjectUndo(childObject, "Create Child Object"); AssetDatabase.AddObjectToAsset(childObject, mainObject);
AssetDatabase.SaveAssets(); mainObject.subItems.Add(childObject);
EditorUtility.SetDirty(mainObject);
} GUILayout.Space(10); if (GUILayout.Button("Remove All Child Objects"))
{
foreach (SubItemTemplate childObject in mainObject.subItems)
{
AssetDatabase.RemoveObjectFromAsset(childObject);
DestroyImmediate(childObject, true);
} mainObject.subItems.Clear();
AssetDatabase.SaveAssets(); EditorUtility.SetDirty(mainObject);
}
}
}

【Unity】 ScriptableObject ——生成多个ScriptableObject作为子对象,可以点击展开并显示二级菜单的更多相关文章

  1. Unity编辑器扩展 Chapter7--使用ScriptableObject持久化存储数据

    Unity编辑器扩展 Chapter7--使用ScriptableObject持久化存储数据 unity unity Editor ScirptableObject  Unity编辑器扩展 Chapt ...

  2. Unity 自动生成组件索引类工具

    Unity 自动生成组件索引类工具 需求由来 我们在写UI类时 需要获取预设中的组件 joystick = transform.Find("joystick"); backgrou ...

  3. Unity 梯子生成算法

    Unity之生成梯子算法的实现. 1.通过预制物体动态生成角度可设置的梯子形状. 1.1 主要涉及到的数学知识点,角度与弧度的转化. 弧度=角度乘以π后再除以180 角度=弧度除以π再乘以180 1. ...

  4. Unity之生成扫描二维码

    Unity之生成扫描二维码 Unity之生成扫描二维码 前言 开篇 Unity版本及使用插件 正题 前期准备 首先生成二维码 然后需要扫描二维码 该使用了 挂载脚本绑定按钮和输入框 运行内容 生成二维 ...

  5. unity, unity默认的Arial字体在编译出的h5版本中不显示

    unity默认的Arial字体在编译出的h5版本中不显示.改用自己的字体可显示.

  6. 巨蟒django之权限7:动态生成一级&&二级菜单

    内容回顾: . 权限的控制 . 表结构设计 存权限的信息 用户表 - name 用户名 - pwd 密码 - roles 多对多 角色表 - name - permissions 多对多 权限表 - ...

  7. (五)Unity插件生成

    1)新建空的AndroidStudio工程,但是新建过程时最小SDK版本要与unity一致,如下图所示,本次操作均为api16 2)创建Library,如下图所示,新建module,然后选择Andro ...

  8. unity,生成的mac版游戏切场景时卡死解法

    unity版本为5.1.1,在编辑器里运行没问题,build出的windows版运行也没问题,但build出的mac版在个别场景切换时会卡死,通过查看log(查看build版本log的方法参考:htt ...

  9. unity 3d 生成apk文件时,设置图标

    如图所示:注意红线标注部分: 如果安装到手机之后,程序的图标还是unity的默认图标,重启手机即可.

  10. Unity自动生成AnimatorController

    上一篇写了如何自动切割动画,这一篇写如何自动生成AnimatorController. 之前网上查了很多资料,看的一直很蒙,看不懂是怎么回事的,这里我先给大家明确几个概念: 画的不好,大家将就着看,写 ...

随机推荐

  1. Win32编程

    WIN32 malloc函数的底层实现是Win32API 字符编码 原始的ASCII编码最多能表示127个符号 0-7F(十六进制) 缺点:表示的符号太少了 ASCII编码的扩展:GB2312或GB2 ...

  2. 2021-11-30 wpf的mvvm绑定2

    主页页面代码 <Grid> <TextBox x:Name="First" Width="80" Height="20" ...

  3. Mysql高级4-索引的使用规则

    一.最左前缀法则 如果索引了多列(联合索引),要遵守最左前缀法则.最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列,如果跳跃某一列,索引将部分失效(后面的字段索引失效) 示例1:acco ...

  4. QMainWindow类中比较重要的方法

    方法和描述 addToolBar():添加工具栏 centralWidget():返回窗口中心的一个空间,未设置时返回NULL menuBar(): 返回主窗口的菜单栏 setCentralWidge ...

  5. vue vue-simple-uploader 前端的简单使用

    前言 因为项目需要上传大文件tif图,考虑使用分片上传. 1.安装 npm install vue-simple-uploader --save 2.main.js中初始化 import upload ...

  6. c++算法之离散化例题

    离散化基础2 题目描述 给定 n 个元素的数列,将相同的数据离散化为一个数据(去重),即把 {4000,201,11,45,11}{4000,201,11,45,11} 离散化为 {4,3,1,2,1 ...

  7. Linux第四章(80X86保护模式及其编程)

    80X86保护模式及其编程 80X86基础知识 保护模式内存管理 各种保护措施 中断和异常处理 任务管理 保护模式编程的初始化 一个简单的多任务内核 4.1 80X86系统寄存器和系统指令 为了协助处 ...

  8. 9、Mybatis之动态SQL

    9.1.环境搭建 9.1.1.创建新module 创建名为mybatis_dynamicSQL的新module,过程参考5.1节 9.1.2.创建Emp实体类 package org.rain.myb ...

  9. 《SQL与数据库基础》23. 读写分离

    目录 读写分离 一主一从 准备 配置 双主双从 准备 配置 主库配置 从库配置 从库关联主库 主库相互复制 双主双从读写分离 本文以 MySQL 为例.以 MyCat 数据库中间件为例,通过 MyCa ...

  10. 京东获得JD商品详情 API 返回值说明

    ​ item_get-获得JD商品详情  API测试 onebound.jd.item_get 公共参数 名称 类型 必须 描述 key String 是 调用key(必须以GET方式拼接在URL中) ...