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

ScriptableObject的Awake()修改内容需重启Unity才显示于Inspector,求解决

问题分析与解决办法

根本原因

你遇到的问题核心在于ScriptableObject的Awake()方法在编辑模式下的执行时机与Unity编辑器序列化流程冲突。当你通过AssetMenu创建新实例时,Unity正处于资产初始化/导入阶段,此时在Awake()中修改列表并调用EditorUtility.SetDirty(),编辑器的序列化系统可能无法正确记录这些变更。当你点击Inspector或按下回车时,编辑器会刷新内存中的资产状态,导致未被正确序列化的列表被重置为空。而重启Unity时,资产会从磁盘重新加载,此时之前的变更才会被读取出来。

另外,EditorUtility.SetDirty()在新版Unity中已被弃用,直接调用AssetDatabase.SaveAssets()会干扰资产导入流程,引发"restrictions during asset importing"错误。


解决方案

1. 移除Awake()中的初始化逻辑,改用自定义资产创建方法

避免在Awake()中修改ScriptableObject数据,转而通过自定义菜单方法显式初始化资产,确保变更被编辑器正确记录。

2. 使用Undo.RecordObject替代EditorUtility.SetDirty

Undo.RecordObject是Unity推荐的编辑器变更记录方式,能正确通知序列化系统资产已修改,保证变更持久化。

3. 避免立即调用AssetDatabase.SaveAssets()

Unity会自动处理资产保存,仅在资产创建完成后调用一次即可,避免干扰导入流程。


代码示例

修改后的MySO类

using UnityEngine;
using System.Collections.Generic;

[CreateAssetMenu(fileName = "New MySO", menuName = "Custom/MySO")]
public class MySO : ScriptableObject
{
    public List<SomeOtherClass> someOtherClassList = new List<SomeOtherClass>();

    // 移除Awake()中的初始化代码
    // void Awake() { ... }

    // 专门的列表初始化方法
    public void InitializeList()
    {
        // 添加你的SomeOtherClass实例
        someOtherClassList.Add(new SomeOtherClass());
        someOtherClassList.Add(new SomeOtherClass());
        // 可继续添加更多实例
    }
}

[System.Serializable]
public class SomeOtherClass
{
    // 你的可序列化字段
    public int exampleValue;
}

自定义编辑器创建脚本

using UnityEditor;
using UnityEngine;

public static class MySOCreator
{
    [MenuItem("Custom/Create MySO with Initialized List")]
    public static void CreateMySO()
    {
        // 创建MySO实例
        MySO newSO = ScriptableObject.CreateInstance<MySO>();
        
        // 记录对象变更(替代SetDirty)
        Undo.RecordObject(newSO, "Initialize MySO List");
        
        // 初始化列表
        newSO.InitializeList();
        
        // 生成唯一资产路径并创建资产文件
        string assetPath = AssetDatabase.GenerateUniqueAssetPath("Assets/New MySO.asset");
        AssetDatabase.CreateAsset(newSO, assetPath);
        
        // 安全保存资产数据库
        AssetDatabase.SaveAssets();
        
        // 在Project窗口定位到新创建的资产
        Selection.activeObject = newSO;
        EditorGUIUtility.PingObject(newSO);
    }
}

额外说明

  • 通过Custom/Create MySO with Initialized List菜单创建资产,列表会被正确初始化并持久化,不会出现点击后清空的问题。
  • 若仍需保留Awake()初始化,可添加编辑模式判断与空列表检查(但不推荐,可靠性不如自定义创建方法):
void Awake()
{
    if (Application.isEditor && !EditorApplication.isPlaying)
    {
        if (someOtherClassList == null || someOtherClassList.Count == 0)
        {
            someOtherClassList.Add(new SomeOtherClass());
            Undo.RecordObject(this, "Initialize List");
        }
    }
}

内容的提问来源于stack exchange,提问作者Gabriel Balassa Turu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 08:34:59