You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 07:05:12