【Unity】 ScriptableObject ——生成多个ScriptableObject作为子对象,可以点击展开并显示二级菜单
官方是这么介绍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作为子对象,可以点击展开并显示二级菜单的更多相关文章
- Unity编辑器扩展 Chapter7--使用ScriptableObject持久化存储数据
Unity编辑器扩展 Chapter7--使用ScriptableObject持久化存储数据 unity unity Editor ScirptableObject Unity编辑器扩展 Chapt ...
- Unity 自动生成组件索引类工具
Unity 自动生成组件索引类工具 需求由来 我们在写UI类时 需要获取预设中的组件 joystick = transform.Find("joystick"); backgrou ...
- Unity 梯子生成算法
Unity之生成梯子算法的实现. 1.通过预制物体动态生成角度可设置的梯子形状. 1.1 主要涉及到的数学知识点,角度与弧度的转化. 弧度=角度乘以π后再除以180 角度=弧度除以π再乘以180 1. ...
- Unity之生成扫描二维码
Unity之生成扫描二维码 Unity之生成扫描二维码 前言 开篇 Unity版本及使用插件 正题 前期准备 首先生成二维码 然后需要扫描二维码 该使用了 挂载脚本绑定按钮和输入框 运行内容 生成二维 ...
- unity, unity默认的Arial字体在编译出的h5版本中不显示
unity默认的Arial字体在编译出的h5版本中不显示.改用自己的字体可显示.
- 巨蟒django之权限7:动态生成一级&&二级菜单
内容回顾: . 权限的控制 . 表结构设计 存权限的信息 用户表 - name 用户名 - pwd 密码 - roles 多对多 角色表 - name - permissions 多对多 权限表 - ...
- (五)Unity插件生成
1)新建空的AndroidStudio工程,但是新建过程时最小SDK版本要与unity一致,如下图所示,本次操作均为api16 2)创建Library,如下图所示,新建module,然后选择Andro ...
- unity,生成的mac版游戏切场景时卡死解法
unity版本为5.1.1,在编辑器里运行没问题,build出的windows版运行也没问题,但build出的mac版在个别场景切换时会卡死,通过查看log(查看build版本log的方法参考:htt ...
- unity 3d 生成apk文件时,设置图标
如图所示:注意红线标注部分: 如果安装到手机之后,程序的图标还是unity的默认图标,重启手机即可.
- Unity自动生成AnimatorController
上一篇写了如何自动切割动画,这一篇写如何自动生成AnimatorController. 之前网上查了很多资料,看的一直很蒙,看不懂是怎么回事的,这里我先给大家明确几个概念: 画的不好,大家将就着看,写 ...
随机推荐
- 一步一图带你构建 Linux 页表体系 —— 详解虚拟内存如何与物理内存进行映射
笔者之前在自己的专栏<聊聊 Linux 内核> 里通过大量的篇幅写了一个系列关于内存管理相关的文章,在这个系列文章中,笔者分别通过虚拟内存管理和物理内存管理两个角度算是把 Linux 内存 ...
- echarts-for-react:实时更新数据
解决方案 echarts 注解 详细链接 https://echarts.apache.org/zh/api.html#echartsInstance.setOption 参考链接 https://b ...
- node.js中kafka的封装和高并发消费限流优雅降级以及egg-kafka的封装说明
HI!,你好,我是zane,zanePerfor是一款我开发的一个前端性能监控平台,现在支持web浏览器端和微信小程序端. 我定义为一款完整,高性能,高可用的前端性能监控系统,这是未来会达到的目的,现 ...
- Unity的BuildPlayerProcessor:深入解析与实用案例
Unity BuildPlayerProcessor Unity BuildPlayerProcessor是Unity引擎中的一个非常有用的功能,它可以让开发者在构建项目时自动执行一些操作.这个功能可 ...
- nodejs中如何使用http创建一个服务
http模块是nodejs中非常重要的一部分,用于开启一个服务,我们可以用它自定义接口供客户端使用. 开启服务的方式也比较简单,几行代码就可以搞定 const http = require('ht ...
- 小白整理了VUEX
在小白开发的项目中前端使用的是Vue,虽然在日常工作中可以使用Vue进行开发工作.但是没有系统的学习过Vue,对Vue的一些特性和方法使用时常常需要查询资料解决问题,查询资料常常会占用大量时间,尤其对 ...
- 文心一言 VS 讯飞星火 VS chatgpt (84)-- 算法导论8.2 1题
一.用go语言,参照图8-2 的方法,说明 COUNTING-SORT 在数组 A=(6,0,2,0,1,3,4,6,1,3,2)上的操作过程. 文心一言: Counting Sort 是一种非比较型 ...
- 以程序员为视角,关于商品详情API接口的说明
商品详情API接口是现代电商平台中非常重要的一部分,它提供了获取淘宝商品详细信息的能力.作为一个程序员,了解如何调用这个API接口是非常关键的. 首先,我们需要明确的是,API接口是应用程序与服务 ...
- 微信小程序隐私保护协议修改方法 uniapp
微信隐私保护协议指南 一天天没事闲的 01 在manifest.json 中添加一行 "__usePrivacyCheck__" : false 02 自定义一个弹窗组件 ...
- mybatis数据库字段自动填充
背景描述 目前,大多数项目的数据库设计,都会添加一些公共字段,比如version(版本号).deleted(逻辑删除标识).create_time.update_time.create_by.upda ...