1. ARSDK란?

ARSDK는 지도와 AR 컨텐츠 저작툴인 AMapper의 데이터를 이용하여 공간에 배치 된 오브젝트들을 쉽게 증강시키고 이를 바탕으로 AR 어플리케이션을 간편하게 만들 수 있도록 도와주는 Unity 패키지입니다.

2. 설치 방법

샘플 프로젝트 기반 설치 (권장)

  • ARCeyeARSDK 프로젝트 clone

      git clone https://github.com/NaverCloudPlatform/ARCeyeARSDK.git
  • Unity Hub에서 clone한 프로젝트 불러오기

  • Android 혹은 iOS 플랫폼으로 변경 (선택)
  • Assets > ARPG > Example > Scenes > 0.example_simple 실행 후 정상 동작 확인

💡 ARSDK의 Github 페이지에서 Download ZIP을 이용해 프로젝트를 다운로드 받을 경우 플러그인에 손상이 발생하는 문제가 있습니다. git clone으로 프로젝트를 받거나 다운로드 받은 프로젝트에 ar-sdk-unity.unitypackage를 추가해주세요.

직접 설치

  • arpg-sdk-unity-1.2.4.unitypackage 다운로드
  • Unity 프로젝트 생성
  • 생성한 프로젝트에 glTFast 설치
  • VL SDK unitypackage 추가
  • 다운로드 받은 arpg-sdk-unity-1.2.4.unitypackage 추가

3. AMapper 데이터 로드

ARPlayground 연결

AMapper 프로젝트를 생성하면 다음과 같이 *.amproj 파일과 각종 디렉토리들이 생성 됩니다. 이렇게 생성된 전체 프로젝트 파일을 통해 ARSDK를 동작시킬 수 있습니다.

StreamingAssets 경로 활용

AMapper 프로젝트 디렉토리를 수정하지 않고 그대로 Unity 프로젝트의 StreamingAssets 디렉토리의 하위에 추가를 해줍니다.

💡 StreamingAssets 디렉토리는 런타임에 경로 기반으로 접근할 수 있는 파일들을 저장하는 디렉토리입니다. 기본적으로 생성되어 있지 않기 때문에 사용자가 Unity 프로젝트 내의 Assets 폴더 하위에 직접 생성을 해야합니다.

추가 된 AMapper 프로젝트 파일의 경로를 ARPlayGround 컴포넌트에서 설정해줍니다. Contants Path 필드에 StreamingAssets의 하위 경로를 작성합니다.

이와 같은 방법을 통해 AMapper의 데이터를 ARSDK에서 읽을 수 있습니다.

PersistentDataPath 활용

ARPlayGround에서 Streaming Asset에 체크를 하면 Application.streamingAssets 하위의 Contents Path를 사용하고, 체크를 해제하면 Application.persistentDataPath 하위의 경로를 사용하게 됩니다.

StreamingAssets 경로를 이용하면 앱 빌드 시 컨텐츠가 함께 빌드 되어 빠르고 쉽게 컨텐츠에 접근할 수 있습니다. 하지만 모든 컨텐츠가 앱에 포함되어 빌드가 되기 때문에 앱의 용량이 커진다는 단점이 있습니다. 이 문제는 별도의 컨텐츠 서버를 구축한 뒤 해당 서버를 통해 컨텐츠를 다운로드 받아 AMapper 프로젝트에 접근하는 방법을 사용하면 해결할 수 있습니다. 다운로드 받은 컨텐츠 파일은 Application.persistentDataPath을 기준으로 저장되기 때문에 ARPlayground에서 Streaming Asset에 체크를 해제하면 해당 경로에 접근이 가능합니다.

AMapper 프로젝트 로드

ARPlayGround 컴포넌트를 보면 Load On Awake라는 필드가 있는 것을 볼 수 있습니다. 해당 필드에 체크가 되어 있으면 시작과 동시에 Contents Path에 지정된 경로의 amproj 파일을 읽어서 화면을 구성합니다. 만일 앱을 실행한 뒤 원하는 순간에 amproj 로드를 직접 호출해야 합니다. ARSDK는 로딩 완료 콜백 호출과 비동기 로딩을 모두 지원합니다. 필요에 따라 둘 중 한가지 방법을 선택해서 AMapper 프로젝트를 로드할 수 있습니다.

// 로딩 완료 콜백 호출
m_ARPlayGround.Load(() => {
    Debug.Log("AMapper 프로젝트 파일 로드 성공");
});

// async를 이용한 로딩
await m_ARPlayGround.LoadAsync();

모든 ARSDK의 기능들은 AMapper 프로젝트가 정상적으로 로드가 된 뒤에 실행해야 합니다.

주의 사항

주어진 경로에서 *.amapper 파일을 찾을 수 없다면 아래와 같은 경고 메시지를 확인할 수 있습니다. 이 경우 AMapper 프로젝트 파일이 정상적인 위치에 있는지, 혹은 Contents Path에 정확한 경로를 입력했는지 확인이 필요합니다.

4. ARSDK를 구성하는 필수 요소

ARSDK 프로젝트는 아래에 표시된 ARPlayGround, ItemGenerator, MapCameraRig, NextStep이 반드시 필요합니다. 각 요소들은 ARPG > Core > Prefabs에서 확인할 수 있습니다.

ARPlayGround

ARSDK의 핵심 요소들을 관리하고 실행하는 기능을 수행합니다. 핵심 모듈인 Native 플러그인을 호출하고 각종 콜백 이벤트를 받아 사용자에게 전달합니다.

초기화, 각종 콜백 이벤트 수신, 내비게이션 실행 등의 역할을 수행합니다. 자세한 설명은 ARPlayGround 세부 설명 파트를 참고 바랍니다.

ItemGenerator

Native 플러그인에서 호출하는 아이템 생성 메시지를 수신하여 아이템 오브젝트들을 생성하는 기능을 수행합니다. AMapper 프로젝트에서 추가한 지도, Map POI, Sign POI, AR 오브젝트 등을 생성합니다.

ItemGenerator는 ItemGenerator, POIGenerator, InfoPanelGenerator를 포함하고 있습니다. ItemGenerator는 사용자의 사전 설정이 가장 많이 들어가는 부분이기 때문에 ItemGenerator 세부 설명 파트를 참고 바랍니다.

MapCameraRig

미니맵을 렌더링하는 카메라를 움직이거나 관리하는 기능을 수행합니다. MapCameraRig에 할당된 RenderTexture에 렌더링하여 사용자가 원하는 위치에 지도를 그릴 수 있도록 합니다.

NextStep

내비게이션 모드에서 사용자가 어느 방향으로 움직여야 할지 알려주는 ‘NextStep’의 카메라와 캔버스를 관리하는 기능을 수행합니다.

5. 기본 사용 방법

5.1 오브젝트 로드

ARPlayGround는 생성이 완료되면 Contents Path의 amapper 파일을 찾아 자동으로 로딩을 수행합니다. 이 상태에서는 아직 각종 오브젝트들이 로딩되지 않은 상태입니다. ARPlayGroundSetStage(string) 메서드를 이용하여 특정 스테이지의 오브젝트들을 로드할 수 있습니다. 이 때 SetStage(string)의 매개변수는 AMapper에서 설정했던 Stage의 이름을 사용합니다.

AMapper에서의 Stage 이름. 1F로 설정 되어 있다.

Unity에서 SetStage를 호출할때의 모습. 1F로 호출하고 있다.

// 코드를 통해 스테이지를 로드하는 방법
m_ARPlayGround.SetStage("1F");

스테이지 설정이 완료되면 해당 스테이지에 맞는 오브젝트들이 로드 됩니다. ARSDK의 기본 상태는 Visibility가 Around인 오브젝트를 로딩하는 상태이기 때문에 Visibility가 Around이거나 Always인 오브젝트가 로딩됩니다.

5.2 오브젝트 삭제

다음 스테이지를 로드하면 기존에 로드 되어 있던 스테이지 오브젝트들을 자동으로 삭제 됩니다.

5.3 미니맵 생성

미니맵은 MapCameraRig 하위의 카메라들을 이용해서 렌더링이 되는 RenderTexture와 RawImage를 이용하여 만들 수 있습니다. 지도가 렌더링 되는 RenderTexture는 ARPG > Core > TextureShrinkMapRenderTextureFullMapRenderTexture입니다. ARPG > Core > PrefabsMapCameraRig를 화면에 추가하면 해당 텍스처에 지도가 렌더링 되기 시작합니다.

미니맵의 크기에 따라 RenderTexture의 크기를 변경해서 비율을 조정해야 합니다. 또한 Anti-aliasing 부분의 설정을 통해 렌더링의 품질을 개선할 수 있습니다.

6. 패키지 추가 후 실행되는 작업

패키지가 추가되면 Layer가 추가 되고 Custom Shader가 Always included shader로 추가 됩니다.

추가 되는 레이어는 다음과 같습니다.

Map, MapPOI, MapArrow

또한 ARPG > Core > Shaders의 모든 쉐이더들이 Always included shader로 추가 됩니다.

7. ARPlayGround 세부 설명

ARPlayGround 오브젝트는 ARSDK의 핵심 로직이 담겨있는 네이티브 플러그인을 실행하고 그로부터 각종 콜백 이벤트를 받아 사용자에게 전달하는 역할을 수행합니다.

7.1 메인 카메라를 이용한 업데이트

ARPlayGround는 매 프레임마다 Main Camera의 위치를 이용하여 내부에서 각종 연산을 수행합니다. 그래서 앱의 시작과 동시에 Main Camera를 ARPlayGround에 할당하는 작업이 필요합니다. 이 작업은 ARPlayGround.csInitMainCamera() 메서드에서 자동으로 수행 됩니다.

private void InitMainCamera()
{
    // 메인 카메라 참조.
    m_MainCamera = Camera.main;

    // 메인 카메라의 렌더링 culling mask 설정.
    int cullingMask = m_MainCamera.cullingMask;
    string[] layersToDisable = { "Map", "MapPOI", "MapArrow", "UI" };
    foreach (string layer in layersToDisable)
    {
        int layerIndex = LayerMask.NameToLayer(layer);
        if (layerIndex == -1)
        {
            continue;
        }

        cullingMask &= ~(1 << layerIndex);
    }

    m_MainCamera.cullingMask = cullingMask;
}

이렇게 참조한 Main Camera는 Update 이벤트를 통해 view matrix와 projection matrix로 변환되어 네이티브 영역으로 전달됩니다.

private void Update()
{
    // Camera의 view matrix와 pose matrix를 계산해서 ARPlayGround를 갱신.
    Matrix4x4 poseMatrix = Matrix4x4.TRS(m_MainCamera.transform.position, m_MainCamera.transform.rotation, Vector3.one);
    Matrix4x4 viewMatrix = Matrix4x4.Inverse(poseMatrix);
    Matrix4x4 projMatrix = m_MainCamera.projectionMatrix;

    UpdateScene(viewMatrix, projMatrix);
}

InitMainCamera()를 참고하면 일부 레이어에 대한 culling mask를 설정하는 것을 확인할 수 있습니다. 로딩이 되는 지도 오브젝트나 MapPOI와 같은 것들은 메인 카메라에서 렌더링이 되면 안되기 때문에 해당 레이어의 오브젝트들은 렌더링에서 제외 시킵니다.

7.2 스테이지 로드

ARPlayGround는 스테이지 단위로 데이터를 로드합니다. 스테이지는 SetStage(string) 메서드를 실행함으로서 로드할 수 있습니다. 이 때 SetStage의 매개변수로 AMapper에서 설정했던 스테이지의 이름을 입력합니다.

m_ARPlayGround.SetStage("1F");

7.3 POI 정보 가져오기

기본적으로 ItemGenerator를 통해서 자동으로 Map POI와 Sign POI 오브젝트들을 생성할 수 있습니다. 하지만 POI 정보를 이용하여 리스트 뷰를 구성하는 것과 같이 데이터에 대한 직접 접근이 필요한 경우 이를 가져올 수 있습니다.

AMapper에서 설정한 POI 리스트

ARPlayGround의 OnPOIList 이벤트를 활용하면 amproj 파일에 저장 된 POI 리스트들을 가져올 수 있습니다.

전달되는 POI 리스트는 다음과 같이 필터링을 해서 사용할 수 있습니다.

public void OnPOIList(List<LayerPOIItem> poiItems)
{
    // 조건에 해당하는 POI만 출력.
    var filterdPOIItems = poiItems.FindAll(
        e => 
            // Cafe
            e.dpcode == 110700 ||
            e.dpcode == 111100 ||

            // Toliets
            e.dpcode == 133000 ||
            e.dpcode == 133003 ||
            e.dpcode == 133004 ||
            e.dpcode == 133113 ||

            // Info
            e.dpcode == 133130 ||

            e.name == "랩스연구소"
    );
}

7.4 내비게이션 (Beta)

ARPlayGround와 POI 정보를 이용하면 현재 위치를 기반으로 경로 탐색을 수행할 수 있습니다. OnPOIList 이벤트를 통해 전달된 LayerPOIItem을 목적지로 설정하여 경로를 탐색합니다.

// 이름이 화장실인 LayerPOIItem을 참조.
LayerPOIItem destPOI = poiItems.Find(e => e.name == "화장실");

// 내비게이션 실행
m_ARPlayGround.LoadNavigation(destPOI);

경로 탐색에 성공했다면 경로가 화면에 출력합니다.

경로를 그리기 위해서는 ItemGenerator의 Style 항목에서 경로를 렌더링하는데 사용되는 LineRenderer를 위한 Material과 시작점, 종료점에 대한 prefab을 설정해야 합니다. 해당 자료들은 ARPG > Example > MaterialsARPG > Example > Prefabs에서 확인하실 수 있습니다.

내비게이션 이벤트

내비게이션을 실행할 경우 내비게이션의 상태에 따라 다양한 이벤트를 수신할 수 있습니다. 주로 내비게이션의 상태에 따른 UI를 처리하는데 많이 사용 됩니다.

OnNavigationStarted

내비게이션을 시작과 동시에 호출되는 이벤트

OnNavigationEnded()

내비게이션이 종료 됐을 때 호출되는 이벤트. 목적지 도착 이후 5초 뒤에 실행 된다.

OnNavigationReSearched()

내비게이션 중 경로를 이탈한 뒤 재탐색을 수행했을때 호출되는 이벤트.

OnDistanceUpdated(float)

매 프레임마다 남은 거리(m)를 전달하는 이벤트

OnDestinationArrived()

목적지 도착과 동시에 호출되는 이벤트

OnTransitMovingStarted(int transitType, string destStageName)

Transit의 시작점 노드 진입 시 호출되는 이벤트. transitType에는 다음과 같은 transit type이 전달 된다.

  • 0 - Default
  • 1 - Escalator
  • 2 - Elevator
  • 3 - Stair

destStageName에는 목적지 층이 전달 된다.

OnTransitMovingEnded()

Transit의 종료점 노드 진입 시 호출되는 이벤트.

내비게이션 종료

다음과 같은 코드를 실행하여 실행 중인 내비게이션을 종료할 수 있습니다.

// 내비게이션 종료
m_ARPlayGround.UnloadNavigation();

다른 층의 목적지에 대한 길찾기

목적지의 층이 현재 층과 다를 경우 층을 이동하는 수단을 선택해야 합니다. 길찾기를 요청했을때 현재 층과 목적지의 층을 비교하여 층이 다를 경우 사용자에게 이동 수단을 선택하게 하거나 지정된 이동 수단을 이용하여 경로를 탐색하게 할 수 있습니다.

public void LoadNavigation(LayerPOIItem poiItem)
{
    if(m_CurrStage == poiItem.stageName)
    {
        m_ARPlayGround.LoadNavigation(poiItem, ConnectionType.Default);
    }
    else
    {
        Debug.Log("다른 층의 목적지를 선택");
        m_ARPlayGround.LoadNavigation(poiItem, ConnectionType.Elevator);
    }
}

8. ItemGenerator 세부 설명

ItemGenerator는 네이티브 플러그인의 요청을 받아 각종 아이템을 생성하는 역할을 수행합니다. 생성하는 아이템의 종류는 다음과 같습니다.

  • UnityModel
  • UnityCartoMap
  • UnityTurnSpot
  • UnityGroundSpot
  • UnitySignPOI
  • UnityMapPOI
  • UnityInfoPanel
  • UnityNextStepArrow
  • UnityNextStepDot
  • UnityNextStepText

AMapper를 통해 배치 된 오브젝트는 위 타입들 중 하나로 생성이 되어 Unity가 Play 모드가 될 때 Scene에 배치됩니다.

AMapper에서 배치한 햄버거 아이템

ARSDK에서 로딩 된 햄버거 아이템

8.1 ItemGenerator

Item Generator의 Inspector에서 확인할 수 있는 Item Generator의 필드에 대한 세부 설명은 다음과 같습니다.

Scene

아이템들이 생성될 Scene을 설정합니다. 설정하지 않을 경우 Scene의 최상단에 아이템들이 생성 됩니다.

Font

아이템의 내부에 포함된 Text에서 사용할 폰트 설정합니다. 폰트가 없을 경우 기본 폰트를 사용합니다.

Path Material

Navigation 시 경로를 출력하는데 사용되는 Material을 설정합니다.

Map Path Bullet Begin

Navigation 경로의 시작 지점을 렌더링하는데 사용되는 Prefab을 설정합니다.

Map Path Bullet End

Navigation 경로의 끝 지점을 렌더링하는데 사용되는 Prefab을 설정합니다.

8.2 POIGenerator

ItemGenerator의 또 다른 중요한 기능은 각종 POI들을 자동으로 배치하는 것입니다. 이는 ItemGenerator 오브젝트에 추가된 컴포넌트인 POIGenerator에서 수행합니다.

POI Generator의 주요 필드에 대한 설명은 다음과 같습니다.

Sign POI Prefab

공간에 증강되는 SignPOI 생성 시 사용되는 Prefab입니다. 해당 Prefab에 UnitySignPOI가 추가 되어 있어야 합니다. 샘플로ARPG > Example > PrefabsUnitySignPOI.prefab가 추가 되어 있어서 이를 사용할 수 있습니다.

UnitySignPOI의 모습

Sign POI Icon Models

Sign POI에서 사용하는 Icon 모델 파일들입니다. Sign POI가 생성될 때 전달 받은 dpcode를 이름으로 변환하여 모델 파일을 참조하여 Sign POI를 생성합니다. ARPG > Example > POI > GLB에서 샘플 파일들을 확인할 수 있습니다.

Map POI Prefab

지도에 표시되는 MapPOI 생성 시 사용되는 Prefab입니다. 해당 Prefab에 UnityMapPOI가 추가 되어 있어야 합니다. 샘플로ARPG > Example > PrefabsUnityMapPOI.prefab가 추가 되어 있어서 이를 사용할 수 있습니다.

UnityMapPOI의 모습

Map POI Icon Sprites

Map POI 생성에 사용되는 아이콘 이미지들입니다. Map POI가 생성될 때 전달 받은 dpcode를 이름으로 변환하여 이미지 파일을 참조하고 Map POI를 생성합니다. ARPG > Example > POI > Icons에서 샘플 파일들을 확인할 수 있습니다.

8.3 InfoPanelGenerator

InfoPanel Generator는 AMapper에서 ‘Panel Stamp Mode’를 통해 생성한 InfoPanelItem들을 ARSDK 상에 생성하는데 사용됩니다. 별도의 설정 없이도 자동으로 AMapper의 InfoPanelItem들을 형식에 맞춰서 생성합니다. ARPG > Example > Prefabs > UnityInfoPanel.prefabInfo Panel Prefab 필드에 할당해서 사용할 수 있습니다.

9. MapCameraRig 세부 설명

MapCameraRig는 미니맵을 렌더링하는데 사용되는 Map Camera를 관리하는 오브젝트입니다. ARPG > Core > Prefabs > MapCameraRig.prefab을 화면에 추가하면 ARPG > Core > TextureShrinkMapRenderTextureFullMapRenderTexture에 렌더링이 되기 시작합니다.

MapCameraRig의 하위에 Map Camera, MapPOI Camera, MapArrow Camera라는 세 개의 카메라가 배치 되어 있으며 각각의 카메라는 Map 레이어, MapPOI 레이어, MapArrow 레이어의 오브젝트들을 렌더링합니다.

Map Camera Rig는 다음과 같은 필드들을 가지고 있습니다.

각각에 대한 설명은 다음과 같습니다.

Shrink Render Texture

축소 상태의 지도를 렌더링하는 RenderTexture. ARPG > Core > Textures의 ShrinkMapRenderTexture를 할당해서 사용할 수 있습니다.

Full Render Texture

전체 화면 상태의 지도를 렌더링하는 RenderTexture. ARPG > Core > Textures의 FullMapRenderTexture를 할당해서 사용할 수 있습니다.

Shrink Camera Distance

축소 상태에서의 카메라 거리 (m)

Full Camera Distance

전체 화면 상태에서의 카메라 거리 (m)

Full Camera Min Distance

전체 화면 상태에서의 카메라 최소 거리 (m)

Full Camera Max Distance

전체 화면 상태에서의 카메라 최대 거리 (m)

10. NextStep 세부 설명

NextStep은 ARSDK를 통해 내비게이션을 수행할 때 사용되는 가이드 오브젝트입니다. 사용자의 기기가 내비게이션의 다음 목적지(TurnSpot)를 바라보고 있지 않을때 혼동하지 않고 올바른 방향으로 기기를 가리키도록 유도합니다.

NextStep을 사용하기 위해서는 ARPG > Core > PrefabsNextStep.prefab을 화면에 추가해야 합니다. NextStep이 존재하는 상태에서 내비게이션을 수행하면 NextStep에 필요한 오브젝트들이 자동으로 생성 됩니다.

11. VLSDK 연동

LayerInfoSetting 설정

VLSDK로 공간을 인식한 결과를 이용하여 스테이지를 로드할 수 있습니다. VLSDK는 ARC eye에서 설정한 공간 계층 정보를 전달하는 OnLayerInfoChanged(string) 라는 이벤트를 가지고 있습니다. 이 정보를 ARSDK에 전달하여 스테이지를 로드하게 됩니다.

아래 사진은 ARC eye의 Location 설명에서 확인할 수 있는 이미지입니다.

ARC eye 콘솔에서 입력할 수 있는 로케이션 정보. 계층 정보를 입력할 수 있다.

ARC eye 콘솔에서는 로케이션의 각 계층에 대한 정보를 관리할 수 있습니다. VLSDK의 공간 인식 결과는 이 곳의 계층 이름들을 사용하게 됩니다.

콘솔의 값을 ARSDK에서 사용하기 위해서는 ARPG > Core > LayerInfoSetting.asset 파일을 수정해야 합니다. 해당 파일 클릭하면 Inspector에서 아래와 같은 그림을 확인할 수 있습니다.

기본적으로 계층 1이 추가가 되어 있으며 이는 최상위 계층으로 삭제가 불가능합니다. 하위 계층을 추가하려면 우측의 ‘새 계층 추가’ 버튼을 클릭합니다. 버튼을 클릭하면 하단에 하위 계층이 추가 됩니다. 새 계층을 추가하면서 계층 이름을 ARC eye의 로케이션 계층 이름과 일치 시킵니다.

특정 계층을 스테이지와 연결 시키려면 스테이지 연결에 체크를 합니다. 스테이지 연결이 체크가 되면 새 계층을 추가하는 버튼이 사라지고 스테이지 이름을 입력하는 텍스트 필드가 출력되게 됩니다. 여기에 AMapper에서 설정한 스테이지 이름을 입력하면 됩니다. 스테이지 연결이 되는 계층은 계층의 이름이 노란색으로 출력 되며 연결이 되는 스테이지의 이름이 함께 표시됩니다.

계층을 삭제하기 위해서는 오른쪽의 빨간색 - 버튼을 클릭합니다.

완료 된 설정 파일은 ARPlayGround에 추가된 LayerInfoConverter 컴포넌트에 할당해서 사용할 수 있습니다.

이벤트 연결

LayerInfoSetting의 설정이 완료 됐으면 VLSDK와 ARSDK를 직접 연결하는 작업이 필요합니다. 구체적으로 VLSDK의 OnLayerInfoChanged(string) 이벤트가 실행될때 ARSDK의 SetLayerInfo(string) 메서드가 실행되도록 합니다. 아래와 같이 이벤트를 직접 연결해줍니다.

이제 VL 인식이 되면 AMapper에서 설정한 스테이지가 로드 되는 것을 확인할 수 있습니다.

12. 데모 앱 개발

AMapper를 이용해 그린 지도 데이터를 이용하여 AR Navigation 앱을 개발하는 방법에 대한 설명입니다.

amproj 파일 완성

AMapper를 이용하여 지도 데이터를 완성합니다. 구역에 대한 정보, 경로, POI, 3D 오브젝트 등등을 배치합니다.

지도 3D 모델 생성

File > Export > 3D Format을 클릭하여 지도 데이터를 3D 모델로 생성합니다.

각 영역들을 어떤 형식의 모델로 만들 것인지 설정합니다. 이 때 Layer Distance는 0.01 이상의 값을 설정합니다. 이 값이 매우 작을 경우 Unity 에디터 상에서 z-fighting이 발생하게 됩니다.

적당한 이름으로 저장합니다. 이렇게 지도 모델을 만드는 과정이 끝났습니다.

지도 모델 스테이지 등록

생성된 glb 파일을 AMapper에서 불러온 뒤 스테이지를 눌러 Map 영역에 모델을 할당해줍니다.

지도 모델이 할당되면 다음과 같이 AMapper 화면에 모델이 로드된 모습을 볼 수 있습니다.

AMapper 프로젝트 파일 배치

앞서 생성한 AMapper 프로젝트 폴더 전체를 StreamingAssets 폴더의 하위에 복사합니다.

ARSDK 컴포넌트 배치

ARPG > Core > Prefabs에서 ARPlayGround.prefab, ItemGenerator.prefab, MapCameraRig.prefab, NextStep.prefab을 Scene에 추가합니다. ARPlayGround의 Contents Path 필드에는 StreamingAssets 폴더의 하위에 배치한 AMapper 프로젝트 폴더의 상대 경로를 입력합니다.

ARFoundation XR 환경 구축

Unity의 ARFoundation의 ARSession과 XR Origin을 추가하여 XR 환경을 구축합니다. XR Origin을 추가한 뒤에 기존의 Main Camera가 있을 경우 Main Camera를 삭제합니다.

VLSDK 환경 구축

VLSDKManager는 ARSession과 XR Origin이 배치가 되어 있어야 생성 가능합니다. VLSDKManager를 생성합니다.

스테이지 로드

버튼을 눌러서 특정 스테이지를 로드할 수 있습니다. 버튼을 생성한 뒤 버튼 클릭 이벤트에 ARPlayGround의 SetStage 메서드를 연결합니다. 매개변수로는 AMapper에서 설정한 스테이지 이름인 ‘1F’를 설정했습니다.

Play mode로 진입하면 아래와 같이 해당 스테이지의 지도와 POI가 로드되는 것을 확인할 수 있습니다.

VLSDK 사용 설정

VLSDK Settings을 통해 VL API와 관련된 정보를 입력합니다. 설정한 VLSDK Settings 값을 VLSDKManager에 할당합니다.

VLSDK를 개발환경에서 수월하게 사용하기 위해 Texture Provider에 텍스처를 할당해줍니다. 단일 이미지를 전송하고 싶을 경우에는 이미지를 직접 할당하면 되고, 동영상 데이터를 사용하기 위해서는 Texture to Send에 VideoTexture를 할당해줍니다.

VLSDK 동영상 데이터셋 사용

동영상 데이터셋을 사용하기 위해서는 Unity에서 제공하는 Video Player 사용해야 합니다. Video Player 오브젝트를 생성합니다.

Video Player 오브젝트에 데이터셋을 할당합니다. Video Clip에는 테스트를 위해 촬영한 비디오 파일을 할당하고 Target Texture 필드에는 앞서 설정한 VideoTexture를 할당합니다. 이제 Video Player가 실행되면 VideoTexture에 프레임을 렌더링하고 그 결과가 VLSDKManager의 TextureProvider에게 전달되게 됩니다.

Play 모드에 들어가면 비디오가 재생되는 것을 확인할 수 있습니다.

만일 화면에 출력되는 디버그 화면을 비활성화 하고 싶을 경우 아래의 경로에서 체크를 해제하면 디버그 창이 출력되는 것을 비활성화 할 수 있습니다.

VL 요청 시작

VLSDKManager는 기본적으로 VL 요청을 자동으로 시작하지 않습니다. VLSDKManager의 세션을 시작하는 코드를 작성합니다.

using UnityEngine;
using ARCeye;

public class GameManager : MonoBehaviour
{
    public VLSDKManager m_VLSDKManager;

    private void Start()
    {
        m_VLSDKManager.StartSession();
    }
}

VL 응답을 이용하여 자동으로 스테이지 로드

VLSDKManager의 이벤트와 ARSDK의 LayerInfoSetting을 활용하면 VL 인식과 동시에 자동으로 스테이지가 로딩이 되도록 할 수 있습니다.

우선 ARPG > Core > LayerInfoSetting.asset 에서 다음과 같이 Layer Info 정보를 설정합니다.

그 후 VLSDKManager에서 OnLayerInfoChanged(string) 이벤트에 ARPlayGound의 SetLayerInfo(string) 을 연결합니다. 이와 같은 작업을 통해 자동으로 스테이지가 로드 되게 할 수 있습니다.

미니맵 생성

미니맵은 ShrinkMapRenderTexture를 이용해서 렌더링할 수 있습니다. RawImage를 생성한뒤 ShrinkMapRenderTexture를 할당합니다.

이 때 ShrinkMapRenderTexture는 RawImage와 같은 비율을 가지도록 사이즈를 조절합니다.

미니맵에서의 카메라 거리를 조절하고 싶은 경우 MapCameraRig 하위의 Translation Rig의 z값을 조절합니다.

13. AMapper 고급기능 활용

ARSDK의 일부 기능들은 AMapper에서 설정하는 값을 기반으로 실행이 됩니다. 다음은 AMapper의 설정을 이용한 고급 기능에 대한 설명입니다.

13.1 Custom Range

내비게이션을 진행하면서 특정 Transit node에 진입할 때, Transit node를 기준으로 5m 이내에 들어오게 될 경우 OnTransitMovingStarted 이벤트가 실행됩니다. 하지만 거리 기준으로 Transit node의 진입 여부를 판단한다면 의도하지 않은 순간에 Transit node에 진입했다고 판단할 수 있습니다. 이와 같은 경우를 대비하여 Custom Range를 사용할 수 있습니다. Custom Range를 이용하면 AMapper에서 설정한 폴리곤의 모양에 맞춰서 Transit node의 진입 여부를 판단할 수 있습니다.

Custom Range 생성

Custom Range를 생성하기 위해서는 Semantic Area가 활성화된 레이어가 필요합니다. 새로운 레이어를 생성한 뒤 레이어를 선택하 Semantic Area를 활성화합니다. 그 후 생성된 레이어 하위에 폴리곤을 그립니다.

Transit node와 Custom Range 연결

Custom Range를 설정하고 싶은 Transit node를 선택하여 Custom Range를 할당해줍니다. 현재 아무 연결도 없는 Custom Range의 목록이 자동으로 출력됩니다. 연결을 하고자 하는 Custom Range의 이름을 선택하면 연결이 완료됩니다.

💡 Transit node에 Custom Range를 연결할 땐 반드시 시작 transit 노드와 끝 transit 노드 모두에 Custom Range를 연결해야 Custom Range 기능이 활성화 됩니다.

Custom Range 활성화 조건

Custom Range는 다음 조건에서 활성화 되어 transit이 시작됨을 알립니다.

  1. 내비게이션을 실행하는 상태
  2. 현재 경로의 마지막 NextStep이 활성화가 되었으며 사용자의 카메라 위치가 Custom Range 안에 들어왔을 때

13.2 길찾기 에셋 변경

AMapper와 ARSDK를 이용하여 경로탐색을 하면 기본적으로 설정된 경로의 인디케이터 모델 파일들을 참조합니다. 기본 참조 경로는 Contents/Indicator이며 하위의 TurnSpot_L.glb, TurnSpot_R.glb 등의 파일들을 참조합니다. 만일 해당 모델 파일들을 변경하고 싶다면 스테이지의 Config에서 IndicatorConfigAR을 수정해서 변경 가능합니다.

모델 파일의 경로를 수정하면 다음과 같이 경로 탐색 화살표 모델이 바뀌는 것을 확인할 수 있습니다.

13.3 공통 에셋

하나의 앱에서 여러 지역을 대응할 경우 중복된 에셋들을 사용하게 되는 경우가 많습니다. 특히 경로 탐색 시 사용 되는 각종 화살표 모델들은 중복되어 사용될 가능성이 높습니다. 이와 같이 사용 빈도가 높은 에셋은 공통 에셋으로 관리해주는 것이 좋습니다.

공통 에셋은 지역 에셋 디렉토리의 상위에 위치하여 여러 지역에서도 하나의 에셋을 참조할 수 있도록 합니다. 예를 들어 1784_demo와 AMCO라는 지역이 있을 경우 기존에는 각 지역 내에 각종 컨텐츠들을 배치했다면 공통 에셋은 그 상위에 위치하여 모든 지역이 참조할 수 있습니다.

이와 같이 상위에 배치된 공통 에셋을 AMapper에서 설정하기 위해서는 공통 에셋에 대한 상대 경로를 입력해야 합니다. 길찾기 에셋 변경 시 상위 디렉토리의 공통 에셋을 선택하면 자동적으로 공통 에셋에 대한 상대 경로가 설정되는 것을 볼 수 있습니다.

💡 상대 경로는 절대로 StreamingAssets 디렉토리보다 상위 경로를 참조해서는 안됩니다

공통 에셋은 길찾기 에셋 뿐만이 아닌 일반 에셋에도 활용할 수 있습니다. 공통 에셋 디렉토리의 파일을 AMapper에 추가한 뒤 아래와 같이 상대 경로가 정상적으로 설정 되었다면 ARSDK에서도 이를 불러올 수 있습니다.

14. 문의 사항

ARSDK 사용 시 버그를 발견하거나 사용 방법에 대한 문의가 있을 경우 dl_ar@naverlabs.com로 연락 바랍니다.

버그 리포팅 시 ARPlayground에서 VERBOSE 로그를 출력하게 설졍한 뒤 Console에서 Stack Tracing Logging의 설정을 모두 Full로 선택한 상태에서 전체 로그를 함께 첨부해주면 문제 상황을 더욱 빠르게 확인할 수 있습니다.