유니티에서 제공하는 LocationService 클래스로 간단히 GPS 기능을 구현해보자.
이번 글에서는 사진은 없고, 소스 코드를 위주로 진행해보겠다.
일단, 전체 소스를 먼저 보도록 하자.
using UnityEngine;
using UnityEngine.Android; //네임스페이스 추가
public class GPSModule : MonoBehaviour
{
[Header("Setting")]
public bool startGPSOnStart; //Start문에서 GPS를 실행할 것인지 여부
public float desiredAccuracyInMeters; //현재 위치로부터의 최대 오차를 지정하는 변수 (정확도)
public float updateDistanceInMeters; //특정 거리 이상 이동하면 갱신되도록 지정하는 변수 (갱신 빈도)
[Header("Cache")]
private LocationService locationService; //핵심 클래스
private void Awake()
{
locationService = Input.location; //계속 참조할 것이므로 캐싱
}
private void Start()
{
if (startGPSOnStart) //Start문에서 GPS를 실행하고자 하면
StartGPS(); //실행
}
public void StartGPS(string permissionName = null) //GPS를 실행하는 함수
{
if (Permission.HasUserAuthorizedPermission(Permission.FineLocation)) //이미 위치 권한을 획득했으면
{
locationService.Start(desiredAccuracyInMeters, updateDistanceInMeters); //서비스 시작
}
else //아직 위치 권한을 획득하지 못했으면
{
PermissionCallbacks callbacks = new(); //콜백 함수 생성 후
callbacks.PermissionGranted += StartGPS; //현재 함수를 재귀로 들어오도록
Permission.RequestUserPermission(Permission.FineLocation, callbacks); //권한 요청 후, 다시 GPS를 시작하도록 함수 실행
}
}
public void StopGPS() //GPS를 정지하는 함수
{
locationService.Stop(); //서비스 정지
}
public bool GetLocation(out LocationServiceStatus status, out float latitude, out float longitude, out float altitude) //위치 정보를 얻는 함수
{
latitude = 0f; //위도
longitude = 0f; //경도
altitude = 0f; //고도
status = locationService.status; //서비스 상태
if (!locationService.isEnabledByUser) //만약, 사용자가 스마트폰의 GPS 기능을 껐다면
return false;
switch (status)
{
case LocationServiceStatus.Stopped: //GPS를 시작하지 않음
case LocationServiceStatus.Failed: //GPS 정보를 가져올 수 없음
case LocationServiceStatus.Initializing: //GPS 기능 시작 후 초기화 중
return false; //false를 반환해서 정상적으로 정보를 주지 못했음을 알림 (그 원인은 status에 담김)
default: //GPS 기능이 정상적임 (Running)
LocationInfo locationInfo = locationService.lastData; //마지막 GPS 정보를 담고
latitude = locationInfo.latitude; //위도 지정
longitude = locationInfo.longitude; //경도 지정
altitude = locationInfo.altitude; //고도 지정
return true; //true를 반환해서 정상적으로 정보를 줬음을 알림
}
}
}
아래에서부터 분석하도록 하겠다.
① 변수 선언 및 초기화
[Header("Setting")]
public bool startGPSOnStart; //Start문에서 GPS를 실행할 것인지 여부
public float desiredAccuracyInMeters; //현재 위치로부터의 최대 오차를 지정하는 변수 (정확도)
public float updateDistanceInMeters; //특정 거리 이상 이동하면 갱신되도록 지정하는 변수 (갱신 빈도)
[Header("Cache")]
private LocationService locationService; //핵심 클래스
private void Awake()
{
locationService = Input.location; //계속 참조할 것이므로 캐싱
}
private void Start()
{
if (startGPSOnStart) //Start문에서 GPS를 실행하고자 하면
StartGPS(); //실행
}
Start문에서 GPS를 시작할 수 있도록 구성했다.
desiredAccuracyInMeters가 최대 오차를 지정하는 변수이고,
updateDistanceInMeters는 현재 위치에서 몇 미터이상 멀어지면 갱신할 것인지를 지정하는 변수이다.
※ 사실 최대 오차를 지정했다고 해서, 완벽히 현재 위치를 찾는 것이라 볼 수는 없다.
여러 요인에 의한 오차는 반드시 존재한다.
② GPS 시작 / 정지 함수
public void StartGPS(string permissionName = null) //GPS를 실행하는 함수
{
if (Permission.HasUserAuthorizedPermission(Permission.FineLocation)) //이미 위치 권한을 획득했으면
{
locationService.Start(desiredAccuracyInMeters, updateDistanceInMeters); //서비스 시작
}
else //아직 위치 권한을 획득하지 못했으면
{
PermissionCallbacks callbacks = new(); //콜백 함수 생성 후
callbacks.PermissionGranted += StartGPS; //현재 함수를 재귀로 들어오도록
Permission.RequestUserPermission(Permission.FineLocation, callbacks); //권한 요청 후, 다시 GPS를 시작하도록 함수 실행
}
}
public void StopGPS() //GPS를 정지하는 함수
{
locationService.Stop(); //서비스 정지
}
위치 권한의 여부에 따라 GPS를 시작하는 방식이 달라진다.
이미 권한을 획득했다면, LocationService를 바로 시작하면 되는 것이고,
그게 아니라면 권한을 받고 다시 시작할 수 있도록 콜백 함수를 지정해주면 된다.
콜백 함수는 재귀 형태로 지정해주었는데, 다시 StartGPS 함수가 실행되었을 시점에는
권한을 획득했기 때문에 무한 루프에 빠지지 않는다.
③ 위치 정보 함수
public bool GetLocation(out LocationServiceStatus status, out float latitude, out float longitude, out float altitude) //위치 정보를 얻는 함수
{
latitude = 0f; //위도
longitude = 0f; //경도
altitude = 0f; //고도
status = locationService.status; //서비스 상태
if (!locationService.isEnabledByUser) //만약, 사용자가 스마트폰의 GPS 기능을 껐다면
return false;
switch (status)
{
case LocationServiceStatus.Stopped: //GPS를 시작하지 않음
case LocationServiceStatus.Failed: //GPS 정보를 가져올 수 없음
case LocationServiceStatus.Initializing: //GPS 기능 시작 후 초기화 중
return false; //false를 반환해서 정상적으로 정보를 주지 못했음을 알림 (그 원인은 status에 담김)
default: //GPS 기능이 정상적임 (Running)
LocationInfo locationInfo = locationService.lastData; //마지막 GPS 정보를 담고
latitude = locationInfo.latitude; //위도 지정
longitude = locationInfo.longitude; //경도 지정
altitude = locationInfo.altitude; //고도 지정
return true; //true를 반환해서 정상적으로 정보를 줬음을 알림
}
}
핵심 함수이다. 위치 정보를 가져오는데에 성공할 수도 있고, 실패할 수도 있기 때문에 bool 형태를 반환한다.
대신, out 키워드를 사용하여 외부 변수에 값을 할당한다.
만약, 위치 정보를 가져오는 데에 실패했다면 그 원인을 status 변수로 확인할 수 있는 것이다.
여기까지 GPS 정보를 받아오는 방법에 대해 알아보았다.
GPS는 배터리 소모가 많은 기능이므로 적절히 변수 값들을 조절해서 사용했으면 한다.
'[Unity]' 카테고리의 다른 글
[Unity] LeanTween을 활용한 부드러운 전환 효과 만들기 (0) | 2023.08.27 |
---|---|
[Unity] 간단히 메모리 변조 방지하기 - 안티 치트(Anti Cheat) (28) | 2023.08.20 |
[Unity] 안드로이드(Android) 카메라 연동하기 (23) | 2023.08.05 |
[Unity] EditorGUI를 활용한 커스텀 에디터 만들기 (0) | 2023.04.25 |
[Unity] GameObject의 경로를 반환하는 함수 (0) | 2023.02.26 |
댓글