用途
ScriptableObject 是 Unity 中存在于场景层级之外的数据容器,适合用于配置、共享数据以及解耦系统。本技能围绕这一机制,整理了数据管理、配置和运行时系统的常见模式。
主要能力
数据定义
通过 [CreateAssetMenu] 创建资产,可定义物品等数据,包含基础信息、属性、玩法字段,并提供基于 Resources.LoadAll 的运行时查找优化。
数据库模式
ItemDatabase 以列表持有多个定义,初始化时构建字典查找,支持按稀有度筛选,并可在编辑器下通过 ContextMenu 自动收集所有定义资产。
运行时数据
- 共享运行时值:
RuntimeInt提供初始值与运行时值分离,支持OnValueChanged事件,并在OnEnable中重置初始化状态。 - 可观察集合:
RuntimeList<T>提供添加、移除、清空操作及对应事件,OnEnable时重建列表。
事件系统
GameEvent:基于监听者列表的简单事件,支持注册、注销与触发,遍历时倒序以保证安全移除。- 类型化事件:
GameEvent<T>抽象基类配合IGameEventListener<T>接口,可派生IntEvent、StringEvent等具体事件。
配置
- 游戏设置:
GameSettings集中管理玩法、音频、图形参数,并提供基于Resources.Load的单例访问。 - 平台配置:
PlatformConfig按平台(iOS、Android、桌面)返回对应设置,使用条件编译区分。
校验
- 编辑器校验:
ValidatedScriptableObject在OnValidate中调用校验逻辑,子类可重写GetValidationErrors返回错误信息。 - ID 唯一性检查:通过
DidReloadScripts回调扫描指定类型资产,检测重复 ID 并输出错误。
使用方式
在 Unity 项目中按需引入上述模式:使用 CreateAssetMenu 创建资产,在 OnEnable 中初始化运行时状态,集合类数据使用数据库模式,编辑器下通过 OnValidate 进行校验,并保持 ID 唯一。
适用场景
- 游戏配置与设置
- 物品、技能、角色定义
- 共享运行时数据
- 事件系统
- 依赖注入的替代方案
限制与注意事项
- 运行时状态需在
OnEnable中重置,因为 ScriptableObject 在编辑器中会持久化。 - 避免在 SO 中引用场景对象。
- 谨慎使用
Resources.Load,优先考虑 Addressables。 - 大型 SO 可能拖慢编辑器,建议拆分为更小的资产。
- 事件不触发时需检查监听者注册情况。
- 资产未保存更改时需调用
EditorUtility.SetDirty。
最佳实践
- 使用
CreateAssetMenu便于创建。 - 在
OnEnable中初始化运行时状态。 - 清除运行时状态,避免编辑器持久化影响。
- 集合使用数据库模式。
- 在编辑器中通过
OnValidate校验。 - 保持 ID 唯一并自动校验。
- 私有字段使用
SerializeField。 - 避免在 SO 中引用场景对象。
- 在编辑器中每次播放之间重置状态。
- 谨慎使用
Resources.Load,优先使用 Addressables。