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

Unity构建模式下实例化ScriptableObject返回null问题咨询

Unity 2022.3.21f1c1中ScriptableObject实例化构建后显示null的问题

问题场景

我是Unity新手,使用2022.3.21f1c1版本,定义了继承自ScriptableObject的CardData类:

public class CardData : ScriptableObject
{
    public string id;
    public string title;
    // ... 其他多种类型变量,包括列表、字典及自定义类对象
}

通过以下代码实例化:

CardData ref_card = card_list[0];
CardData card = UnityEngine.Object.Instantiate(ref_card);
if(card.title.Contains("test"))
{
    Debug.Log($"ref_card.title = {ref_card.title}, ref_card = {ref_card}");
    Debug.Log($"card.title = {card.title}, card = {card}");
}

编辑器运行模式下日志正常:

ref_card.title = test1, ref_card = test (TcgEngine.CardData)

card.title = test1, card = test(Clone) (TcgEngine.CardData)

但构建项目后(开启Development Build和Player Log),日志显示:

ref_card.title = test1, ref_card = test (TcgEngine.CardData)

card.title = test1, card = null

同一代码多次测试均如此,存在两个疑问:

  1. 为何构建模式下实例化对象显示为null?
  2. 为何null对象可访问属性且不报错?

原因分析与解决方案

1. 构建后实例化对象显示null的原因

Unity的ScriptableObject在构建后的实例化逻辑和编辑器模式存在差异:

  • 编辑器中,Instantiate可以直接克隆ScriptableObject并保留引用追踪;但在构建后的Player环境中,如果ScriptableObject实例没有被正确序列化或未在内存中注册,Unity的Object.Equals/ToString逻辑会将其识别为"null",但实际内存中该对象的数据依然存在。
  • 另一种可能是card_list中的原始CardData对象在构建时被Unity的资源打包优化处理,导致克隆实例无法被引擎正确标记为有效Object。

2. 为什么"null"对象能访问属性不报错

Unity的Object子类(包括ScriptableObject)的空值判断和常规C#对象不同:

  • Unity重载了==运算符和Object.ToString()方法,当一个Unity Object实例失去了和引擎内部资源管理器的关联(比如构建中未正确注册),ToString()会返回"null",用==判断也会返回true,但该对象在托管堆上的实例依然存在,所以直接访问其公共字段(比如title)不会触发空引用异常——因为字段数据还在托管内存里,只是Unity引擎层面认为它是"无效"对象。

解决方法

  • 改用ScriptableObject.CreateInstance<CardData>()手动创建实例,然后逐个复制字段数据,替代Instantiate克隆:
    CardData ref_card = card_list[0];
    CardData card = ScriptableObject.CreateInstance<CardData>();
    // 手动复制所有需要的字段
    card.id = ref_card.id;
    card.title = ref_card.title;
    // ... 复制其他列表、字典、自定义类对象等
    
  • 如果必须使用Instantiate,确保原始CardData对象被正确包含在构建资源中:比如将其放在Resources文件夹下,或者通过Addressables/AssetBundle管理,避免构建时被Unity剔除优化。
  • 检查CardData类中的自定义类对象是否标记了[System.Serializable],否则构建后可能出现序列化异常,导致实例无法被引擎正确识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:03:21