Unity中如何从JSON取值存入C# List?索引越界问题排查
解决Unity中JsonUtility解析JSON后List为空的索引越界问题
问题概述
尝试从JSON文件读取人物数据并设置到Unity的InputField中,读取后List<Usuarios>始终为空,触发索引越界错误。尝试访问lista.personajes[0].nombre仍报错。
相关文件与代码
lista.json内容
{ "personajes":[ {"nombre":"Pepe","apellido":"Lereie","puntos":15}, {"nombre":"David","apellido":"Garcia","puntos":99} ] }
Usuarios类代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Usuarios { public string nombre; public string apellido; public int puntos; }
Personajes类代码
using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable] public class Personajes { public List<Usuarios> personajes = new List<Usuarios>(); }
控制器脚本
using System.Collections; using System.Collections.Generic; using System.IO; using TMPro; using UnityEngine; using UnityEngine.UI; public class MenuController : MonoBehaviour { public TMP_InputField entradaNombre, entradaApellidos, entradaPuntos; string fichero; string datos; Personajes lista; void Awake() { fichero = Application.dataPath + "/Files/lista.json"; datos = File.ReadAllText(fichero); lista = JsonUtility.FromJson<Personajes>(datos); Debug.log(lista[0].nombre); } }
核心问题
Usuarios类未添加[System.Serializable]特性,Unity的JsonUtility仅能解析带有该标记的自定义类,否则无法识别类中的字段,导致JSON中的人物数据无法被反序列化到List<Usuarios>中,最终列表为空。
另外原代码中Debug.log应为Debug.Log(API方法名首字母大写),会引发编译错误。
解决方案
1. 给Usuarios类添加序列化标记
修改Usuarios类,添加[System.Serializable]:
using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable] public class Usuarios { public string nombre; public string apellido; public int puntos; }
2. 修正Debug日志的方法名
将Debug.log改为Debug.Log,并正确访问列表元素:
Debug.Log(lista.personajes[0].nombre);
3. 增加空值判断(可选但推荐)
为避免后续再次出现索引越界,解析后先判断列表长度:
void Awake() { fichero = Application.dataPath + "/Files/lista.json"; datos = File.ReadAllText(fichero); lista = JsonUtility.FromJson<Personajes>(datos); if (lista.personajes.Count > 0) { Debug.Log(lista.personajes[0].nombre); // 将数据设置到InputField entradaNombre.text = lista.personajes[0].nombre; entradaApellidos.text = lista.personajes[0].apellido; entradaPuntos.text = lista.personajes[0].puntos.ToString(); } else { Debug.LogWarning("未解析到任何人物数据"); } }
验证
完成上述修改后,运行Unity项目,控制台将正确输出Pepe,同时InputField会被设置为对应的数据。
内容的提问来源于stack exchange,提问作者David Garcia
相关产品推荐
相关产品推荐

