Unity 獲取手機(jī)地理位置信息
引言
在游戲的開(kāi)發(fā)過(guò)程中,有時(shí)候會(huì)遇到需要獲取玩家位置信息的需求,比如顯示玩家所在的國(guó)家城市等。
有一下方法可以參考:
-
可以根據(jù)手機(jī)的地區(qū)和語(yǔ)言來(lái)做判斷。
-
根據(jù)IP來(lái)判斷所處的位置,阿里云啥的都有對(duì)應(yīng)的接口服務(wù)。
-
根據(jù)GPS來(lái)判斷。
以上方法都各有利弊吧,這里簡(jiǎn)單介紹下根據(jù)GPS來(lái)處理的方案。
實(shí)現(xiàn)
Unity中不提供直接獲取玩家在哪個(gè)國(guó)家哪座城市的功能,只提供獲取一些GPS信息的功能,這樣我們就需要根據(jù)GPS信息來(lái)獲取具體的國(guó)家城市,需要借助一些第三方插件來(lái)實(shí)現(xiàn)。
Unity獲取用戶(hù)的經(jīng)緯度信息
官方文檔:Unity - Scripting API: LocationService.Start (unity3d.com)
我根據(jù)官方文檔做了一些修改,在請(qǐng)求權(quán)限的時(shí)候因?yàn)槭褂玫腢nity2019,Unity提供的接口還不支持回調(diào)返回,所以這里做了一些處理。
完整代碼如下:
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>
/// 超時(shí)時(shí)間
/// 20秒
/// </summary>
private const float Time_Out = 20;
/// <summary>
/// 啟動(dòng)成功回調(diào)
/// </summary>
public event UnityAction<LocationInfo> SuccessCallback;
/// <summary>
/// 失敗回調(diào)
/// </summary>
public event UnityAction<string> FailureCallback;
/// <summary>
/// 刷新回調(diào)
/// </summary>
public event UnityAction<LocationInfo> UpdateCallback;
/// <summary>
/// 停止回調(diào)
/// </summary>
public event UnityAction StoppedCallback;
/// <summary>
/// 是否開(kāi)始
/// </summary>
private bool _IsStarted = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.location.status == LocationServiceStatus.Running)
{
OnUpdate(Input.location.lastData);
}
#if UNITY_ANDROID && !UNITY_EDITOR
if (UnityEngine.Android.Permission.HasUserAuthorizedPermission(UnityEngine.Android.Permission.FineLocation))
{
StartGPS();
}
#endif
}
/// <summary>
/// 申請(qǐng)權(quán)限
/// </summary>
public static void RequestPermission()
{
#if UNITY_ANDROID && !UNITY_EDITOR
string 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>
/// 開(kāi)始定位
/// </summary>
private void StartGPS()
{
if (!Input.location.isEnabledByUser)
{
OnError("用戶(hù)沒(méi)有權(quán)限");
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>
/// 啟動(dòng)成功
/// </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>
/// 發(fā)生錯(cuò)誤
/// </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;
}
}
}
根據(jù)GPS信息獲取對(duì)應(yīng)的國(guó)家城市
基本上所有的地圖都有這個(gè)功能,例如百度地圖,谷歌地圖等。
百度地圖:逆地理編碼 rgc 反geo檢索 | 百度地圖API SDK (baidu.com)
谷歌地圖:反向地理編碼(地址查詢(xún))請(qǐng)求和響應(yīng) | Geocoding API | Google Developers
簡(jiǎn)答來(lái)說(shuō)就是都是通過(guò)網(wǎng)絡(luò)請(qǐng)求,將GPS信息和自己創(chuàng)建的密鑰發(fā)送給后臺(tái),后臺(tái)返回對(duì)應(yīng)的國(guó)家城市信息,按照指定的格式進(jìn)行解析就可以了,這里就不過(guò)多介紹了。
但是想用起來(lái)都不簡(jiǎn)單,畢竟人家統(tǒng)計(jì)這么多地圖信息也不容易。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-531841.html
尾語(yǔ)
如果有寫(xiě)的不好的地方,歡迎各位大佬批評(píng)指正。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-531841.html
到了這里,關(guān)于Unity 獲取手機(jī)地理位置信息的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!