Unity中如何在创建ScriptableObject时自动设置值且不重置?
解决Unity创建ScriptableObject子类时自动设置字段值的问题
问题原因
你用Awake/OnEnable设置值无效,是因为Unity创建SO实例时,会先调用这些生命周期方法,随后用字段的默认序列化值(这里是枚举的第一个值)覆盖你的设置,导致最终值被重置。
解决方案一:使用OnValidate方法(推荐,无需额外编辑器脚本)
修改MoneyPickupData子类代码,利用编辑器环境下的OnValidate回调,设置值并强制保存修改:
public class MoneyPickupData : PickupData { private void OnValidate() { if (type != EPickupType.Money) { type = EPickupType.Money; #if UNITY_EDITOR UnityEditor.EditorUtility.SetDirty(this); #endif } } }
OnValidate在编辑器中对象被创建、修改或加载时都会触发,且在序列化流程之后执行,设置的值不会被默认值覆盖。EditorUtility.SetDirty用于标记对象为“已修改”,确保Unity将更改保存到资源文件中。
解决方案二:自定义创建菜单(更灵活,适合批量或复杂初始化)
创建一个Editor脚本,手动控制SO的创建和初始化流程,避免默认序列化的干扰:
#if UNITY_EDITOR using UnityEditor; using UnityEngine; public static class PickupDataCreator { [MenuItem("Assets/Create/Pickup/Money Pickup Data", false, 1)] public static void CreateMoneyPickupData() { // 创建子类实例并设置类型 MoneyPickupData data = ScriptableObject.CreateInstance<MoneyPickupData>(); data.type = EPickupType.Money; // 获取目标路径,默认用Assets文件夹 string path = AssetDatabase.GetAssetPath(Selection.activeObject); if (string.IsNullOrEmpty(path) || !AssetDatabase.IsValidFolder(path)) { path = "Assets"; } // 生成唯一路径避免重名 path = AssetDatabase.GenerateUniqueAssetPath($"{path}/New MoneyPickupData.asset"); // 保存资源并刷新数据库 AssetDatabase.CreateAsset(data, path); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); // 自动选中创建的资源 Selection.activeObject = data; } } #endif
使用时右键点击Project窗口,选择Assets/Create/Pickup/Money Pickup Data即可创建已预设好类型的SO实例。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

