Unity 获取手机地理位置信息
引言
在游戏的开发过程中,有时候会遇到需要获取玩家位置信息的需求,比如显示玩家所在的国家城市等。
有一下方法可以参考:
-
可以根据手机的地区和语言来做判断。
-
根据IP来判断所处的位置,阿里云啥的都有对应的接口服务。
-
根据GPS来判断。
以上方法都各有利弊吧,这里简单介绍下根据GPS来处理的方案。
实现
Unity中不提供直接获取玩家在哪个国家哪座城市的功能,只提供获取一些GPS信息的功能,这样我们就需要根据GPS信息来获取具体的国家城市,需要借助一些第三方插件来实现。
Unity获取用户的经纬度信息
官方文档:Unity - Scripting API: LocationService.Start (unity3d.com)
我根据官方文档做了一些修改,在请求权限的时候因为使用的Unity2019,Unity提供的接口还不支持回调返回,所以这里做了一些处理。
完整代码如下:
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.Android;
using UnityEngine.Events;/// <summary>
/// GPS位置管理器
/// </summary>
public class LocationManager : MonoBehaviour
{#region 单例public static LocationManager _Instance;public static LocationManager Instance{get{if (_Instance == null){GameObject obj = new GameObject("LocationManager");_Instance = obj.AddComponent<LocationManager>();DontDestroyOnLoad(obj);}return _Instance;}}#endregion/// <summary>/// 超时时间/// 20秒/// </summary>private const float Time_Out = 20;/// <summary>/// 启动成功回调/// </summary>public event UnityAction<LocationInfo> SuccessCallback;/// <summary>/// 失败回调/// </summary>public event UnityAction<string> FailureCallback;/// <summary>/// 刷新回调/// </summary>public event UnityAction<LocationInfo> UpdateCallback;/// <summary>/// 停止回调/// </summary>public event UnityAction StoppedCallback;/// <summary>/// 是否开始/// </summary>private bool _IsStarted = false;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){if (Input.location.status == LocationServiceStatus.Running){OnUpdate(Input.location.lastData);}
#if UNITY_ANDROID && !UNITY_EDITORif (UnityEngine.Android.Permission.HasUserAuthorizedPermission(UnityEngine.Android.Permission.FineLocation)){StartGPS();}
#endif}/// <summary>/// 申请权限/// </summary>public static void RequestPermission(){
#if UNITY_ANDROID && !UNITY_EDITORstring permission = UnityEngine.Android.Permission.FineLocation;if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(permission)){UnityEngine.Android.Permission.RequestUserPermission(permission);}
#endif}/// <summary>/// 初始化/// </summary>public void Init(){RequestPermission();StartGPS();}/// <summary>/// 开始定位/// </summary>private void StartGPS(){if (!Input.location.isEnabledByUser){OnError("用户没有权限");return;}if (_IsStarted){return;}_IsStarted = true;Input.location.Start();StartCoroutine(GetGPS());}private IEnumerator GetGPS(){float time = Time_Out;while (Input.location.status == LocationServiceStatus.Initializing && time > 0){yield return new WaitForSeconds(1);time--;}if (time < 1){OnError("Timed out");yield break;}if (Input.location.status == LocationServiceStatus.Failed){OnError("Unable to determine device location");yield break;}else{OnStartSuccess(Input.location.lastData);}}/// <summary>/// 停止定位/// </summary>public static void StopGPS(){if (!_Instance){return;}if (!_Instance._IsStarted){return;}try{Input.location.Stop();_Instance._IsStarted = false;}catch (System.Exception){throw;}finally{_Instance.OnStopped();}}/// <summary>/// 启动成功/// </summary>/// <param name="locationInfo"></param>private void OnStartSuccess(LocationInfo locationInfo){Debug.Log("OnStartSuccess:" + locationInfo.latitude + " " + locationInfo.longitude + " " + locationInfo.altitude + " " + locationInfo.horizontalAccuracy + " " + locationInfo.timestamp);SuccessCallback?.Invoke(locationInfo);}/// <summary>/// 发生错误/// </summary>private void OnError(string errorInfo){Debug.Log("OnError:" + errorInfo);FailureCallback?.Invoke(errorInfo);StopGPS();}/// <summary>/// 更新位置/// </summary>/// <param name="locationInfo"></param>private void OnUpdate(LocationInfo locationInfo){UpdateCallback?.Invoke(locationInfo);}/// <summary>/// 停止/// </summary>private void OnStopped(){Debug.Log("OnStopped:");StoppedCallback?.Invoke();if (gameObject){Destroy(gameObject);_Instance = null;}}
}
根据GPS信息获取对应的国家城市
基本上所有的地图都有这个功能,例如百度地图,谷歌地图等。
百度地图:逆地理编码 rgc 反geo检索 | 百度地图API SDK (baidu.com)
谷歌地图:反向地理编码(地址查询)请求和响应 | Geocoding API | Google Developers
简答来说就是都是通过网络请求,将GPS信息和自己创建的密钥发送给后台,后台返回对应的国家城市信息,按照指定的格式进行解析就可以了,这里就不过多介绍了。
但是想用起来都不简单,毕竟人家统计这么多地图信息也不容易。
尾语
如果有写的不好的地方,欢迎各位大佬批评指正。