c# - 如何在 Unity 中由用户定义从 JSON 获取哪个字段名称
问题描述
当我使用 JsonUtility 在我的类中通过变量名称指定字段名称时,我能够在 Unity 中读取 JSON。我想让我的脚本更通用,以便用户可以从多个 JSON 中定义要使用的字段名称,而不必使用相同的字段名称。
// call this function to get array of JsonEntry objects
public static T[] FromJson<T>(string json)
{
return JsonUtility.FromJson<JsonEntries<T>>(json).Entries;
}
我正在使用这个类
[Serializable]
public class JsonEntries<T>
{
public T[] Entries;
}
[Serializable]
public class JsonEntry
{
// field names from one JSON example
public string USULAN_ID;
public string USULAN_LAT;
public string USULAN_LONG;
public string USULAN_URGENSI;
//TODO user defined filed names
}
如果我在 Unity 中使用 JsonUtility 事先不知道字段名称,是否可以让用户定义要使用的字段名称?
解决方案
不使用JsonUtility
,不!
使用 Unity JsonUtility
,您必须事先知道字段名称,并实现表示 JSON 结构的类,包括精确匹配的字段名称。它也仅限于某些类型:
API 支持任何具有该属性的
MonoBehaviour
-subclass、ScriptableObject
-subclass 或普通类/结构。[Serializable]
你传入的对象会被送入标准的 Unity 序列化器进行处理,因此与 Inspector 中的规则和限制相同;只有字段被序列化,类型如Dictionary<>
; 不支持。目前不支持将其他类型直接传递给 API,例如原始类型或数组。现在,您需要将此类类型包装在某种类或结构中。
假设您只需要一个级别并且 JSON 看起来像例如
{
"USULAN_ID":"some id",
"USULAN_LAT":"some lat",
"USULAN_LONG":"some long",
"USULAN_URGENSI":"some urgensi"
}
其中字段名称和计数可能会动态更改,您可以使用SimpleJSON
. 为此,只需将 的内容复制SimpleJSON.cs
到项目中相应命名的新文件中,然后添加using SimpleJSON;
到要使用它的脚本中。
在场景中,我会简单地使用 aDropdown
让用户决定使用哪个字段
using SimpleJSON;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DropDownController : MonoBehaviour
{
[Header("Components References")]
public Dropdown dropdown;
[Header("Input")]
// Where ever you get the json data from
public string JsonString = "{\"USULAN_ID\":\"some id\", \"USULAN_LAT\":\"some lat\", \"USULAN_LONG\":\"some long\", \"USULAN_URGENSI\":\"some urgensi\"}";
[Header("Output")]
public string currentlySelectedKey;
public string currentlySelectedValue;
public Text selectedValueText;
private Dictionary<string, string> entries = new Dictionary<string, string>();
private void Awake()
{
// get the component
if (!dropdown) dropdown = GetComponent<Dropdown>();
// register a callback
dropdown.onValueChanged.AddListener(HandleValueChanged);
// where ever you need to call this method
UpdateOptions(JsonString);
}
public void UpdateOptions(string jsonString)
{
// parse the string to a JSONNode
var json = JSON.Parse(jsonString);
// unfortunately SimpleJson simply returns null
// and doesn't throw any exceptions so you have to do it on your own
if(json == null)
{
Debug.LogFormat(this, "Oh no! Something went wrong! Can't parse json: {0}", jsonString);
return;
}
// for the case this is called multiple times
// reset the lists and dictionaries
dropdown.options.Clear();
entries.Clear();
//optional add a default field
entries.Add("Please select a field", "no field selected!");
dropdown.options.Add(new Dropdown.OptionData("Please select a field"));
// JSONNode implements an Enumerator letting
// us simply iterate through all first level entries
foreach (var field in json)
{
// simply assume string keys and string values
// might brake if the provided json has another structure
// I'll skip the null checks here
var key = field.key;
var value = field.value;
entries.Add(key, value);
dropdown.options.Add(new Dropdown.OptionData(key));
}
// set default
dropdown.value = 0;
HandleValueChanged(0);
}
private void HandleValueChanged(int newValue)
{
currentlySelectedKey = dropdown.options[newValue].text;
currentlySelectedValue = entries[currentlySelectedKey];
// optional visual feedback for the user
selectedValueText.text = currentlySelectedValue;
// optional color feedback for not yet selected
selectedValueText.color = newValue == 0 ? Color.red : Color.black;
}
}
注意:用Unity 2019.1
;测试 由于 UI 已更改,因此Dropdown
可能会有所不同。2019.2
推荐阅读
- json - 如何创建多个 json 对象并在单个请求中发布
- validation - 如何为颤振表单添加验证?
- xamarin - 以 xamarin 形式使用 tabcoltrol
- git - 无法将故障存储库镜像到 gitlab
- java - 比较两个列表并输出Java中的缺失和额外元素
- apache - 带有openldap的Apache 24无法提示用户登录
- python - Traceback,'module'没有属性我不知道为什么
- c# - 错误:部署到 IIS 后无法加载文件或程序集 'System.Web.WebPages.Razor,版本 = 3.0.0.0
- authentication - 在 Blazor 服务器应用程序登录页面上使用没有身份的 JWT 身份验证
- php - 如何将具有相同值的数据彼此隔离