推荐阅读

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

前段时间有小伙伴问到如何用Unity制作天气预报,博主也是在网上找了很多资料,发现天气API接口稳定的确实没有,除非是天气官方提供的, 但是我观察了下,要是合作伙伴才有开放的可能。

其他的,例如:百度 APIStore、一些同学在其他网站上抓包下来的接口,以及什么各种收费的 API,都没有稳定的。
找了很多接口API,发现了一个比较好用的免费天气API,就分享一下

首先看一下效果图:
在这里插入图片描述

项目源码链接:
https://github.com/764424567/Unity_GetWeatherInfo

二、参考资料

1、unity 获取地方位置和天气(简单版本)
2、免费、稳定的天气预报API
3、免费天气API,天气JSON API,不限次数获取十五天的天气预报
4、国内天气API Java版本请求Demo

三、正文

3.1 获取地方位置

百度地图API:

http://api.map.baidu.com/location/ip?ak=bretF4dm6W5gqjQAXuvP0NXW6FeesRXb&coor=bd09ll
有小伙伴反应上面的接口有时候不管用,显示天配额超限,限制访问,可以用下面的接口,只改了ak值:
http://api.map.baidu.com/location/ip?ak=rnymRO22dzlwhkN1rGHkHP3oNdnUL5C7&coor=bd09ll
具体这个接口的ak是怎么获取的,我会再开一个文章详细讲解,就不在这个文章赘述了。

返回的Json字符串:

{“address”:“CN|\u6cb3\u5357|\u90d1\u5dde|None|UNICOM|0|0”,“content”:{“address”:“\u6cb3\u5357\u7701\u90d1\u5dde\u5e02”,“address_detail”:{“city”:“\u90d1\u5dde\u5e02”,“city_code”:268,“district”:“”,“province”:“\u6cb3\u5357\u7701”,“street”:“”,“street_number”:“”},“point”:{“x”:“185.64964385”,“y”:“134.75661006”}},“status”:0}

看不懂没关系,我们去Json解析网站解析一下:
https://tool.oschina.net/codeformat/json
在这里插入图片描述
数据说明:
address:数据头
content:数据内容

  • address:省份城市
  • address_detail:城市名字,编号代码,省份
  • point:位置坐标等数据

status:数据状态

我们就根据这些数据写一个数据类来接收这些数据:

#region 返回的城市名字等数据类
public class CityData
{
    public string address;
    public Content content;
    public int status;

}
public class Content
{
    public string address;
    public Address_Detail address_detail;
    public Point point;
}
public class Address_Detail
{
    public string city;
    public int city_code;
    public string district;
    public string province;
    public string street;
    public string street_number;
}

public class Point
{
    public string x;
    public string y;
}
#endregion

这些命名不能改,不然Json解析不了
在这里插入图片描述
下面解析Json文件

需要导入这些脚本:
在这里插入图片描述
下载链接:
https://download.csdn.net/download/q764424567/12403068

代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#region 返回的城市名字等数据类
public class CityData
{
    public string address;
    public Content content;
    public int status;

}
public class Content
{
    public string address;
    public Address_Detail address_detail;
    public Point point;
}
public class Address_Detail
{
    public string city;
    public int city_code;
    public string district;
    public string province;
    public string street;
    public string street_number;
}

public class Point
{
    public string x;
    public string y;
}
#endregion

public class WeatherTools : MonoBehaviour
{
    /// <summary>
    /// 获取位置信息
    /// </summary>
    string Posurl = "http://api.map.baidu.com/location/ip?ak=bretF4dm6W5gqjQAXuvP0NXW6FeesRXb&coor=bd09ll";

    void Start()
    {
        //获取位置
        StartCoroutine(RequestCityName());
    }

    IEnumerator RequestCityName()
    {
        WWW www = new WWW(Posurl);
        yield return www;
        if (string.IsNullOrEmpty(www.error))
        {
            CityData cityData = LitJson.JsonMapper.ToObject<CityData>(www.text);
            Debug.Log(cityData.content.address_detail.city);
        }
    }
}

效果:
在这里插入图片描述

3.2 城市名字转化为城市代码编号

因为接口:

http://t.weather.sojson.com/api/weather/city/city_code

需要用到city_code的值,我们需要将获取到城市名字转为city_code,也就是城市代码编号,这个编号对应的Json文件是这样的:
在这里插入图片描述
城市对应的city_code的Json文件:
https://download.csdn.net/download/q764424567/12403068

城市名字转为city_code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#region 返回的城市名字等数据类
public class CityData
{
    public string address;
    public Content content;
    public int status;

}
public class Content
{
    public string address;
    public Address_Detail address_detail;
    public Point point;
}
public class Address_Detail
{
    public string city;
    public int city_code;
    public string district;
    public string province;
    public string street;
    public string street_number;
}

public class Point
{
    public string x;
    public string y;
}
#endregion

#region 城市的city_code编号代码
public class CityCode
{
    public int id;
    public int pid;
    public string city_code;
    public string city_name;
    public string post_code;
    public string area_code;
    public string ctime;
}
#endregion

public class WeatherTools : MonoBehaviour
{
    public static Dictionary<string, string> PosToId = new Dictionary<string, string>();
    public static bool initDic = false;

    /// <summary>
    /// 获取位置信息
    /// </summary>
    string Posurl = "http://api.map.baidu.com/location/ip?ak=bretF4dm6W5gqjQAXuvP0NXW6FeesRXb&coor=bd09ll";

    void Start()
    {
        //获取位置
        StartCoroutine(RequestCityName());
    }

    IEnumerator RequestCityName()
    {
        WWW www = new WWW(Posurl);
        yield return www;
        if (string.IsNullOrEmpty(www.error))
        {
            CityData cityData = LitJson.JsonMapper.ToObject<CityData>(www.text);
            Debug.Log(cityData.content.address_detail.city);
            //获取city_code
            Debug.Log(GetWeatherId(cityData.content.address_detail.city));
        }
    }

    public static string GetWeatherId(string name)
    {
        string city_code = "";
        if (!initDic)
        {
            initDic = true;
            TextAsset city = Resources.Load<TextAsset>("city");
            List<CityCode> cityCode = LitJson.JsonMapper.ToObject<List<CityCode>>(city.text);
            foreach (CityCode t in cityCode)
            {
                PosToId[t.city_name] = t.city_code;
            }
        }
        for (int i = 1; i < name.Length; i++)
        {
            string tn = name.Substring(0, i);
            if (PosToId.ContainsKey(tn))
            {
                city_code = PosToId[tn];
            }
        }
        return city_code;
    }
}

效果:
在这里插入图片描述

3.3 获取天气信息

万事俱备,只欠东风,接下来就看一下如何获取天气信息吧:
在这里插入图片描述
先分析一下获取到Json字符串:
获取天气的API:

http://t.weather.sojson.com/api/weather/city/city_code

在这里插入图片描述
在这里插入图片描述
密密麻麻的啥玩意呀,没关系,我们还可以用Json解析工具解析一下:
https://tool.oschina.net/codeformat/json
在这里插入图片描述
没错啦,就是我们需要的所有数据,我们根据这些再次制作数据类:

#region 天气数据类
public class WeatherData
{
    public string message;
    public int status;
    public string date;
    public string time;
    public CityInfo cityInfo;
    public WeathData data;
}
public class CityInfo
{
    public string city;
    public string cityId;
    public string parent;
    public string updateTime;
}
public class WeathData
{
    public string shidu;
    public double pm25;
    public double pm10;
    public string quality;
    public string wendu;
    public string ganmao;
    public WeathDetailData[] forecast;
    public WeathDetailData yesterday;
}
public class WeathDetailData
{
    public string date;
    public string sunrise;
    public string high;
    public string low;
    public string sunset;
    public double aqi;
    public string ymd;
    public string week;
    public string fx;
    public string fl;
    public string type;
    public string notice;
}
#endregion

看不懂建议再看一下Json解析出来的数据格式。。。

》不想看上面过程的,直接复制下面的代码就行《

代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#region 返回的城市名字等数据类
public class CityData
{
    public string address;
    public Content content;
    public int status;

}
public class Content
{
    public string address;
    public Address_Detail address_detail;
    public Point point;
}
public class Address_Detail
{
    public string city;
    public int city_code;
    public string district;
    public string province;
    public string street;
    public string street_number;
}

public class Point
{
    public string x;
    public string y;
}
#endregion

#region 城市的city_code编号代码
public class CityCode
{
    public int id;
    public int pid;
    public string city_code;
    public string city_name;
    public string post_code;
    public string area_code;
    public string ctime;
}
#endregion

#region 天气数据类
public class WeatherData
{
    public string message;
    public int status;
    public string date;
    public string time;
    public CityInfo cityInfo;
    public WeathData data;
}
public class CityInfo
{
    public string city;
    public string cityId;
    public string parent;
    public string updateTime;
}
public class WeathData
{
    public string shidu;
    public double pm25;
    public double pm10;
    public string quality;
    public string wendu;
    public string ganmao;
    public WeathDetailData[] forecast;
    public WeathDetailData yesterday;
}
public class WeathDetailData
{
    public string date;
    public string sunrise;
    public string high;
    public string low;
    public string sunset;
    public double aqi;
    public string ymd;
    public string week;
    public string fx;
    public string fl;
    public string type;
    public string notice;
}
#endregion

public class WeatherTools : MonoBehaviour
{
    public static Dictionary<string, string> PosToId = new Dictionary<string, string>();
    public static bool initDic = false;

    /// <summary>
    /// 获取位置信息
    /// </summary>
    string Posurl = "http://api.map.baidu.com/location/ip?ak=bretF4dm6W5gqjQAXuvP0NXW6FeesRXb&coor=bd09ll";
    /// <summary>
    /// 获取天气信息
    /// </summary>
    string Weatherurl = "http://t.weather.sojson.com/api/weather/city/";

    void Start()
    {
        //获取位置
        StartCoroutine(RequestCityName());
    }

    IEnumerator RequestCityName()
    {
        WWW www = new WWW(Posurl);
        yield return www;
        if (string.IsNullOrEmpty(www.error))
        {
            CityData cityData = LitJson.JsonMapper.ToObject<CityData>(www.text);
            Debug.Log(cityData.content.address_detail.city);
            //获取city_code
            Debug.Log(GetWeatherId(cityData.content.address_detail.city));
            //获取天气信息
            string city_code = GetWeatherId(cityData.content.address_detail.city);
            StartCoroutine(RequestWeatherData(city_code));
        }
    }

    public static string GetWeatherId(string name)
    {
        string city_code = "";
        if (!initDic)
        {
            initDic = true;
            TextAsset city = Resources.Load<TextAsset>("city");
            List<CityCode> cityCode = LitJson.JsonMapper.ToObject<List<CityCode>>(city.text);
            foreach (CityCode t in cityCode)
            {
                PosToId[t.city_name] = t.city_code;
            }
        }
        for (int i = 1; i < name.Length; i++)
        {
            string tn = name.Substring(0, i);
            if (PosToId.ContainsKey(tn))
            {
                city_code = PosToId[tn];
            }
        }
        return city_code;
    }

    IEnumerator RequestWeatherData(string cicy_code)
    {
        WWW www = new WWW(Weatherurl + cicy_code);
        Debug.Log(Weatherurl + cicy_code);
        yield return www;
        if (string.IsNullOrEmpty(www.error))
        {
            Debug.Log(www.text);
            WeatherData t = LitJson.JsonMapper.ToObject<WeatherData>(www.text);
            //天气信息
            Debug.Log(t.data.forecast[0].date);
            Debug.Log(t.data.forecast[0].high);
            Debug.Log(t.data.forecast[0].low);
            Debug.Log(t.data.forecast[0].ymd);
            Debug.Log(t.data.forecast[0].week);
            Debug.Log(t.data.forecast[0].sunrise);
            Debug.Log(t.data.forecast[0].sunset);
            Debug.Log(t.data.forecast[0].aqi);
            Debug.Log(t.data.forecast[0].fx);
            Debug.Log(t.data.forecast[0].fl);
            Debug.Log(t.data.forecast[0].type);
            Debug.Log(t.data.forecast[0].notice);
        }
    }
}

效果:
在这里插入图片描述

3.4 数据显示

数据都有,下面就是显示了
在这里插入图片描述
UI:

    //UI显示
    public Text m_TextCityName;
    public Text m_TextQuality;
    public Text m_TextNotice;
    public Image[] m_ImageType;
    //今天
    public Text m_TextTodayDate;
    
    public Text m_TextTodayType;
    public Text m_TextTodayTemperature;
    public Text m_TextTodayfx;
    //明天
    public Text m_TextTomorrowDate;
    public Text m_TextTomorrowType;
    public Text m_TextTomorrowTemperature;
    public Text m_TextTomorrowfx;
    //后天
    public Text m_TextAcquiredDate;
    public Text m_TextAcquiredType;
    public Text m_TextAcquiredTemperature;
    public Text m_TextAcquiredfx;

在这里插入图片描述
天气UI图片资源:
https://download.csdn.net/download/q764424567/12403068

代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

#region 返回的城市名字等数据类
public class CityData
{
    public string address;
    public Content content;
    public int status;

}
public class Content
{
    public string address;
    public Address_Detail address_detail;
    public Point point;
}
public class Address_Detail
{
    public string city;
    public int city_code;
    public string district;
    public string province;
    public string street;
    public string street_number;
}

public class Point
{
    public string x;
    public string y;
}
#endregion

#region 城市的city_code编号代码
public class CityCode
{
    public int id;
    public int pid;
    public string city_code;
    public string city_name;
    public string post_code;
    public string area_code;
    public string ctime;
}
#endregion

#region 天气数据类
public class WeatherData
{
    public string message;
    public int status;
    public string date;
    public string time;
    public CityInfo cityInfo;
    public WeathData data;
}
public class CityInfo
{
    public string city;
    public string cityId;
    public string parent;
    public string updateTime;
}
public class WeathData
{
    public string shidu;
    public double pm25;
    public double pm10;
    public string quality;
    public string wendu;
    public string ganmao;
    public WeathDetailData[] forecast;
    public WeathDetailData yesterday;
}
public class WeathDetailData
{
    public string date;
    public string sunrise;
    public string high;
    public string low;
    public string sunset;
    public double aqi;
    public string ymd;
    public string week;
    public string fx;
    public string fl;
    public string type;
    public string notice;
}
#endregion

public class WeatherTools : MonoBehaviour
{
    public static Dictionary<string, string> PosToId = new Dictionary<string, string>();
    public static bool initDic = false;

    //UI显示
    public Text m_TextCityName;
    public Text m_TextQuality;
    public Text m_TextNotice;
    public Image[] m_ImageType;
    //今天
    public Text m_TextTodayDate;
    
    public Text m_TextTodayType;
    public Text m_TextTodayTemperature;
    public Text m_TextTodayfx;
    //明天
    public Text m_TextTomorrowDate;
    public Text m_TextTomorrowType;
    public Text m_TextTomorrowTemperature;
    public Text m_TextTomorrowfx;
    //后天
    public Text m_TextAcquiredDate;
    public Text m_TextAcquiredType;
    public Text m_TextAcquiredTemperature;
    public Text m_TextAcquiredfx;

    /// <summary>
    /// 获取位置信息
    /// </summary>
    string Posurl = "http://api.map.baidu.com/location/ip?ak=bretF4dm6W5gqjQAXuvP0NXW6FeesRXb&coor=bd09ll";
    /// <summary>
    /// 获取天气信息
    /// </summary>
    string Weatherurl = "http://t.weather.sojson.com/api/weather/city/";

    void Start()
    {
        //获取位置
        StartCoroutine(RequestCityName());
    }

    IEnumerator RequestCityName()
    {
        WWW www = new WWW(Posurl);
        yield return www;
        if (string.IsNullOrEmpty(www.error))
        {
            CityData cityData = LitJson.JsonMapper.ToObject<CityData>(www.text);
            Debug.Log(cityData.content.address_detail.city);
            //获取city_code
            Debug.Log(GetWeatherId(cityData.content.address_detail.city));
            //获取天气信息
            string city_code = GetWeatherId(cityData.content.address_detail.city);
            StartCoroutine(RequestWeatherData(city_code));
        }
    }

    public static string GetWeatherId(string name)
    {
        string city_code = "";
        if (!initDic)
        {
            initDic = true;
            TextAsset city = Resources.Load<TextAsset>("city");
            List<CityCode> cityCode = LitJson.JsonMapper.ToObject<List<CityCode>>(city.text);
            foreach (CityCode t in cityCode)
            {
                PosToId[t.city_name] = t.city_code;
            }
        }
        for (int i = 1; i < name.Length; i++)
        {
            string tn = name.Substring(0, i);
            if (PosToId.ContainsKey(tn))
            {
                city_code = PosToId[tn];
            }
        }
        return city_code;
    }

    IEnumerator RequestWeatherData(string cicy_code)
    {
        WWW www = new WWW(Weatherurl + cicy_code);
        Debug.Log(Weatherurl + cicy_code);
        yield return www;
        if (string.IsNullOrEmpty(www.error))
        {
            Debug.Log(www.text);
            WeatherData t = LitJson.JsonMapper.ToObject<WeatherData>(www.text);
            //UI显示数据
            WeatherData_UIShow(t);
        }
    }

    public void WeatherData_UIShow(WeatherData _weatherData)
    {
        m_TextCityName.text = _weatherData.cityInfo.city;
        m_TextQuality.text = _weatherData.data.quality;
        m_TextNotice.text = _weatherData.data.forecast[0].notice;
        string[] data = WeatherData_Parse(_weatherData);
        //今天
        m_TextTodayDate.text = data[0];
        m_TextTodayType.text = data[1];
        m_TextTodayTemperature.text = data[2];
        m_TextTodayfx.text = data[3];
        //明天
        m_TextTomorrowDate.text = data[4];
        m_TextTomorrowType.text = data[5];
        m_TextTomorrowTemperature.text = data[6];
        m_TextTomorrowfx.text = data[7];
        //后天
        m_TextAcquiredDate.text = data[8];
        m_TextAcquiredType.text = data[9];
        m_TextAcquiredTemperature.text = data[10];
        m_TextAcquiredfx.text = data[11];
    }

    public string[] WeatherData_Parse(WeatherData _weatherData)
    {
        string[] data = new string[12];
        for (int i = 0; i < 3; i++)
        {
            //图片显示
            string path = "weather/" + _weatherData.data.forecast[i].type;
            m_ImageType[i].sprite = Resources.Load(path, typeof(Sprite)) as Sprite;
            //数据计算
            string temperatureLow = _weatherData.data.forecast[i].low;
            string temperatureHigh = _weatherData.data.forecast[i].high;
            temperatureLow = temperatureLow.Substring(3, temperatureLow.Length - 3);
            temperatureHigh = temperatureHigh.Substring(3, temperatureHigh.Length- 3);
            //String数组存一下拼接好的字符串
            data[i * 4 + 0] = _weatherData.data.forecast[i].date + "日   " + _weatherData.data.forecast[i].week;
            data[i * 4 + 1] = _weatherData.data.forecast[i].type;
            data[i * 4 + 2] = temperatureLow + " ~ " + temperatureHigh;
            data[i * 4 + 3] = _weatherData.data.forecast[i].fx;
        }
        return data;
    }
}

效果:
在这里插入图片描述

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐