Unity中的脚本响应不正确的值 问题幕后花絮解决方案

问题描述

我一直在尝试使用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返回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)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...