官方是这么介绍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. Redis解决网络抖动问题

    Redis解决网络抖动问题 所谓网络抖动问题, 简单来说就是防止用户短暂的时间内对同一个接口多次点击访问 这里利用的是redis锁的原子性和with Statement上下文管理器实现, 另外该类还支 ...

  2. Nextcloud允许不被信任的域访问 取消 trusted domains

    在服务器部署了Nextcloud,由于测试需要,经常从不同的地址访问,但是每次访问都要把域名添加到受信任域,反反复复修改也挺麻烦,暂时又没找到通配符或者禁用的方法. 不过网上提供了一个替代方法,动态生 ...

  3. 解决: better-scroll.esm.js?f40f:180 [BScroll warn]: EventEmitter has used unknown event type: "pullingUp"

    改为这样,把所有值设为true mounted() { // 滚动条 this.scroll = new BScroll(this.$refs.wrapper, { click: true, obse ...

  4. JSONP前端流程

    JSONP前端流程 JSONP总体思路 后端先给前端一个接口文档. 如https://www.baidu.com/sugrec?prod=pc&wd=用户输入的文字&cb=后端要调用的 ...

  5. 十 Appium环境搭建(Windows版)

    注:appium安装到C盘,node.js安装到C盘 一.安装node.js 1.到官网下载node.js:https://nodejs.org/en/download/ 2.获取到安装文件后,直接双 ...

  6. cesium中文网

    http://cesium.xin/cesium/cn/Documentation1.62/CallbackProperty.html

  7. 修改启动配置文件更改root密码

    第二种:修改启动配置文件 (1)进入救援模式 开机选择第一个系统内核,键入e (2)修改配置文件 将光标移动linux 开始的行,添加内核参数 rd.break 按ctrl-x启动 光标放在linux ...

  8. 使用 Rancher 安装 K8s 集群

    舞台环境 Ubuntu 22.04.2 LTS Docker 24.0.2 2GB RAM或者更多 CPU 2核心或者更多 Rancher 2.6.9 测试环境中,我准备了两台 Ubuntu 服务器, ...

  9. QEMU tap数据接收流程

    QEMU直接从tap/tun取数据 QEMU tap数据接收步骤: qemu从tun取数据包 qemu将数据包放入virtio硬件网卡. qemu触发中断. 虚拟机收到中断,从virtio读取数据. ...

  10. 如何将项目打包上传到NuGet服务器?

    作者:西瓜程序猿 主页传送门:https://www.cnblogs.com/kimiliucn 前言 在我写[在.NET Framework中使用RocketMQ(阿里云版)]这篇博客的时候,因为封 ...