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

为何第二次程序集重载后我的Scriptable Object数据全部丢失?

问题分析与解决方案

核心问题根源

你遇到的数据丢失问题,本质是Scriptable Object(SO)的使用方式错误:

  1. 多余的[System.Serializable]标签:ScriptableObject本身继承自UnityEngine.Object,已经内置Unity序列化支持,额外添加该标签会干扰正常序列化逻辑。
  2. 错误设置hideFlags:作为磁盘Asset存在的SO,Unity会自动管理其生命周期,强制设置DontUnloadUnusedAsset会破坏资源加载/卸载流程,反而导致状态异常。
  3. 未将SpellComponent保存为独立Asset:如果在Spell的Inspector中直接添加临时创建的SpellComponent实例(而非已保存的Asset),程序集重载(如二次进入PlayMode)时临时对象会被销毁,数据自然丢失。
  4. 代码拼写错误:Spell类中的virutal应为virtual,编译异常会间接影响序列化稳定性。

修正后的代码示例

Spell类

[CreateAssetMenu(menuName = "Spell", fileName = "New Spell")]
public class Spell : ScriptableObject
{
    [SerializeField] private List<SpellComponent> m_Components;

    public virtual void OnEnable()
    {
        // 移除hideFlags设置,交由Unity默认管理资源生命周期
    }
}

SpellComponent类

[CreateAssetMenu(menuName = "Spell Component", fileName = "New Spell Component")]
public abstract class SpellComponent : ScriptableObject
{
    [SerializeField] int m_ExampleInt;

    public virtual void OnEnable()
    {
        // 移除hideFlags设置
    }
}

正确操作流程

  1. 先通过CreateAssetMenu创建独立的SpellComponent Asset(比如火焰组件、冰冻组件),编辑m_ExampleInt后保存到磁盘。
  2. 创建Spell Asset,在Inspector中将已保存的SpellComponent Asset拖拽到m_Components列表中。
  3. 此时无论多少次进入PlayMode或触发程序集重载,数据都会正常保留。

补充说明

如果需要动态生成临时的SpellComponent实例(无需持久化到磁盘),可以使用ScriptableObject.CreateInstance<具体子类>(),但这类实例的数据不会被保存,程序重启或重载后会自动丢失,仅适用于 runtime 临时逻辑。

内容的提问来源于stack exchange,提问作者Kube

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:02:45