Unity 工具 之 获取 OpenWeatherMap 的天气(可以获取国内外的天气)的简单封装
Unity 工具 之 获取 OpenWeatherMap 的天气(可以获取国内外的天气)的简单封装
目录
Unity 工具 之 获取 OpenWeatherMap 的天气(可以获取国内外的天气)的简单封装
五、申请 OpenWeatherMap 账号,获得 API Key
一、简单介绍
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
相关文章
- 【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装 【手记】走近科学之为什么明明实现了IEnumerable<T>的类型却不能调用LINQ扩展方法 【手记】手机网页弹出层后屏蔽底层的滑动响应 【手记】ASP.NET提示“未能创建类型”处理 【Web】一个非常简单的移动web消息框 【手记】解决EXCEL跑SQL遇“查询无法运行或数据库表无法打开...”
- Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
- Laravel通过request表单验证类返回封装http状态码
- HttpServer 2 框架【使用第三方自定义路由、简易封装 Request 对象】
- Android Jetpack组件 DataStore的使用和简单封装
- react-native fetch 请求封装
- Vue - 中文汉字转拼音(工具函数封装)
- http框架--基于OkHttp 4 封装的http请求工具类
- C#调用C++Dll封装时遇到的一系列问题 参考
- WireShark数据包分析数据封装
- 基于iOS 10、realm封装的下载器
- Redis操作Set工具类封装,Java Redis Set命令封装
- Redis操作List工具类封装,Java Redis List命令封装
- Redis操作字符串工具类封装,Redis工具类封装
- H3C TCP封装
- FMDB 二次封装工具类,让你快速学会封装,集成数据库
- 【面试题】封装jQuery源码以及实现jQuery的扩展功能
- 微信小程序原生开发功能合集十:分步组件的封装
- 微信小程序原生开发功能合集九:评分组件的封装
- pdo 封装增删改查类
- [js高手之路] 跟GhostWu一起封装一个字符串工具库-架构篇(1)
- EasyExcel根据模板填充(多sheet页封装工具方法)
- Shiro(八):shiro 通过实例工厂方法的方式封装filterChainDefinitionMap
- 微信小程序使用flyio封装request请求
- Unity 工具 之 简单引用计数器的封装整理,继承即可使用,便于简单计数使用及相关计算事件触发
- Unity 工具之 获取当前所在城市的天气数据的封装(自动定位当前所在城市,天气数据可以获得多天天数据)
- Unity 工具类 之 发送邮件功能的简单封装 SendEmailWrapper
- python读取配置文件&&简单封装
- vue2 - 基于Export2Excel.js导出Excel案例(js-xlsx插件二次封装使用)
- Swift - 简单封装一个工具类模板