zl程序教程

您现在的位置是:首页 >  前端

当前栏目

Unity 工具 之 获取 OpenWeatherMap 的天气(可以获取国内外的天气)的简单封装

封装工具 简单 获取 可以 Unity 天气 国内外
2023-09-11 14:20:50 时间

 

 

Unity 工具 之 获取 OpenWeatherMap 的天气(可以获取国内外的天气)的简单封装

 

目录

Unity 工具 之 获取 OpenWeatherMap 的天气(可以获取国内外的天气)的简单封装

一、简单介绍

二、实现原理

三、注意事项

四、效果预览

五、申请 OpenWeatherMap 账号,获得 API Key

六、实现步骤

七、关键代码

附录:(weather-conditions)


 

一、简单介绍

Unity中的一些基础知识点。

本节介绍,在 Unity 中,简单实现使用 OpenWeatherMap(可以获得国外的天气,OpenWeatherMap  官网:https://openweathermap.org/) 获取天气的封装,便于后期使用,有不对,欢迎指正。

如果只是国内的天气获取,可以使用这个  中国天气网地址:http://www.weather.com.cn

OpenWeatherMap 有多个 API 接口,有不同的功能,使用方法差不多,API 传递参数不同,以及返回的数据不同而已。

 

二、实现原理

https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={your api key} 为例子

1、通过 Http Get 获取对应经纬度的数据

2、数据位  Json 格式,对应的解析出数据即可

 

三、注意事项

1、 使用 json 解析时,数据不支持 float 类型,请注意,可以使用 double 代替

2、json 数据中有些数据,不符合变量命名方式,在使用 json 解析映射到数据结构的时候,特别注意,解决的方法,就是把json 字符串的不符合变量命名的参数做修改即可

3、json 参考的Respond 的数据只是参考,用来定义解析的数据结构不全,要全的话,请参考 Json 部分的 Parameters 中的介绍

4、注册 OpenWeatherMap 账号,可能需要 VPN

5、可以动态获取 GPS 经纬度或者城市,动态获取当地的天气

 

四、效果预览

 

五、申请 OpenWeatherMap 账号,获得 API Key

1、在百度输入 OpenWeatherMap,点击进入官网

OpenWeatherMap  官网:https://openweathermap.org/

 

2、没有账号,注册一个账号

(可能需要vpn)

 

3、填写数据,人机身份验证完后,创建即可

 

4、没有vpn 注册 可能,不能进行人机身份验证

 

5、人机认证完毕后,会有确认邮件,点击确认即可

 

6、点击 API 菜单栏,查看API

 

7、API 如下,有些是免费的(使用有限制),有些是收费的

 

8、注册好账号,会有一个默认的 API key,点击查看

 

六、实现步骤

1、打开 Unity,新建工程

 

2、在工程中,新建脚本 GetOpenWeatherMapWrapper 编写获取天气的逻辑,TestGetOpenWeatherMapWrapper 测试 GetOpenWeatherMapWrapper 的功能

 

3、把 TestGetOpenWeatherMapWrapper 脚本挂载到场景中

 

4、运行场景,网络没有问题的话,效果如上

 

七、关键代码

1、GetOpenWeatherMapWrapper

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using LitJson;

namespace XANTools
{
    /// <summary>
    ///  OpenWeatherMap 获取当天天气的接口封装
    /// </summary>
    public class GetOpenWeatherMapWrapper : MonoSingleton<GetOpenWeatherMapWrapper>
    {

        //获取天气 url = "https://api.openweathermap.org/data/2.5/weather?lat=22.36&lon=114.11&appid=YourKey";
        string urlHeader = "https://api.openweathermap.org/data/2.5/weather?lat=";
        string urlMid = "&lon=";
        string urlTailer = "&appid=YourKey";

        // 天气数据
        private WeatherStruct weatherStructData;
        public WeatherStruct WeatherStructData { get => weatherStructData; set => weatherStructData = value; }

        // 天气获取成功的事件
        Action<WeatherStruct> GetWeatherSucessAction;
        Action<string> GetWeatherFailAction;


        /// <summary>
        /// 开始获取天气数据
        /// </summary>
        /// <param name="GetWeatherSucessHandler">获取成功的事件</param>
        /// <param name="lat"></param>
        /// <param name="lon"></param>
        public void StartGetWeather(float lat, float lon, Action<WeatherStruct> GetWeatherSucessHandler, Action<string> GetWeatherFailHandler) {
            GetWeatherSucessAction = GetWeatherSucessHandler;
            GetWeatherFailAction = GetWeatherFailHandler;
            StartCoroutine(GetRequest(GetWeatherUrl(lat, lon)));            
        }

        /// <summary>
        /// 获取网络数据
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        IEnumerator GetRequest(string url)
        {

            using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
            {
                Debug.Log(GetType() + "/UnityWebRequest.Get()/");

                yield return webRequest.SendWebRequest();

                // 可以放在 Update 中显示 
                //Debug.Log("webRequest.uploadProgress " + webRequest.uploadProgress);

                if (webRequest.isHttpError || webRequest.isNetworkError)
                {
                    Debug.LogError(webRequest.error + "\n" + webRequest.downloadHandler.text);

                    // 执行回调
                    if (GetWeatherFailAction != null)
                    {
                        GetWeatherFailAction(webRequest.downloadHandler.text);
                    }
                }
                else
                {
                    string weatherJsonStr = webRequest.downloadHandler.text;
                    Debug.Log(GetType() + "/GetRequest()/Old weatherJsonStr : " + weatherJsonStr);
                    // 如果有进行替换,便于 json 解析
                    weatherJsonStr = weatherJsonStr.Replace("\"base\":", "\"_base\":");
                    weatherJsonStr = weatherJsonStr.Replace("\"1h\":", "\"_1h\":");
                    weatherJsonStr = weatherJsonStr.Replace("\"3h\":", "\"_3h\":");
                    Debug.Log(GetType()+ "/GetRequest()/Replace weatherJsonStr : " + weatherJsonStr);

                    // 解析数据
                    WeatherStructData = JsonMapper.ToObject<WeatherStruct>(weatherJsonStr);

                    Debug.Log(GetType()+ "/GetRequest()/ WeatherStructData.weather[0].main :" + WeatherStructData.weather[0].main);
                    Debug.Log(GetType()+ "/GetRequest()/ WeatherStructData.main.temp_max :" + WeatherStructData.main.temp_max);
                    Debug.Log(GetType()+ "/GetRequest()/ WeatherStructData.main.temp_min :" + WeatherStructData.main.temp_min);

                    // 执行回调
                    if (GetWeatherSucessAction != null) {
                        GetWeatherSucessAction(WeatherStructData);
                    }
                }
            }
        }

        /// <summary>
        /// 获取 天气数据,可能为空
        /// </summary>
        /// <returns></returns>
        public WeatherStruct GetWeatherStructData() {

            return weatherStructData;
        }

        /// <summary>
        /// 获取拼接的天气 url
        /// </summary>
        /// <param name="lon"></param>
        /// <param name="lat"></param>
        /// <returns></returns>
        string GetWeatherUrl(float lon, float lat)
        {

            return urlHeader + lon + urlMid + lat + urlTailer;
        }


    }


    #region 天气 json 数据结构 网址:https://openweathermap.org/current#current_JSON 
    /// <summary>
    /// OpenWeathermMap 获取数据的json数据结构
    /// </summary>
    public class WeatherStruct{
        public WeatherCoord coord;
        public List<Weather> weather;
        // base 是代码的特殊属性,不能作为变量名,替换位_base
        public string _base;
        public WeatherMain main;
        public double visibility;
        public WeatherWind wind;
        public WeatherClouds clouds;
        public WeatherRain rain;
        public WeatherSnow snow;
        public int dt;
        public WeatherSys sys;
        public int timezone;
        public int id;
        public string name;
        public int cod;
    }

    

    /// <summary>
    /// 经纬度
    /// </summary>
    public class WeatherCoord
    {
        public double lon;   // 经度
        public double lat;   // 纬度
    }

    /// <summary>
    /// 天气简单描述
    /// </summary>
    public class Weather
    {
        public int id;
        public string main;
        public string description;
        public string icon;
    }

    /// <summary>
    /// 天气略详描述
    /// </summary>
    public class WeatherMain {
        public double temp;
        public double feels_like;
        public double temp_min;
        public double temp_max;
        public double pressure;
        public double humidity;
        public double sea_level;
        public double grnd_level;
    }

    /// <summary>
    /// 风速,风向
    /// </summary>
    public class WeatherWind
    {
        public double speed;
        public double deg;
        public double gust;
    }

    /// <summary>
    /// 云量
    /// </summary>
    public class WeatherClouds {
        public double all;
    }

    /// <summary>
    /// 雨速
    /// </summary>
    public class WeatherRain {

        // 由于变量并不能以数字开头,把原来的 1h / 3h 转为 _1h/_3h
        public double _1h; 
        public double _3h; 
    }

    /// <summary>
    /// 雪速
    /// </summary>
    public class WeatherSnow
    {

        // 由于变量并不能以数字开头,把原来的 1h / 3h 转为 _1h/_3h
        public double _1h;
        public double _3h;
    }

    /// <summary>
    /// 天气的地理位置
    /// </summary>
    public class WeatherSys
    {
        public double type;
        public int id;
        public double message;
        public string country;
        public int sunrise;
        public int sunset;
    }
    #endregion 天气 json 数据结构 网址:https://openweathermap.org/current#current_JSON 
}

 

2、TestGetOpenWeatherMapWrapper

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

public class TestGetOpenWeatherMapWrapper : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // 测试经纬度
        float lon = 110.46f;
        float lat = 24.71f;
        GetOpenWeatherMapWrapper.Instance.StartGetWeather(lat, lon, 
            (weatherData)=> {

                Debug.Log(GetType() + "/Start()/ weatherData.weather[0].main :" + weatherData.weather[0].main);
                Debug.Log(GetType() + "/Start()/ weatherData.main.temp_max :" + weatherData.main.temp_max);
                Debug.Log(GetType() + "/Start()/ weatherData.main.temp_min :" + weatherData.main.temp_min);

            },(failInfo)=>{
                Debug.Log(GetType() + "/Start()/ failInfo :" + failInfo);
            });
    }

   
}

 

3、MonoSingleton

using UnityEngine;

public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance = null;

    private static readonly object locker = new object();

    private static bool bAppQuitting;

    public static T Instance
    {
        get
        {
            if (bAppQuitting)
            {
                instance = null;
                return instance;
            }

            lock (locker)
            {
                if (instance == null)
                {
                    // 保证场景中只有一个 单例
                    T[] managers = Object.FindObjectsOfType(typeof(T)) as T[];
                    if (managers.Length != 0)
                    {
                        if (managers.Length == 1)
                        {
                            instance = managers[0];
                            instance.gameObject.name = typeof(T).Name;
                            return instance;
                        }
                        else
                        {
                            Debug.LogError("Class " + typeof(T).Name + " exists multiple times in violation of singleton pattern. Destroying all copies");
                            foreach (T manager in managers)
                            {
                                Destroy(manager.gameObject);
                            }
                        }
                    }


                    var singleton = new GameObject();
                    instance = singleton.AddComponent<T>();
                    singleton.name = "(singleton)" + typeof(T);
                    singleton.hideFlags = HideFlags.None;
                    DontDestroyOnLoad(singleton);

                }
                instance.hideFlags = HideFlags.None;
                return instance;
            }
        }
    }

    protected virtual void Awake()
    {
        bAppQuitting = false;
    }

    protected virtual void OnDestroy()
    {
        bAppQuitting = true;
    }
}

 

附录:(weather-conditions)

1、Weather id 相关

网址:https://openweathermap.org/weather-conditions