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

38 篇文章 17 订阅

 

 

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 

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个Unity 2021版本中封装获取网络图片并转换成Sprite的代码示例: ```c# using System.Collections; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; public class ImageDownloader : MonoBehaviour { // 下载图片并转换成Sprite的方法 public IEnumerator DownloadImage(string url, Image image) { // 创建UnityWebRequest对象 UnityWebRequest request = UnityWebRequestTexture.GetTexture(url); // 发送请求并等待返回结果 yield return request.SendWebRequest(); // 判断请求是否出错 if (request.result != UnityWebRequest.Result.Success) { Debug.LogError("Failed to download image: " + request.error); yield break; } // 获取Texture2D对象 Texture2D texture = ((DownloadHandlerTexture)request.downloadHandler).texture; // 创建Sprite Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero); // 设置Image组件的Sprite image.sprite = sprite; } } ``` 这个代码示例中,我们创建了一个名为ImageDownloader的类,其中包含一个用于下载网络图片并转换成Sprite的协程方法DownloadImage。该方法接受两个参数:图片的URL和一个Image组件,用于显示下载后的Sprite。方法中,我们首先创建了一个UnityWebRequest对象,然后使用它发送请求并等待返回结果。如果请求出错,我们将在控制台输出错误信息并退出方法。如果请求成功,我们获取到了Texture2D对象,然后使用它创建一个新的Sprite对象。最后,我们将创建的Sprite对象设置为Image组件的Sprite,完成图片下载和转换的过程。 在使用该方法时,你可以在其他脚本中创建一个ImageDownloader对象,并调用DownloadImage方法来获取网络图片并将其显示在UI界面上。比如: ```c# using UnityEngine; using UnityEngine.UI; public class MyScript : MonoBehaviour { public Image image; public string url; // 创建ImageDownloader对象 private ImageDownloader imageDownloader = new ImageDownloader(); void Start() { // 调用DownloadImage方法 StartCoroutine(imageDownloader.DownloadImage(url, image)); } } ``` 在这个示例代码中,我们在MyScript脚本中创建了一个Image组件和一个字符串变量url,用于存储图片的URL。然后,在Start方法中,我们创建了一个ImageDownloader对象,并调用了它的DownloadImage方法,将url和image组件作为参数传递进去。通过这样的方式,我们可以轻松地将网络图片下载并显示在UI界面上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仙魁XAN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值