Unity 中的脚本响应不正确的值
Script in Unity responding incorrect values
我一直在尝试使用 weatherbit.io API 在我的 android 应用程序中访问 AQI 信息。 AqiInfoScript
脚本用于访问API,Update AQI
脚本用于打印值。
AqiInfoScript:
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using SimpleJSON;
public class AqiInfoScript : MonoBehaviour
{
private float timer;
public float minutesBetweenUpdate;
private float latitude;
private float longitude;
private bool locationInitialized;
public static string cityName;
public static double currentAqi;
private readonly string baseWeatherbitURL = "https://api.weatherbit.io/v2.0/current/airquality?";
private readonly string key = "*********************";
public void Begin()
{
latitude = GPS.latitude;
longitude = GPS.longitude;
locationInitialized = true;
}
void Update()
{
if (locationInitialized)
{
if (timer <= 0)
{
StartCoroutine(GetAqi());
timer = minutesBetweenUpdate * 60;
}
else
{
timer -= Time.deltaTime;
}
}
}
private IEnumerator GetAqi()
{
string weatherbitURL = baseWeatherbitURL + "lat=" + latitude + "&lon=" + longitude + "&key="
+ key;
UnityWebRequest aqiInfoRequest = UnityWebRequest.Get(weatherbitURL);
yield return aqiInfoRequest.SendWebRequest();
//error
if (aqiInfoRequest.isNetworkError || aqiInfoRequest.isHttpError)
{
Debug.LogError(aqiInfoRequest.error);
yield break;
}
JSONNode aqiInfo = JSON.Parse(aqiInfoRequest.downloadHandler.text);
cityName = aqiInfo["city_name"];
currentAqi = aqiInfo["data"]["aqi"];
}
}
更新 AQI 脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UpdateAQI : MonoBehaviour
{
public Text airquality;
//public Text coordinates;
private void Update()
{
airquality.text = "Current Aqi: " + AqiInfoScript.currentAqi.ToString();
}
}
当前输出:当前 AQI:0
期望输出:当前 AQI:129.0000
问题
在我看来 API returns 代表 your request 例如对于 lat=42, lon=-7
以下 JSON
{
"data":[
{
"mold_level":1,
"aqi":54,
"pm10":7.71189,
"co":298.738,
"o3":115.871,
"predominant_pollen_type":"Molds",
"so2":0.952743,
"pollen_level_tree":1,
"pollen_level_weed":1,
"no2":0.233282,
"pm25":6.7908,
"pollen_level_grass":1
}
],
"city_name":"Pías",
"lon":-7,
"timezone":"Europe\/Madrid",
"lat":42,
"country_code":"ES",
"state_code":"55"
}
如你所见"data"
实际上是一个数组。您将其视为单个值。
幕后花絮
不幸的是,您使用的 SmipleJson 库很容易出错,因为它不会因拼写错误而抛出任何异常,而是默默地失败并使用默认值。
你可以看到这个,例如在
public override JSONNode this[string aKey]
{
get
{
if (m_Dict.ContainsKey(aKey))
return m_Dict[aKey];
else
return new JSONLazyCreator(this, aKey);
}
....
}
和
public static implicit operator double(JSONNode d)
{
return (d == null) ? 0 : d.AsDouble;
}
解决方案
应该是
cityName = aqiInfo["city_name"];
currentAqi = aqiInfo["data"][0]["aqi"].AsDouble;
Debug.Log($"cityName = {cityName}\ncurrentAqi = {currentAqi}");
一般来说,我建议使用 JsonUtility.FromJson
,而是在 C# 中实现所需的数据结构,例如:
[Serializable]
public class Data
{
public int mold_level;
public double aqi;
public double pm10;
public double co;
public double o3;
public string predominant_pollen_type;
public double so2;
public int pollen_level_tree;
public int pollen_level_weed;
public double no2;
public double pm25;
public int pollen_level_grass;
}
[Serializable]
public class Root
{
public List<Data> data;
public string city_name;
public int lon;
public string timezone;
public int lat;
public string country_code;
public string state_code;
}
然后你会使用
var aqiInfo = JsonUtility.FromJson<Root>(aqiInfoRequest.downloadHandler.text);
cityName = aqiInfo.city_name;
currentAqi = aqiInfo.data[0].aqi;
Debug.Log($"cityName = {cityName}\ncurrentAqi = {currentAqi}");
对我来说,正如虚拟值所说 lat=42, lon=-7
两次都按预期打印出来
cityName = Pías
currentAqi = 54
UnityEngine.Debug:Log(Object)
<GetAqi>d__18:MoveNext() (at Assets/Example.cs:109)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
我一直在尝试使用 weatherbit.io API 在我的 android 应用程序中访问 AQI 信息。 AqiInfoScript
脚本用于访问API,Update AQI
脚本用于打印值。
AqiInfoScript:
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using SimpleJSON;
public class AqiInfoScript : MonoBehaviour
{
private float timer;
public float minutesBetweenUpdate;
private float latitude;
private float longitude;
private bool locationInitialized;
public static string cityName;
public static double currentAqi;
private readonly string baseWeatherbitURL = "https://api.weatherbit.io/v2.0/current/airquality?";
private readonly string key = "*********************";
public void Begin()
{
latitude = GPS.latitude;
longitude = GPS.longitude;
locationInitialized = true;
}
void Update()
{
if (locationInitialized)
{
if (timer <= 0)
{
StartCoroutine(GetAqi());
timer = minutesBetweenUpdate * 60;
}
else
{
timer -= Time.deltaTime;
}
}
}
private IEnumerator GetAqi()
{
string weatherbitURL = baseWeatherbitURL + "lat=" + latitude + "&lon=" + longitude + "&key="
+ key;
UnityWebRequest aqiInfoRequest = UnityWebRequest.Get(weatherbitURL);
yield return aqiInfoRequest.SendWebRequest();
//error
if (aqiInfoRequest.isNetworkError || aqiInfoRequest.isHttpError)
{
Debug.LogError(aqiInfoRequest.error);
yield break;
}
JSONNode aqiInfo = JSON.Parse(aqiInfoRequest.downloadHandler.text);
cityName = aqiInfo["city_name"];
currentAqi = aqiInfo["data"]["aqi"];
}
}
更新 AQI 脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UpdateAQI : MonoBehaviour
{
public Text airquality;
//public Text coordinates;
private void Update()
{
airquality.text = "Current Aqi: " + AqiInfoScript.currentAqi.ToString();
}
}
当前输出:当前 AQI:0 期望输出:当前 AQI:129.0000
问题
在我看来 API returns 代表 your request 例如对于 lat=42, lon=-7
以下 JSON
{
"data":[
{
"mold_level":1,
"aqi":54,
"pm10":7.71189,
"co":298.738,
"o3":115.871,
"predominant_pollen_type":"Molds",
"so2":0.952743,
"pollen_level_tree":1,
"pollen_level_weed":1,
"no2":0.233282,
"pm25":6.7908,
"pollen_level_grass":1
}
],
"city_name":"Pías",
"lon":-7,
"timezone":"Europe\/Madrid",
"lat":42,
"country_code":"ES",
"state_code":"55"
}
如你所见"data"
实际上是一个数组。您将其视为单个值。
幕后花絮
不幸的是,您使用的 SmipleJson 库很容易出错,因为它不会因拼写错误而抛出任何异常,而是默默地失败并使用默认值。
你可以看到这个,例如在
public override JSONNode this[string aKey]
{
get
{
if (m_Dict.ContainsKey(aKey))
return m_Dict[aKey];
else
return new JSONLazyCreator(this, aKey);
}
....
}
和
public static implicit operator double(JSONNode d)
{
return (d == null) ? 0 : d.AsDouble;
}
解决方案
应该是
cityName = aqiInfo["city_name"];
currentAqi = aqiInfo["data"][0]["aqi"].AsDouble;
Debug.Log($"cityName = {cityName}\ncurrentAqi = {currentAqi}");
一般来说,我建议使用 JsonUtility.FromJson
,而是在 C# 中实现所需的数据结构,例如:
[Serializable]
public class Data
{
public int mold_level;
public double aqi;
public double pm10;
public double co;
public double o3;
public string predominant_pollen_type;
public double so2;
public int pollen_level_tree;
public int pollen_level_weed;
public double no2;
public double pm25;
public int pollen_level_grass;
}
[Serializable]
public class Root
{
public List<Data> data;
public string city_name;
public int lon;
public string timezone;
public int lat;
public string country_code;
public string state_code;
}
然后你会使用
var aqiInfo = JsonUtility.FromJson<Root>(aqiInfoRequest.downloadHandler.text);
cityName = aqiInfo.city_name;
currentAqi = aqiInfo.data[0].aqi;
Debug.Log($"cityName = {cityName}\ncurrentAqi = {currentAqi}");
对我来说,正如虚拟值所说 lat=42, lon=-7
两次都按预期打印出来
cityName = Pías
currentAqi = 54
UnityEngine.Debug:Log(Object)
<GetAqi>d__18:MoveNext() (at Assets/Example.cs:109)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)