Unity WebGL构建项目无法通过Mapbox SDK获取浏览器定位服务
Unity WebGL构建项目无法通过Mapbox SDK获取浏览器定位服务
我用Unity导出了一个WebGL应用,添加了JavaScript和C#代码来获取浏览器的定位服务,但启动应用时,虽然弹出了权限请求,应用却无法接收到定位信息。我使用的是Mapbox SDK中的LocationProviderFactory定位服务脚本。
JavaScript代码
var EXPORTED_FUNCTIONS = ['_requestWebGLLocation']; mergeInto(LibraryManager.library, { requestWebGLLocation: function() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( function(position) { unityInstance.SendMessage('LocationProviderFactory', 'OnLocationReceived', position.coords.latitude + ',' + position.coords.longitude); }, function(error) { console.error('Error obtaining location: ', error); } ); } else { console.error('Geolocation is not supported by this browser.'); } } });
C#定位代码
#if !UNITY_EDITOR #define NOT_UNITY_EDITOR #endif namespace Mapbox.Unity.Location { using UnityEngine; using Mapbox.Unity.Map; using System.Text.RegularExpressions; using System.Runtime.InteropServices; using System.Collections; /// <summary> /// Singleton factory to allow easy access to various LocationProviders. /// This is meant to be attached to a game object. /// </summary> public class LocationProviderFactory : MonoBehaviour { [SerializeField] public AbstractMap mapManager; [SerializeField] [Tooltip("Provider using Unity's builtin 'Input.Location' service")] AbstractLocationProvider _deviceLocationProviderUnity; [SerializeField] [Tooltip("Custom native Android location provider. If this is not set above provider is used")] DeviceLocationProviderAndroidNative _deviceLocationProviderAndroid; [SerializeField] AbstractLocationProvider _editorLocationProvider; [SerializeField] AbstractLocationProvider _transformLocationProvider; [SerializeField] bool _dontDestroyOnLoad; [DllImport("__Internal")] private static extern void requestWebGLLocation(); /// <summary> /// The singleton instance of this factory. /// </summary> private static LocationProviderFactory _instance; public static LocationProviderFactory Instance { get { return _instance; } private set { _instance = value; } } ILocationProvider _defaultLocationProvider; /// <summary> /// The default location provider. /// Outside of the editor, this will be a <see cref="T:Mapbox.Unity.Location.DeviceLocationProvider"/>. /// In the Unity editor, this will be an <see cref="T:Mapbox.Unity.Location.EditorLocationProvider"/> /// </summary> /// <example> /// Fetch location to set a transform's position: /// <code> /// void Update() /// { /// var locationProvider = LocationProviderFactory.Instance.DefaultLocationProvider; /// transform.position = Conversions.GeoToWorldPosition(locationProvider.Location, /// MapController.ReferenceTileRect.Center, /// MapController.WorldScaleFactor).ToVector3xz(); /// } /// </code> /// </example> public ILocationProvider DefaultLocationProvider { get { return _defaultLocationProvider; } set { _defaultLocationProvider = value; } } /// <summary> /// Returns the serialized <see cref="T:Mapbox.Unity.Location.TransformLocationProvider"/>. /// </summary> public ILocationProvider TransformLocationProvider { get { return _transformLocationProvider; } } /// <summary> /// Returns the serialized <see cref="T:Mapbox.Unity.Location.EditorLocationProvider"/>. /// </summary> public ILocationProvider EditorLocationProvider { get { return _editorLocationProvider; } } /// <summary> /// Returns the serialized <see cref="T:Mapbox.Unity.Location.DeviceLocationProvider"/> /// </summary> public ILocationProvider DeviceLocationProvider { get { return _deviceLocationProviderUnity; } } /// <summary> /// Create singleton instance and inject the DefaultLocationProvider upon initialization of this component. /// </summary> protected virtual void Awake() { if (Instance != null) { DestroyImmediate(gameObject); return; } Instance = this; if (_dontDestroyOnLoad) { DontDestroyOnLoad(gameObject); } InjectEditorLocationProvider(); InjectDeviceLocationProvider(); } private void Start() { StartCoroutine(StartLocationService()); } /// <summary> /// Injects the editor location provider. /// Depending on the platform, this method and calls to it will be stripped during compile. /// </summary> [System.Diagnostics.Conditional("UNITY_EDITOR")] void InjectEditorLocationProvider() { Debug.LogFormat("LocationProviderFactory: Injected EDITOR Location Provider - {0}", _editorLocationProvider.GetType()); DefaultLocationProvider = _editorLocationProvider; } /// <summary> /// Injects the device location provider. /// Depending on the platform, this method and calls to it will be stripped during compile. /// </summary> [System.Diagnostics.Conditional("NOT_UNITY_EDITOR")] void InjectDeviceLocationProvider() { if (Application.platform == RuntimePlatform.WebGLPlayer) { Debug.Log("Using WebGL Geolocation."); requestWebGLLocation(); } else { int AndroidApiVersion = 0; var regex = new Regex(@"(?<=API-)-?\d+"); Match match = regex.Match(SystemInfo.operatingSystem); if (match.Success) { int.TryParse(match.Groups[0].Value, out AndroidApiVersion); } Debug.LogFormat("{0} => API version: {1}", SystemInfo.operatingSystem, AndroidApiVersion); if (Application.platform == RuntimePlatform.Android && AndroidApiVersion >= 24) { DefaultLocationProvider = _deviceLocationProviderAndroid; } else { DefaultLocationProvider = _deviceLocationProviderUnity; } } } public void OnLocationReceived(string locationData) { string[] coordinates = locationData.Split(','); if (coordinates.Length == 2) { float latitude = float.Parse(coordinates[0]); float longitude = float.Parse(coordinates[1]); Debug.Log($"WebGL Location Received: Latitude: {latitude}, Longitude: {longitude}"); // You can further process this location data as required } } IEnumerator StartLocationService() { if (!Input.location.isEnabledByUser) { Debug.LogError("Location services are not enabled."); yield break; } Input.location.Start(); int maxWait = 20; while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0) { yield return new WaitForSeconds(1); maxWait--; } if (maxWait <= 0) { Debug.LogError("Timed out while initializing location services."); yield break; } if (Input.location.status == LocationServiceStatus.Failed) { Debug.LogError("Unable to determine device location."); yield break; } Debug.Log($"Location: {Input.location.lastData.latitude}, {Input.location.lastData.longitude}"); } } }
编辑器错误信息
Location services are not enabled. UnityEngine.Debug:LogError (object) Mapbox.Unity.Location.LocationProviderFactory/<StartLocationService>d__26:MoveNext () (at Assets/Mapbox/Unity/Location/LocationProviderFactory.cs:210) UnityEngine.MonoBehaviour:StartCoroutine (System.Collections.IEnumerator) Mapbox.Unity.Location.LocationProviderFactory:Start () (at Assets/Mapbox/Unity/Location/LocationProviderFactory.cs:149)
GUI Error: Invalid GUILayout state in view. Verify that all layout Begin/End calls match UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
备注:内容来源于stack exchange,提问作者NiftyRunner
相关产品推荐
相关产品推荐

