This article summarizes how to obtain GPS location data (latitude, longitude, altitude) in Unity.
Introduction
I wanted to create an app that utilizes location data.
As the first step, I will organize the method to obtain location data using Unity.
# Unity Version 2019.4.13.f1 LTS
Note: This article was translated from my original post.
Getting Location Data in Unity
Final Application
The final Unity project source code is available here:
This is a simple application that retrieves latitude, longitude, and altitude from a smartphone (Android / iOS) every 10 seconds and displays it on the screen.
Below are the key points.
Script for Obtaining Location Data
The following is the C# script for obtaining location data. Unity's LocationService feature is used.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Location : MonoBehaviour { public static Location Instance { set; get; } public float latitude; public float longitude; public float altitude; private void Start() { Instance = this; DontDestroyOnLoad(gameObject); StartCoroutine(StartLocationService()); } private IEnumerator StartLocationService() { // First, check if user has location service enabled if (!Input.location.isEnabledByUser) { Debug.Log("GPS not enabled"); yield break; } // Start service before querying location Input.location.Start(); // Wait until service initializes int maxWait = 20; while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0) { yield return new WaitForSeconds(1); maxWait--; } // Service didn't initialize in 20 seconds if (maxWait <= 0) { Debug.Log("Timed out"); yield break; } // Connection has failed if (Input.location.status == LocationServiceStatus.Failed) { Debug.Log("Unable to determine device location"); yield break; } // Set locational infomations while (true) { latitude = Input.location.lastData.latitude; longitude = Input.location.lastData.longitude; altitude = Input.location.lastData.altitude; yield return new WaitForSeconds(10); } } }
The code is adapted from the sample code in the Unity documentation.
The flow of the process in the coroutine is as follows:
- Checking GPS permission
- Starting the LocationService
- Handling failures in LocationService startup
- Retrieving location data from LocationService
// First, check if user has location service enabled if (!Input.location.isEnabledByUser) { Debug.Log("GPS not enabled"); yield break; }
First, Input.location.isEnabledByUser
is checked to determine whether access to location data is allowed on the smartphone.
If access is not granted, the coroutine is terminated with yield break;
.
// Start service before querying location Input.location.Start(); // Wait until service initializes int maxWait = 20; while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0) { yield return new WaitForSeconds(1); maxWait--; }
Next, Input.location.Start();
starts the LocationService.
A maximum startup time of 20 seconds is set, and it waits for the LocationService to initialize.
The implementation for waiting uses yield return new WaitForSeconds(1);
, which resumes the coroutine after 1 second and keeps monitoring the status of LocationService.
// Service didn't initialize in 20 seconds if (maxWait <= 0) { Debug.Log("Timed out"); yield break; } // Connection has failed if (Input.location.status == LocationServiceStatus.Failed) { Debug.Log("Unable to determine device location"); yield break; }
Next, handling for LocationService startup failures is included.
If 20 seconds pass without initialization (maxWait <= 0
) or the LocationService status is Failed
(Input.location.status == LocationServiceStatus.Failed
), the coroutine is terminated.
// Set locational infomations while (true) { latitude = Input.location.lastData.latitude; longitude = Input.location.lastData.longitude; altitude = Input.location.lastData.altitude; yield return new WaitForSeconds(10); }
Finally, latitude, longitude, and altitude are retrieved.
Each value is obtained from Input.location.lastData
.
Since I wanted to retrieve data periodically, I added a while loop with a 10-second wait between each retrieval.
Now, the location data is successfully obtained.
To access this location data from other scripts, use the Instance
variable in the Location
class.
For example, to display the location data in a Text
UI element, use the following separate script that accesses Location.Instance
:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class UpdateLocationText : MonoBehaviour { public Text location; private void Update() { location.text = $"緯度: {Location.Instance.latitude}\n経度: {Location.Instance.longitude}\n高度: {Location.Instance.altitude}\n\nCount: {Location.Instance.gps_count}\nMessage:\n{Location.Instance.message}"; } }
For more details, check the source project:
Conclusion
This article documented the method to obtain location data in Unity.
It is impressive how easily Unity allows access to GPS location data on a smartphone. (Godot Engine does not seem to provide location access functionality yet.)
I hope this helps someone!
[Related Articles]