Unity之获取用户地理位置

1.直接利用三方API获取:

1.1 利用bilibili的api 【未知稳定性】

    public void Awake() {
		StartCoroutine(GetLocationInfoNew());
	}

    /// <summary>
	/// 利用bilibili的接口通过ip直接获取城市信息
	/// </summary>
	IEnumerator GetLocationInfoNew() {

		//UnityWebRequest publicIpReq = UnityWebRequest.Get(@"https://api.live.bilibili.com/client/v1/Ip/getInfoNew");

		var publicIpReq = new UnityWebRequest("https://api.live.bilibili.com/client/v1/Ip/getInfoNew", UnityWebRequest.kHttpVerbGET);
		publicIpReq.downloadHandler = new DownloadHandlerBuffer();

		yield return publicIpReq.SendWebRequest();
		if (!string.IsNullOrEmpty(publicIpReq.error)) {
			Debug.Log($"获取城市信息失败:{publicIpReq.error}");
			yield break;
		}
		var info = publicIpReq.downloadHandler.text;
		Debug.Log(info);

		//将json解析为object
		var resData = JsonUtility.FromJson<ResponseRootData>(info);
		Debug.Log($"address:{resData.data.addr}|province:{resData.data.province}|city:{resData.data.city}");
	}
	#region 用于接收返回值json的反序列化数据
	[System.Serializable]
	public class ResponseRootData {
		public int code;
		public string message;
		public ResponseData data;
	}
	[System.Serializable]
	public class ResponseData {
		public string addr;
		public string country;
		public string province;
		public string city;
		public string isp;
		public string latitude;
		public string longitude;
	}
	#endregion

lua代码

			    local info = request.downloadHandler.text
				log:Info(info)
				local json_parser_ = RapidJsonParser.new()
				info = json_parser_:Decode(info)
				if IsNull(info) or IsNull(info.data) then
					return
				end
				local addr = info.data.addr
				local city = info.data.city
				local province = info.data.province
				if IsNull(addr) or IsNull(city) or IsNull(province) then
					return
				end
				log:Info("IP:" .. addr .. "|城市:" .. city .. "|省份:" .. province)

1.2 利用baidu api 【配额超限,需要扩充配额,需要联系官方】

string url = "http://api.map.baidu.com/location/ip?ak=bretF4dm6W5gqjQAXuvP0NXW6FeesRXb&coor=bd09ll";
	void Start() {
		StartCoroutine(Request());
	}

	IEnumerator Request() {
		WWW www = new WWW(url);
		yield return www;

		if (string.IsNullOrEmpty(www.error)) {
			//TODO:结果为:{"status":302,"message":"天配额超限,限制访问"}	,
			Debug.Log(www.text);
			ResponseBody req = JsonConvert.DeserializeObject<ResponseBody>(www.text);
			if (req.content != null) {

				Debug.Log(req.content.address_detail.city + " X: " + req.content.point.x + " Y: " + req.content.point.x);
			}
		}
		else {
			Debug.Log(www.error);
		}
	}


	public class ResponseBody {

		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 Address_Detail(string city, int city_code, string district, string province, string street, string street_number) {
			this.city = city;
			this.city_code = city_code;
			this.district = district;
			this.province = province;
			this.street = street;
			this.street_number = street_number;
		}
	}
	public class Point {
		public string x;
		public string y;
		public Point(string x, string y) {
			this.x = x;
			this.y = y;
		}
	}

2.获取IP地址,根据IP位置映射表计算地理位置

2.1 API: "https://api.ipify.org" 和 心知天气官网"心知天气 - 高精度气象数据 - 天气数据API接口 - 行业气象解决方案"

获取公网IP

    //ipv6:http://icanhazip.com  
    //ipv4:https://api.ipify.org  (推荐用ipv4,ipv6返回的results里面的[]可能为空)
    IEnumerator GetPublicIP() {
		var ipv4Api = @"https://api.ipify.org";
		UnityWebRequest publicIpReq = UnityWebRequest.Get(ipv4Api);
		yield return publicIpReq.SendWebRequest();
		if (!string.IsNullOrEmpty(publicIpReq.error)) {
			Debug.Log($"查询公网ip报错:{publicIpReq.error}");
			yield break;
		}
		Debug.Log("公网ip:" + publicIpReq.downloadHandler.text);
	}

根据IP获取地理信息和天气信息,json反解析的数据结构自行定义

	IEnumerator GetWeatherInfos() {
		var ipv4Api = @"https://api.ipify.org";
		UnityWebRequest publicIpReq = UnityWebRequest.Get(ipv4Api);
		yield return publicIpReq.SendWebRequest();
		if (!string.IsNullOrEmpty(publicIpReq.error)) {
			Debug.Log($"查询公网ip报错:{publicIpReq.error}");
			yield break;
		}

        //"https://www.seniverse.com/"
		var privateKey = "去心知天气官网购买免费版把私钥填写在这里~";
		string cityUri = "https://api.seniverse.com/v3/location/search.json?key=" + privateKey + "&q=" + publicIpReq.downloadHandler.text;
		UnityWebRequest cityReq = UnityWebRequest.Get(cityUri);
		yield return cityReq.SendWebRequest();
		if (!string.IsNullOrEmpty(cityReq.error)) {
			Debug.Log($"根据公网ip得到城市信息报错:{publicIpReq.error}");
			yield break;
		}
		Debug.Log(cityReq.downloadHandler.text);
		//城市信息范例:
		// {
		//	"results": [{
		//		"id": "WT3Q0FW9ZJ3Q",
		//   "name": "武汉",
		//   "country": "CN",
		//   "path": "武汉,武汉,湖北,中国",
		//   "timezone": "Asia/Shanghai",
		//   "timezone_offset": "+08:00"
		//		  }]
		// }
		JSONNode cityDataNode = JSON.Parse(cityReq.downloadHandler.text);
		string cityId = cityDataNode["results"][0]["id"];

		string weatherUri = "https://api.seniverse.com/v3/weather/now.json?key=" + privateKey + "&location=" + cityId + "&language=zh-Hans&unit=c";
		UnityWebRequest weatherReq = UnityWebRequest.Get(weatherUri);
		yield return weatherReq.SendWebRequest();

		if (!string.IsNullOrEmpty(weatherReq.error)) {
			Debug.Log($"获取城市天气信息报错:{weatherReq.error}");
			yield break;
		}

		// 天气信息范例:
		// {
		//  "results": [{
		//   "location": {
		//    "id": "WT3Q0FW9ZJ3Q",
		//    "name": "武汉",
		//    "country": "CN",
		//    "path": "武汉,武汉,湖北,中国",
		//    "timezone": "Asia/Shanghai",
		//    "timezone_offset": "+08:00"
		//   },
		//   "now": {
		//    "text": "晴",
		//    "code": "0",
		//    "temperature": "35"
		//   },
		//   "last_update": "2022-08-17T11:20:04+08:00"
		//  }]
		// }
		JSONNode weatherDataNode = JSON.Parse(weatherReq.downloadHandler.text);
		cityNameText.text = weatherDataNode["results"][0]["location"]["name"];
		cityTemperatureText.text = weatherDataNode["results"][0]["now"]["temperature"] + "°";
	}

2.2 API:"http://icanhazip.com/"

	void Start() {
		GetInIp();

		StartCoroutine(GetOutIp());
	}
	/// <summary>
	/// 获取本机的内网ip地址
	/// </summary>
	public void GetInIp() {
		var ip = "";
		IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
		for (int i = 0; i < ips.Length; i++) {
			IPAddress address = ips[i];
			if (address.AddressFamily == AddressFamily.InterNetwork) {
				ip = address.ToString();//返回ipv4的地址的字符串
			}
			//else if (address.AddressFamily == AddressFamily.InterNetworkV6)
			//{
			//	return address.ToString();//返回ipv6的地址的字符串
			//}
		}
		//找不到就返回本地
		ip = "127.0.0.1";

		Debug.Log("in ip:" + ip);
	}
	/// <summary>
	/// 借助第三方库获取本机的外网ip地址
	/// ip查询库:http://icanhazip.com/
	/// pv4: http://ipv4.icanhazip.com/
	/// ipv6:  http://ipv6.icanhazip.com/
	/// </summary>
	IEnumerator GetOutIp() {
		var ipApi = @"http://icanhazip.com/";
		ipApi = "http://ipv4.icanhazip.com/";
		UnityWebRequest request = UnityWebRequest.Get(ipApi);
		yield return request.SendWebRequest();
		//if (request.isHttpError || request.isNetworkError) {
		//	Debug.LogError(request.error);

		//	yield break;
		//}

		if (request.result == UnityWebRequest.Result.ProtocolError || request.result == UnityWebRequest.Result.ConnectionError) {
			Debug.LogError(request.error);

			yield break;
		}

		var ip = request.downloadHandler.text;
		Debug.Log("out ip:" + ip);

	}
相关推荐
逐·風7 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
_oP_i8 小时前
Unity Addressables 系统处理 WebGL 打包本地资源的一种高效方式
unity·游戏引擎·webgl
Leoysq17 小时前
【UGUI】实现点击注册按钮跳转游戏场景
游戏·unity·游戏引擎·ugui
_oP_i20 小时前
unity中 骨骼、纹理和材质关系
unity·游戏引擎·材质
Padid1 天前
Unity SRP学习笔记(二)
笔记·学习·unity·游戏引擎·图形渲染·着色器
Tp_jh1 天前
推荐一款非常好用的C/C++在线编译器
linux·c语言·c++·ide·单片机·unity·云原生
dangoxiba2 天前
[Unity Demo]从零开始制作空洞骑士Hollow Knight第十八集补充:制作空洞骑士独有的EventSystem和InputModule
游戏·unity·c#·游戏引擎·playmaker
无敌最俊朗@2 天前
unity3d————屏幕坐标,GUI坐标,世界坐标的基础注意点
开发语言·学习·unity·c#·游戏引擎
_oP_i2 天前
Unity 中使用 WebGL 构建并运行时使用的图片必须使用web服务器上的
前端·unity·webgl
司军礼2 天前
Unity自动打包——Shell交互
unity·游戏引擎·交互