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

Resources.Load加载ScriptableObject后读取List报空引用异常

问题结论

ScriptableObject完全支持存储可序列化的结构体List,通过Resources.Load加载后可以正常读取,你遇到的空引用和SO的存储、加载机制本身无关,是使用过程中的疏漏导致的,常见原因和修复方案如下:

常见原因排查
  • 字段或结构体未配置序列化规则
    Unity不会序列化所有C#字段,只有满足以下条件的字段内容才会被存入SO资源、随加载读取:
    1. 列表字段为public访问权限,或带有[SerializeField]特性;没有被标记为static、const、[NonSerialized]
    2. List存储的自定义结构体带有[System.Serializable]特性,且结构体内部所有字段均为Unity可序列化类型(基础值类型、string、UnityEngine.Object引用、其他符合序列化规则的自定义类型,不支持字典、未标记序列化的嵌套自定义类型等)
      如果不满足上述规则,你在编辑时填入的列表内容不会被保存到资源中,加载后字段自然为null。
  • 对应SO资源实例未初始化列表
    很多人会在字段声明时写public List<XXX> sceneEntries = new List<XXX>();,但Unity反序列化资源时会覆盖字段初始值:如果你创建SO资源后,从来没有在Inspector中编辑过这个列表、也没有通过初始化代码给列表赋值,加载后这个字段就会保持null,不会自动走你写的字段初始化逻辑。
  • 加载路径不匹配,加载到了未配置的SO资源
    Resources.Load的路径是相对于项目内所有Resources文件夹的相对路径,不包含文件后缀,且大小写敏感。如果拼接出来的路径对应了另一个同类型、没有配置过sceneEntries列表的SO资源,就会出现“加载结果不为null,但访问列表报空”的情况。
修复方案
  1. 补全序列化标记,参考代码如下:
    using System;
    using System.Collections.Generic;
    using UnityEngine;
    
    // 自定义结构体必须加Serializable特性才会被序列化
    [Serializable]
    public struct SceneCheckpointEntry
    {
        // 结构体内部字段也必须是可序列化类型
        public Vector3 spawnPos;
        public string checkpointId;
        public int unlockProgress;
    }
    
    [CreateAssetMenu(fileName = "checkpointData", menuName = "Game Config/Checkpoint Data")]
    public class CheckpointData : ScriptableObject
    {
        // 列表字段加SerializeField保证可序列化,不建议直接public暴露可写字段
        [SerializeField]
        private List<SceneCheckpointEntry> _sceneEntries;
        // 对外提供只读访问
        public List<SceneCheckpointEntry> sceneEntries => _sceneEntries;
    
        // 加兜底初始化,避免空引用
        private void OnEnable()
        {
            if (_sceneEntries == null)
            {
                _sceneEntries = new List<SceneCheckpointEntry>();
            }
        }
    }
    
  2. 打开你要加载的对应SO资源,确认Inspector面板能看到sceneEntries列表,手动填入需要的配置数据后保存资源。
  3. 断点调试确认加载到的attemptLoad实例就是你编辑的那个配置资源,排除路径拼错、加载到冗余同名资源的问题。

注意:通过Resources加载的SO资源是项目中的持久化资源文件,运行时直接修改sceneEntries里的内容会永久写入资源,导致下次运行配置被污染。如果运行时需要修改配置数据,请先创建列表的深拷贝再操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:21:29