Unity C#自定义列表JSON保存后加载长度为0的问题
问题分析与解决方案
核心问题原因
- Unity JsonUtility不支持直接序列化List
:内置的JsonUtility只能处理带 [Serializable]标记的类/结构体,直接传入List调用ToJson会生成无效JSON,反序列化后自然得不到数据。 - 自定义类缺少序列化标记:
Mycustom_gameobject_list类没有添加[Serializable]特性,JsonUtility会跳过对它的序列化操作。 - 不可序列化类型直接存储:
GameObject是Unity引用对象,无法被JsonUtility序列化;WayspotAnchorPayload作为AR相关复杂类型,也不能直接序列化,必须提取其中可持久化的字段(比如坐标、旋转值)。
修复步骤
1. 添加必要的序列化标记与专用存储容器
必须创建专门的数据存储类(容器类)来包裹列表,同时给自定义类加上序列化标记:
// 给自定义数据类添加Serializable标记 [Serializable] public class Mycustom_gameobject_list { // 替换不可序列化的类型为可持久化字段 public Vector3 anchorPosition; public Quaternion anchorRotation; // 不要直接存GameObject,改为存储预制体路径/唯一标识,加载时重新实例化 public string prefabPath; public string objectUniqueId; } // 专用的列表容器类,用于Json序列化 [Serializable] public class GameobjectListContainer { public List<Mycustom_gameobject_list> Store_gameobjects_list = new List<Mycustom_gameobject_list>(); }
2. 修改保存方法
通过容器类来完成序列化:
private const string GameobjData = "GameobjData"; public static void SaveLocalPayloads(List<Mycustom_gameobject_list> gamelist) { var container = new GameobjectListContainer(); container.Store_gameobjects_list = gamelist; var json = JsonUtility.ToJson(container); PlayerPrefs.SetString(GameobjData, json); Debug.Log("保存的JSON内容: " + json); }
3. 修改加载方法
从容器类反序列化数据:
public static List<Mycustom_gameobject_list> LoadLocalPayloads() { if (PlayerPrefs.HasKey(GameobjData)) { var json = PlayerPrefs.GetString(GameobjData); var container = JsonUtility.FromJson<GameobjectListContainer>(json); Debug.Log("加载的数据列表长度: " + container.Store_gameobjects_list.Count); return container.Store_gameobjects_list; } else { return new List<Mycustom_gameobject_list>(); // 返回空列表避免空引用报错 } }
4. 处理特殊类型的持久化
- GameObject:不要直接序列化实例,而是存储预制体路径、唯一ID等信息,加载时根据这些信息重新实例化对象,并设置位置旋转。
- WayspotAnchorPayload:如果是AR Foundation锚点数据,可通过
WayspotAnchor.SavePayloadAsync()获取字节数组,转为Base64字符串存储,加载时再转回字节数组恢复锚点。
关于“专门的数据存储类”
是的,必须创建这类容器类。因为JsonUtility无法直接处理顶级的List、数组等集合类型,必须将它们包裹在带[Serializable]标记的类中,才能完成正确的序列化与反序列化。
内容的提问来源于stack exchange,提问作者aron kan
相关产品推荐
相关产品推荐

