HoloLens(1세대) 및 Azure 308: 디바이스 간 알림


참고

Mixed Reality 아카데미 자습서는 HoloLens(1세대) 및 Mixed Reality 몰입형 헤드셋을 염두에 두고 설계되었습니다. 따라서 이러한 디바이스 개발에 대한 지침을 계속 찾고 있는 개발자를 위해 이러한 자습서를 그대로 두는 것이 중요합니다. 이러한 자습서는 HoloLens 2에 사용되는 최신 도구 집합 또는 상호 작용으로 업데이트되지 않습니다. 대신 지원되는 디바이스에서 계속 작동하도록 유지 관리됩니다. HoloLens 2 위해 개발하는 방법을 보여 줄 새로운 자습서 시리즈가 미래에 게시될 예정입니다. 이 알림은 해당 자습서가 게시될 때 해당 자습서에 대한 링크로 업데이트됩니다.


최종 제품 -start

이 과정에서는 Azure Notification Hubs, Azure Tables 및 Azure Functions 사용하여 혼합 현실 애플리케이션에 Notification Hubs 기능을 추가하는 방법을 알아봅니다.

Azure Notification Hubs 는 개발자가 클라우드 내에서 구동되는 모든 플랫폼에 대상 지정 및 개인 설정된 푸시 알림을 보낼 수 있는 Microsoft 서비스입니다. 이를 통해 개발자는 시나리오에 따라 최종 사용자와 통신하거나 다양한 애플리케이션 간에 통신할 수 있습니다. 자세한 내용은 Azure Notification Hubs페이지를 참조하세요.

Azure Functions 개발자가 Azure에서 작은 코드 'functions'를 실행할 수 있는 Microsoft 서비스입니다. 이렇게 하면 많은 이점이 있을 수 있는 로컬 애플리케이션이 아닌 클라우드에 작업을 위임할 수 있습니다. Azure Functions C#, F#, Node.js, Java 및 PHP를 비롯한 여러 개발 언어를 지원합니다. 자세한 내용은 Azure Functions페이지를 참조하세요.

Azure Tables 는 개발자가 클라우드에 구조적 비 SQL 데이터를 저장하여 어디서나 쉽게 액세스할 수 있도록 하는 Microsoft 클라우드 서비스입니다. 이 서비스는 스키마 없는 디자인을 자랑하므로 필요에 따라 테이블이 진화할 수 있으므로 매우 유연합니다. 자세한 내용은 Azure 테이블페이지를 참조하세요.

이 과정을 완료하면 혼합 현실 몰입형 헤드셋 애플리케이션과 데스크톱 PC 애플리케이션이 있으며, 이 애플리케이션은 다음을 수행할 수 있습니다.

  1. 데스크톱 PC 앱을 사용하면 사용자가 마우스를 사용하여 2D 공간(X 및 Y)에서 개체를 이동할 수 있습니다.

  2. PC 앱 내에서 개체의 이동은 JSON을 사용하여 클라우드로 전송됩니다. JSON은 개체 ID, 형식 및 변환 정보(X 및 Y 좌표)를 포함하는 문자열 형식입니다.

  3. 데스크톱 앱과 동일한 장면이 있는 혼합 현실 앱은 Notification Hubs 서비스(데스크톱 PC 앱에서 방금 업데이트됨)에서 개체 이동과 관련된 알림을 받습니다.

  4. 개체 ID, 형식 및 변환 정보가 포함된 알림을 받으면 혼합 현실 앱은 받은 정보를 자체 장면에 적용합니다.

애플리케이션에서 결과를 디자인과 통합하는 방법은 사용자에게 달려 있습니다. 이 과정은 Unity 프로젝트와 Azure 서비스를 통합하는 방법을 교육하기 위해 고안되었습니다. 혼합 현실 애플리케이션을 향상시키기 위해 이 과정에서 얻은 지식을 사용하는 것이 여러분의 임무입니다. 이 과정은 다른 Mixed Reality 랩을 직접 포함하지 않는 자체 포함된 자습서입니다.

디바이스 지원

과정 HoloLens 몰입형 헤드셋
MR 및 Azure 308: 디바이스 간 알림 ✔️ ✔️

참고

이 과정은 주로 Windows Mixed Reality 몰입형(VR) 헤드셋에 중점을 두지만, 이 과정에서 배운 내용을 Microsoft HoloLens 적용할 수도 있습니다. 과정을 따라가면 HoloLens를 지원하기 위해 사용해야 할 수 있는 변경 내용에 대한 메모가 표시됩니다. HoloLens를 사용하는 경우 음성 캡처 중에 약간의 에코가 나타날 수 있습니다.

사전 요구 사항

참고

이 자습서는 Unity 및 C#에 대한 기본 경험이 있는 개발자를 위해 설계되었습니다. 또한 이 문서의 필수 구성 요소 및 서면 지침은 작성 당시 테스트 및 확인된 내용(2018년 5월)을 나타냅니다. 이 과정의 정보가 아래에 나열된 것보다 최신 소프트웨어에서 찾을 수 있는 내용과 완벽하게 일치한다고 가정해서는 안 되지만 도구 설치 문서에 나열된 대로 최신 소프트웨어를 자유롭게 사용할 수 있습니다.

이 과정에서는 다음 하드웨어 및 소프트웨어를 사용하는 것이 좋습니다.

시작하기 전에

  • 이 프로젝트를 빌드하는 데 문제가 발생하지 않도록 이 자습서에서 언급한 프로젝트를 루트 또는 루트에 가까운 폴더에 만드는 것이 좋습니다(긴 폴더 경로는 빌드 시 문제를 일으킬 수 있음).
  • Microsoft 개발자 포털 및 애플리케이션 등록 포털의 소유자여야 합니다. 그렇지 않으면 2장에서 앱에 액세스할 수 있는 권한이 없습니다.

1장 - Microsoft 개발자 포털에서 애플리케이션 만들기

Azure Notification Hubs 서비스를 사용하려면 알림을 보내고 받을 수 있도록 애플리케이션을 등록해야 하므로 Microsoft 개발자 포털에서 애플리케이션을 만들어야 합니다.

  1. Microsoft 개발자 포털에 로그인합니다.

    Microsoft 계정에 로그인해야 합니다.

  2. 대시보드에서 새 앱 만들기를 클릭합니다.

    앱 만들기

  3. 새 앱의 이름을 예약해야 하는 팝업이 나타납니다. 텍스트 상자에 적절한 이름을 삽입합니다. 선택한 이름을 사용할 수 있으면 텍스트 상자 오른쪽에 틱이 나타납니다. 사용 가능한 이름이 삽입되면 팝업의 왼쪽 아래에 있는 제품 이름 예약 단추를 클릭합니다.

    역방향 이름

  4. 이제 앱을 만들면 다음 챕터로 이동할 준비가 되었습니다.

2장 - 새 앱 자격 증명 검색

새 앱이 나열되는 애플리케이션 등록 포털에 로그인하고 Azure Portal 내에서 Notification Hubs 서비스를 설정하는 데 사용할 자격 증명을 검색합니다.

  1. 애플리케이션 등록 포털로 이동합니다.

    애플리케이션 등록 포털

    경고

    Microsoft 계정을 사용하여 로그인해야 합니다.
    Windows 스토어 개발자 포털에서 이전 챕터에서 사용한 Microsoft 계정이어야 합니다.

  2. 내 애플리케이션 섹션에서 앱을 찾을 수 있습니다. 찾은 후에는 클릭하여 앱 이름과 등록이 있는 새 페이지로 이동합니다.

    새로 등록된 앱

  3. 등록 페이지 아래로 스크롤하여 애플리케이션 비밀 섹션과 앱의 패키지 SID 를 찾습니다. 다음 챕터에서 Azure Notification Hubs Service 를 설정하는 데 사용할 두 가지를 모두 복사합니다.

    애플리케이션 비밀

3장 - Azure Portal 설정: Notification Hubs Service 만들기

앱 자격 증명을 검색하면 Azure Portal로 이동하여 Azure Notification Hubs 서비스를 만들어야 합니다.

  1. Azure Portal에 로그인합니다.

    참고

    Azure 계정이 아직 없는 경우 계정을 만들어야 합니다. 강의실 또는 랩 상황에서 이 자습서를 따르는 경우 강사 또는 감독자 중 한 명에게 새 계정 설정에 대한 도움을 요청하세요.

  2. 로그인한 후 왼쪽 위 모서리에서 새로 만들기를 클릭하고 알림 허브를 검색하고 Enter 키를 클릭합니다.

    알림 허브 검색

    참고

    New라는 단어가 최신 포털에서 리소스 만들기로 대체되었을 수 있습니다.

  3. 새 페이지에서 Notification Hubs 서비스에 대한 설명을 제공합니다. 이 프롬프트의 왼쪽 아래에서 만들기 단추를 선택하여 이 서비스와의 연결을 만듭니다.

    알림 허브 만들기 instance

  4. 만들기를 클릭한 후에는 다음을 수행합니다.

    1. 이 서비스 instance 원하는 이름을 삽입합니다.

    2. 이 앱과 연결할 수 있는 네임스페이스를 제공합니다.

    3. 위치를 선택합니다 .

    4. 리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 액세스를 모니터링, 제어, 프로비전 및 관리하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 랩)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.

      Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹을 관리하는 방법에 대한 이 링크를 따르세요.

    5. 적절한 구독을 선택합니다.

    6. 또한 이 서비스에 적용된 사용 약관을 이해했음을 확인해야 합니다.

    7. 만들기를 선택합니다.

      서비스 세부 정보 입력

  5. 만들기를 클릭하면 서비스가 만들어질 때까지 기다려야 합니다. 이 작업은 1분 정도 걸릴 수 있습니다.

  6. 서비스 instance 만들어지면 포털에 알림이 표시됩니다.

    알림

  7. 알림에서 리소스로 이동 단추를 클릭하여 새 서비스 instance 탐색합니다. 새 Notification Hub 서비스 instance 이동합니다.

    알림 창에 강조 표시된 '리소스로 이동' 단추를 보여 주는 스크린샷

  8. 개요 페이지에서 페이지 중간에 Windows(WNS)를 클릭합니다. 오른쪽 패널은 이전에 설정한 앱에서 패키지 SID보안 키가 필요한 두 개의 텍스트 필드를 표시하도록 변경됩니다.

    새로 만든 허브 서비스

  9. 세부 정보를 올바른 필드에 복사한 후 저장을 클릭하면 알림 허브가 성공적으로 업데이트되면 알림이 표시됩니다.

    보안 세부 정보 복사

4장 - Azure Portal 설정: Table Service 만들기

Notification Hubs Service instance 만든 후 Azure Portal로 다시 이동하여 스토리지 리소스를 만들어 Azure Tables Service를 만듭니다.

  1. 아직 로그인하지 않은 경우 Azure Portal에 로그인합니다.

  2. 로그인한 후 왼쪽 위 모서리에서 새로 만들기를 클릭하고 Storage 계정을 검색한 후 Enter 키를 클릭합니다.

    참고

    단어는 최신 포털에서 리소스 만들기로 대체되었을 수 있습니다.

  3. 목록에서 스토리지 계정 - Blob, 파일, 테이블, 큐 를 선택합니다.

    스토리지 계정 검색

  4. 새 페이지에서는 Storage 계정 서비스에 대한 설명을 제공합니다. 이 프롬프트의 왼쪽 아래에서 만들기 단추를 선택하여 이 서비스의 instance 만듭니다.

    스토리지 instance 만들기

  5. 만들기를 클릭하면 패널이 표시됩니다.

    1. 이 서비스 instance 원하는 이름을 삽입합니다(모두 소문자여야 합니다).

    2. 배포 모델의 경우 리소스 관리자를 클릭합니다.

    3. 계정 종류에 대해 드롭다운 메뉴를 사용하여 스토리지(범용 v1)를 선택합니다.

    4. 적절한 위치를 선택합니다.

    5. 복제 드롭다운 메뉴에서 RA-GRS(읽기 액세스 지역 중복 스토리지)를 선택합니다.

    6. 성능을 위해 표준을 클릭합니다.

    7. 보안 전송 필요 섹션 내에서 사용 안 함을 선택합니다.

    8. 구독 드롭다운 메뉴에서 적절한 구독을 선택합니다.

    9. 리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 액세스를 모니터링, 제어, 프로비전 및 관리하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 랩)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.

      Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹을 관리하는 방법에 대한 이 링크를 따르세요.

    10. 가상 네트워크가 옵션인 경우 사용 안 함으로 둡니다.

    11. 만들기를 클릭합니다.

      스토리지 세부 정보 입력

  6. 만들기를 클릭하면 서비스가 만들어질 때까지 기다려야 합니다. 이 작업은 1분 정도 걸릴 수 있습니다.

  7. 서비스 instance 만들어지면 포털에 알림이 표시됩니다. 알림을 클릭하여 새 서비스 instance 탐색합니다.

    새 스토리지 알림

  8. 알림에서 리소스로 이동 단추를 클릭하여 새 서비스 instance 탐색합니다. 새 Storage Service instance 개요 페이지로 이동합니다.

    '배포 성공' 창에 강조 표시된 '리소스로 이동' 단추를 보여 주는 스크린샷.

  9. 개요 페이지의 오른쪽에서 테이블을 클릭합니다.

    테이블을 선택할 위치를 보여 주는 스크린샷

  10. 오른쪽의 패널이 변경되어 새 테이블을 추가해야 하는 테이블 서비스 정보를 표시합니다. 왼쪽 위 모서리에 있는 +테이블 단추를 클릭하여 이 작업을 수행합니다.

    테이블 열기

  11. 테이블 이름을 입력해야 하는 새 페이지가 표시됩니다. 이후 챕터에서 애플리케이션의 데이터를 참조하는 데 사용할 이름입니다. 적절한 이름을 삽입하고 확인을 클릭합니다.

    새 테이블 만들기

  12. 새 테이블이 만들어지면 테이블 서비스 페이지(아래쪽)에서 볼 수 있습니다.

    만든 새 테이블

5장 - Visual Studio에서 Azure 테이블 완료

Table Service 스토리지 계정이 설정되었으므로 이제 정보를 저장하고 검색하는 데 사용할 데이터를 추가할 차례입니다. 테이블 편집은 Visual Studio를 통해 수행할 수 있습니다.

  1. Visual Studio를 엽니다.

  2. 메뉴에서클라우드 Explorer보기를> 클릭합니다.

    클라우드 탐색기 열기

  3. 클라우드 Explorer 도킹된 항목으로 열립니다(로드하는 데 시간이 걸릴 수 있으므로 인내심을 가져야 합니다).

    참고

    스토리지 계정을 만드는 데 사용한 구독이 표시되지 않는 경우 다음이 있는지 확인합니다.

    • Azure Portal에 사용한 계정과 동일한 계정에 로그인했습니다.

    • 계정 관리 페이지에서 구독을 선택했습니다(계정 설정에서 필터를 적용해야 할 수 있음).

      구독 찾기

  4. Azure 클라우드 서비스가 표시됩니다. 스토리지 계정을 찾고 왼쪽에 있는 화살표를 클릭하여 계정을 확장합니다.

    스토리지 계정 열기

  5. 확장되면 새로 만든 Storage 계정을 사용할 수 있어야 합니다. 저장소 왼쪽에 있는 화살표를 클릭한 다음 확장되면 테이블을 찾아 옆에 있는 화살표를 클릭하여 마지막 챕터에서 만든 테이블을 표시합니다. 테이블을 두 번 클릭합니다.

    장면 개체 테이블 열기

  6. Visual Studio 창의 가운데에 테이블이 열립니다. (더하기)가 있는 + 테이블 아이콘을 클릭합니다.

    새 테이블 추가

  7. 엔터티 추가를 묻는 창이 나타납니다. 각각 여러 속성을 사용하여 총 세 개의 엔터티를 만듭니다. 테이블에서 데이터를 찾는 데 사용되므로 PartitionKeyRowKey 가 이미 제공된 것을 알 수 있습니다.

    파티션 및 행 키

  8. 다음과 같이 PartitionKeyRowKey값을 업데이트합니다(매번 RowKey를 증가하지만 추가하는 각 행 속성에 대해 이 작업을 수행해야 함).

    올바른 값 추가

  9. 속성 추가를 클릭하여 추가 데이터 행을 추가합니다. 첫 번째 빈 테이블을 아래 표와 일치하게 만듭니다.

  10. 작업이 끝나면 확인을 클릭합니다.

    완료되면 확인을 클릭합니다.

    경고

    X, YZ형식 항목이 Double로 변경되었는지 확인합니다.

  11. 이제 테이블에 데이터 행이 있음을 알 수 있습니다. (더하기) 아이콘을 + 다시 클릭하여 다른 엔터티를 추가합니다.

    첫 번째 행

  12. 추가 속성을 만든 다음 아래와 일치하도록 새 엔터티의 값을 설정합니다.

    큐브 추가

  13. 마지막 단계를 반복하여 다른 엔터티를 추가합니다. 이 엔터티의 값을 아래 표시된 값으로 설정합니다.

    실린더 추가

  14. 이제 테이블이 아래와 같이 표시됩니다.

    테이블 완료

  15. 이 챕터를 완료했습니다. 저장해야 합니다.

6장 - Azure 함수 앱 만들기

테이블 서비스를 업데이트 하고 알림 허브를 통해 알림을 보내기 위해 데스크톱 애플리케이션에서 호출되는 Azure Function App을 만듭니다.

먼저 Azure Function에서 필요한 라이브러리를 로드할 수 있는 파일을 만들어야 합니다.

  1. 메모장을 엽니다(Windows 키를 누르고 메모장을 입력).

    메모장 열기

  2. 메모장을 연 상태에서 아래에 JSON 구조를 삽입합니다. 이렇게 하면 데스크톱에 project.json으로 저장합니다. 이름이 올바르다는 것이 중요합니다. .txt파일 확장 명이 없는지 확인합니다. 이 파일은 함수에서 사용할 라이브러리를 정의합니다. NuGet을 사용한 경우 익숙해 보일 것입니다.

    {
    "frameworks": {
        "net46":{
        "dependencies": {
            "WindowsAzure.Storage": "7.0.0",
            "Microsoft.Azure.NotificationHubs" : "1.0.9",
            "Microsoft.Azure.WebJobs.Extensions.NotificationHubs" :"1.1.0"
        }
        }
    }
    }
    
  3. Azure Portal에 로그인합니다.

  4. 로그인한 후 왼쪽 위 모서리에서 새로 만들기를 클릭하고 함수 앱을 검색한 후 Enter 키를 누릅니다.

    함수 앱 검색

    참고

    단어는 최신 포털에서 리소스 만들기로 대체되었을 수 있습니다.

  5. 새 페이지에서 함수 서비스에 대한 설명을 제공합니다. 이 프롬프트의 왼쪽 아래에서 만들기 단추를 선택하여 이 서비스와의 연결을 만듭니다.

    함수 앱 instance

  6. 만들기를 클릭하면 다음을 입력합니다.

    1. 앱 이름에 이 서비스 instance 원하는 이름을 삽입합니다.

    2. 구독을 선택합니다.

    3. 적합한 가격 책정 계층을 선택합니다. 함수 App Service 처음 만드는 경우 무료 계층을 사용할 수 있어야 합니다.

    4. 리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 액세스를 모니터링, 제어, 프로비전 및 관리하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 랩)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.

      Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹을 관리하는 방법에 대한 이 링크를 따르세요.

    5. OS의 경우 의도한 플랫폼이므로 Windows를 클릭합니다.

    6. 호스팅 계획을 선택합니다(이 자습서에서는 소비 계획을 사용합니다.)

    7. 위치를 선택합니다(이전 단계에서 빌드한 스토리지와 동일한 위치 선택)

    8. Storage 섹션의 경우 이전 단계에서 만든 Storage 서비스를 선택해야 합니다.

    9. 이 앱에는 Application Insights가 필요하지 않으므로 자유롭게 십시오.

    10. 만들기를 클릭합니다.

      새 instance 만들기

  7. 만들기를 클릭하면 서비스가 만들어질 때까지 기다려야 합니다. 이 작업은 1분 정도 걸릴 수 있습니다.

  8. 서비스 instance 만들어지면 포털에 알림이 표시됩니다.

    새 알림

  9. 알림을 클릭하여 새 서비스 instance 탐색합니다.

  10. 알림에서 리소스로 이동 단추를 클릭하여 새 서비스 instance 탐색합니다.

    '리소스로 이동' 단추가 강조 표시된 '배포 성공'을 보여 주는 스크린샷

  11. 함수 옆에 있는 + (더하기) 아이콘 클릭하여 새로 만들기를 클릭합니다.

    새 함수 추가

  12. 중앙 패널 내에 함수 만들기 창이 나타납니다. 패널의 위쪽 절반에 있는 정보를 무시하고 아래와 같이 파란색 영역의 아래쪽 근처에 있는 사용자 지정 함수를 클릭합니다.

    사용자 지정 함수

  13. 창 내의 새 페이지에는 다양한 함수 형식이 표시됩니다. 아래로 스크롤하여 자주색 형식을 보고 HTTP PUT 요소를 클릭합니다.

    http put 링크

    중요

    페이지 아래로 스크롤해야 할 수 있습니다(Azure Portal 업데이트가 수행된 경우 이 이미지가 정확히 동일하지 않을 수 있음). 그러나 HTTP PUT이라는 요소를 찾고 있습니다.

  14. 함수를 구성해야 하는 HTTP PUT 창이 나타납니다(이미지의 경우 아래 참조).

    1. 언어의 경우 드롭다운 메뉴를 사용하여 C#을 선택합니다.

    2. 이름에 적절한 이름을 입력합니다.

    3. 인증 수준 드롭다운 메뉴에서 함수를 선택합니다.

    4. 테이블 이름 섹션의 경우 이전에 Table Service를 만드는 데 사용한 정확한 이름(동일한 문자 대/소문자 포함)을 사용해야 합니다.

    5. 스토리지 계정 연결 섹션 내에서 드롭다운 메뉴를 사용하고 해당 위치에서 스토리지 계정을 선택합니다. 없는 경우 섹션 제목과 함께 하이퍼링크를 클릭하여 스토리지 계정을 나열해야 하는 다른 패널을 표시합니다.

      '새로 만들기' 하이퍼링크가 선택된 스토리지 계정 연결 섹션을 보여 주는 스크린샷

  15. 만들기를 클릭하면 설정이 성공적으로 업데이트되었다는 알림이 표시됩니다.

    create 함수

  16. 만들기를 클릭하면 함수 편집기로 리디렉션됩니다.

    함수 코드 업데이트

  17. 함수 편집기에 다음 코드를 삽입합니다(함수의 코드를 대체).

    #r "Microsoft.WindowsAzure.Storage"
    
    using System;
    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Table;
    using Microsoft.Azure.NotificationHubs;
    using Newtonsoft.Json;
    
    public static async Task Run(UnityGameObject gameObj, CloudTable table, IAsyncCollector<Notification> notification, TraceWriter log)
    {
        //RowKey of the table object to be changed
        string rowKey = gameObj.RowKey;
    
        //Retrieve the table object by its RowKey
        TableOperation operation = TableOperation.Retrieve<UnityGameObject>("UnityPartitionKey", rowKey); 
    
        TableResult result = table.Execute(operation);
    
        //Create a UnityGameObject so to set its parameters
        UnityGameObject existingGameObj = (UnityGameObject)result.Result; 
    
        existingGameObj.RowKey = rowKey;
        existingGameObj.X = gameObj.X;
        existingGameObj.Y = gameObj.Y;
        existingGameObj.Z = gameObj.Z;
    
        //Replace the table appropriate table Entity with the value of the UnityGameObject
        operation = TableOperation.Replace(existingGameObj); 
    
        table.Execute(operation);
    
        log.Verbose($"Updated object position");
    
        //Serialize the UnityGameObject
        string wnsNotificationPayload = JsonConvert.SerializeObject(existingGameObj);
    
        log.Info($"{wnsNotificationPayload}");
    
        var headers = new Dictionary<string, string>();
    
        headers["X-WNS-Type"] = @"wns/raw";
    
        //Send the raw notification to subscribed devices
        await notification.AddAsync(new WindowsNotification(wnsNotificationPayload, headers)); 
    
        log.Verbose($"Sent notification");
    }
    
    // This UnityGameObject represent a Table Entity
    public class UnityGameObject : TableEntity
    {
        public string Type { get; set; }
        public double X { get; set; }
        public double Y { get; set; }
        public double Z { get; set; }
        public string RowKey { get; set; }
    }
    

    참고

    포함된 라이브러리를 사용하여 함수는 Unity 장면에서 이동된 개체의 이름과 위치를 받습니다( UnityGameObject라는 C# 개체). 그런 다음 이 개체를 사용하여 만든 테이블 내의 개체 매개 변수를 업데이트합니다. 그런 다음 함수는 모든 구독된 애플리케이션에 알리는 생성된 Notification Hub 서비스를 호출합니다.

  18. 코드가 있는 상태에서 저장을 클릭합니다.

  19. 그런 다음 페이지의 오른쪽에 있는 (화살표) 아이콘을 클릭합니다 < .

    업로드 패널 열기

  20. 패널이 오른쪽에서 안쪽으로 밉니다. 해당 패널에서 업로드를 클릭하면 파일 브라우저가 나타납니다.

  21. 이전에 메모장에서 만든 project.json 파일로 이동하여 클릭한 다음 열기 단추를 클릭합니다. 이 파일은 함수에서 사용할 라이브러리를 정의합니다.

    json 업로드

  22. 파일이 업로드되면 오른쪽 패널에 표시됩니다. 클릭하면 함수 편집기 내에서 열립니다. 다음 이미지와 정확히 동일해야 합니다(23단계 아래).

  23. 그런 다음 왼쪽 패널의 함수 아래에서 통합 링크를 클릭합니다.

    integration 함수

  24. 다음 페이지의 오른쪽 위 모서리에서 고급 편집 기(아래)를 클릭합니다.

    고급 편집기 열기

  25. function.json 파일이 가운데 패널에서 열립니다. 이 파일은 다음 코드 조각으로 바꿔야 합니다. 빌드 중인 함수와 함수에 전달된 매개 변수를 정의합니다.

    {
    "bindings": [
        {
        "authLevel": "function",
        "type": "httpTrigger",
        "methods": [
            "get",
            "post"
        ],
        "name": "gameObj",
        "direction": "in"
        },
        {
        "type": "table",
        "name": "table",
        "tableName": "SceneObjectsTable",
        "connection": "mrnothubstorage_STORAGE",
        "direction": "in"
        },
        {
        "type": "notificationHub",
        "direction": "out",
        "name": "notification",
        "hubName": "MR_NotHub_ServiceInstance",
        "connection": "MRNotHubNS_DefaultFullSharedAccessSignature_NH",
        "platform": "wns"
        }
    ]
    }
    
  26. 이제 편집기가 아래 이미지와 같이 표시됩니다.

    표준 편집기로 돌아가기

  27. 방금 삽입한 입력 매개 변수가 테이블 및 스토리지 세부 정보와 일치하지 않을 수 있으므로 정보로 업데이트해야 합니다. 다음에 설명되어 있으므로 여기서는 이 작업을 수행하지 마세요. 페이지의 오른쪽 위 모서리에 있는 표준 편집 기 링크를 클릭하여 돌아가면 됩니다.

  28. 표준 편집기로 돌아가서 입력에서 Azure Table Storage(테이블)를 클릭합니다.

    테이블 입력

  29. 다음 정보가 다를 수 있으므로 다음과 일치하는 지 확인합니다(다음 단계 아래에 이미지가 있음).

    1. 테이블 이름: Azure Storage, Tables 서비스 내에서 만든 테이블의 이름입니다.

    2. 스토리지 계정 연결: 드롭다운 메뉴와 함께 표시되는 새로 만들기를 클릭하면 창 오른쪽에 패널이 나타납니다.

      창 오른쪽 패널에 '새로 만들기'가 강조 표시된 스토리지 계정 창을 보여 주는 스크린샷

      1. 이전에 함수 앱을 호스트하기 위해 만든 스토리지 계정을 선택합니다.

      2. Storage 계정 연결 값이 생성되었음을 알 수 있습니다.

      3. 완료되면 저장 을 눌러야 합니다.

    3. 이제 입력 페이지가 아래와 일치하여 정보가 표시됩니다.

      입력 완료

  30. 다음으로, 출력에서 Azure Notification Hub(알림) - 를 클릭합니다. 다음과 같은 정보가 다를 수 있으므로 사용자 정보와 일치하는지 확인합니다(다음 단계 아래에 이미지가 있음).

    1. 알림 허브 이름: 이전에 만든 Notification Hub 서비스 instance 이름입니다.

    2. Notification Hubs 네임스페이스 연결: 드롭다운 메뉴와 함께 표시되는 새로 만들기를 클릭합니다.

      검사 출력

    3. 연결 팝업이 표시됩니다(아래 이미지 참조). 여기서 이전에 설정한 Notification Hub네임스페이스를 선택해야 합니다.

    4. 가운데 드롭다운 메뉴에서 알림 허브 이름을 선택합니다.

    5. 정책 드롭다운 메뉴를 DefaultFullSharedAccessSignature로 설정합니다.

    6. 선택 단추를 클릭하여 돌아갑니다.

      출력 업데이트

  31. 출력 페이지는 이제 아래와 일치하지만 대신 사용자 정보와 일치해야 합니다 . 저장을 눌러야 합니다.

경고

알림 허브 이름을 직접 편집하지 마세요(이전 단계를 올바르게 수행한 경우 모두 고급 편집기 사용하여 수행해야 합니다.

일반 정보가 포함된 출력 페이지를 보여 주는 스크린샷.

  1. 이 시점에서 함수가 작동하는지 테스트해야 합니다. 가상 하드 디스크 파일에 대한 중요 정보를 제공하려면

    1. 함수 페이지로 다시 한 번 이동합니다.

      새로 만든 함수가 강조 표시된 함수 페이지를 보여 주는 스크린샷

    2. 함수 페이지로 돌아가서 페이지의 맨 오른쪽에 있는 테스트 탭을 클릭하여 테스트 블레이드를 엽니다.

      오른쪽에 '테스트'가 강조 표시된 함수 페이지의 스크린샷.

    3. 블레이드의 요청 본문 텍스트 상자에 아래 코드를 붙여넣습니다.

      {  
          "Type":null,
          "X":3,
          "Y":0,
          "Z":1,
          "PartitionKey":null,
          "RowKey":"Obj2",
          "Timestamp":"0001-01-01T00:00:00+00:00",
          "ETag":null
      }
      
    4. 테스트 코드가 있는 상태에서 오른쪽 아래에 있는 실행 단추를 클릭하면 테스트가 실행됩니다. 테스트의 출력 로그는 함수 코드 아래의 콘솔 영역에 표시됩니다.

      콘솔 영역에서 테스트의 출력 로그를 보여 주는 스크린샷

    경고

    위의 테스트가 실패하는 경우 위의 단계, 특히 통합 패널 내의 설정을 정확히 수행한 검사 두 배로 해야 합니다.

7장 - Desktop Unity 프로젝트 설정

중요

현재 만들고 있는 데스크톱 애플리케이션은 Unity 편집기에서 작동하지 않습니다 . Visual Studio(또는 배포된 애플리케이션)를 사용하여 애플리케이션 빌드에 따라 편집기 외부에서 실행해야 합니다.

다음은 Unity 및 혼합 현실로 개발하기 위한 일반적인 설정이며, 따라서 다른 프로젝트에 적합한 템플릿입니다.

혼합 현실 몰입형 헤드셋을 설정하고 테스트합니다.

참고

이 과정에는 모션 컨트롤러가 필요하지 않습니다 . 몰입형 헤드셋 설정을 지원해야 하는 경우 Windows Mixed Reality 설정하는 방법에 대한 이 링크를 따르세요.

  1. Unity를 열고 새로 만들기를 클릭합니다.

    오른쪽 위에 '새로 만들기' 프로젝트 아이콘이 강조 표시된 Unity 프로젝트 창의 스크린샷

  2. Unity 프로젝트 이름을 제공하고 UnityDesktopNotifHub를 삽입해야 합니다. 프로젝트 형식이 3D로 설정되어 있는지 확인합니다. 위치를 적절한 위치로 설정합니다(루트 디렉터리에 더 가까울수록 좋습니다). 그런 다음 프로젝트 만들기를 클릭합니다.

    프로젝트 만들기

  3. Unity를 열면 기본 스크립트 편집 기가 Visual Studio로 설정되어 있는지 확인할 필요가 있습니다. 기본 설정편집>으로 이동한 다음 새 창에서 외부 도구로 이동합니다. 외부 스크립트 편집기를 Visual Studio 2017로 변경합니다. 기본 설정 창을 닫습니다.

    외부 VS 도구 설정

  4. 다음으로 파일>빌드 설정으로 이동하여 유니버설 Windows 플랫폼 선택한 다음 플랫폼 전환 단추를 클릭하여 선택 항목을 적용합니다.

    플랫폼 전환

  5. 파일>빌드 설정에 있는 동안 다음을 확인합니다.

    1. 대상 디바이스모든 디바이스로 설정됩니다.

      이 애플리케이션은 데스크톱용이므로 모든 디바이스여야 합니다.

    2. 빌드 유형D3D로 설정됨

    3. SDK최신 설치됨으로 설정됨

    4. Visual Studio 버전최신 설치됨으로 설정됨

    5. 빌드 및 실행로컬 컴퓨터로 설정됩니다.

    6. 여기서는 장면을 저장하고 빌드에 추가하는 것이 좋습니다.

      1. 열린 장면 추가를 선택하여 이 작업을 수행합니다. 저장 창이 나타납니다.

        오른쪽 위에 강조 표시된 '열린 장면 추가'를 보여 주는 스크린샷

      2. 이에 대한 새 폴더를 만들고 이후의 장면에 대해 새 폴더 를 만든 다음 새 폴더 단추를 선택하여 새 폴더를 만들고 이름을 Scenes로 지정 합니다.

        왼쪽 위에 '새 폴더'가 강조 표시된 새 Scenes 폴더를 보여 주는 스크린샷

      3. 새로 만든 Scenes 폴더를 연 다음 파일 이름: 텍스트 필드에 NH_Desktop_Scene 입력한 다음 저장을 누릅니다.

        새 NH_Desktop_Scene

    7. 빌드 설정의 나머지 설정은 현재 기본값으로 남아 있어야 합니다.

  6. 동일한 창에서 플레이어 설정 단추를 클릭하면 Inspector 가 있는 공간에서 관련 패널이 열립니다.

  7. 이 패널에서 몇 가지 설정을 확인해야 합니다.

    1. 기타 설정 탭에서 다음을 수행합니다.

      1. 런타임 버전 스크립팅실험적이어야 합니다(.NET 4.6 동등).

      2. 백 엔드 스크립팅.NET이어야 합니다.

      3. API 호환성 수준은.NET 4.6이어야 합니다.

        4.6 net 버전

    2. 게시 설정 탭의 기능에서 다음을 검사.

      • InternetClient

        기능에서 선택한 InternetClient를 보여 주는 스크린샷

  8. 빌드 설정으로 돌아가서 Unity C# 프로젝트는 더 이상 회색으로 표시되지 않습니다. 이 옆에 있는 확인란을 선택합니다.

  9. 빌드 설정 창을 닫습니다.

  10. 장면 및 프로젝트 파일>저장 장면/파일>저장 프로젝트를 저장합니다.

    중요

    이 프로젝트의 Unity 설정 구성 요소(데스크톱 앱)를 건너뛰고 코드를 계속 진행하려면 이 .unitypackage를 자유롭게 다운로드하고 사용자 지정 패키지로 프로젝트로 가져온 다음 9장에서 계속 진행하세요. 스크립트 구성 요소를 추가해야 합니다.

8장 - Unity에서 DLL 가져오기

Unity용 Azure Storage를 사용합니다(자체에서 Azure용 .Net SDK를 활용). 자세한 내용은 Unity용 Azure Storage에 대한 이 링크를 참조하세요.

현재 Unity에는 가져온 후 플러그 인을 다시 구성해야 하는 알려진 문제가 있습니다. 버그가 해결된 후에는 이러한 단계(이 섹션의 4~7)가 더 이상 필요하지 않습니다.

SDK를 사용자 고유의 프로젝트로 가져오려면 GitHub에서 최신 .unitypackage 를 다운로드했는지 확인합니다. 그런 후 다음을 수행합니다.

  1. 자산 패키지 사용자 지정 패키지 > 가져오기 메뉴 옵션을 사용하여 .unitypackage를 Unity에 추가합니다>.

  2. 팝업되는 Unity 패키지 가져오기 상자에서 플러그 인>스토리지에서 모든 항목을 선택할 수 있습니다. 이 과정에 필요하지 않으므로 다른 모든 항목을 선택 취소합니다.

    패키지로 가져오기

  3. 가져오기 단추를 클릭하여 프로젝트에 항목을 추가합니다.

  4. 프로젝트 보기의 플러그 인 아래에 있는 Storage 폴더로 이동하여 다음 플러그 인 선택합니다.

    • Microsoft.Data.Edm
    • Microsoft.Data.OData
    • Microsoft.WindowsAzure.Storage
    • Newtonsoft.Json
    • System.Spatial

모든 플랫폼 선택 취소

  1. 이러한 특정 플러그 인을 선택한 상태에서 모든 플랫폼의 선택을 취소하고 WSAPlayer의 선택을 취소한 다음 적용을 클릭합니다.

    플랫폼 dll 적용

    참고

    이러한 특정 플러그 인은 Unity 편집기에서만 사용하도록 표시하고 있습니다. 이는 프로젝트를 Unity에서 내보낸 후 사용될 WSA 폴더에 동일한 플러그 인의 버전이 서로 다르기 때문입니다.

  2. Storage 플러그 인 폴더에서 다음만 선택합니다.

    • Microsoft.Data.Services.Client

      dll에 대해 set don't process

  3. 플랫폼 설정에서 처리 안 함 상자를 선택하고 적용을 클릭합니다.

    처리 없음 적용

    참고

    Unity 어셈블리 패치가 이 플러그 인을 처리하는 데 어려움을 겪기 때문에 이 플러그 인 "처리 안 함"을 표시하고 있습니다. 플러그 인은 처리되지 않더라도 계속 작동합니다.

9장 - Desktop Unity 프로젝트에서 TableToScene 클래스 만들기

이제 이 애플리케이션을 실행하려면 코드가 포함된 스크립트를 만들어야 합니다.

만들어야 하는 첫 번째 스크립트는 다음과 같은 역할을 하는 TableToScene입니다.

  • Azure Table 내에서 엔터티를 읽습니다.
  • Table 데이터를 사용하여 생성할 개체와 위치를 결정합니다.

만들어야 하는 두 번째 스크립트는 CloudScene입니다. 이 스크립트는 다음을 담당합니다.

  • 사용자가 장면 주위에 개체를 끌 수 있도록 왼쪽 클릭 이벤트를 등록합니다.
  • 이 Unity 장면에서 개체 데이터를 직렬화하고 Azure Function App으로 보냅니다.

이 클래스를 만들려면 다음을 수행합니다.

  1. 프로젝트 패널의 폴더 만들기에 있는 자산폴더를 마우스 오른쪽 단추> 클릭합니다. 폴더 이름을 Scripts로 지정합니다.

    스크립트 폴더 만들기

    스크립트 만들기 폴더 2

  2. 방금 만든 폴더를 두 번 클릭하여 엽니다.

  3. Scripts 폴더 내부를 마우스 오른쪽 단추로 클릭하고C# 스크립트만들기>를 클릭합니다. 스크립트 이름을 TableToScene으로 지정합니다.

    새 'TableToScene' 스크립트를 만드는 방법을 보여 주는 스크린샷TableToScene 이름 바꾸기

  4. 스크립트를 두 번 클릭하여 Visual Studio 2017에서 엽니다.

  5. 다음 네임스페이스를 추가합니다.

    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Auth;
    using Microsoft.WindowsAzure.Storage.Table;
    using UnityEngine;
    
  6. 클래스 내에서 다음 변수를 삽입합니다.

        /// <summary>    
        /// allows this class to behave like a singleton
        /// </summary>    
        public static TableToScene instance;
    
        /// <summary>    
        /// Insert here you Azure Storage name     
        /// </summary>    
        private string accountName = " -- Insert your Azure Storage name -- ";
    
        /// <summary>    
        /// Insert here you Azure Storage key    
        /// </summary>    
        private string accountKey = " -- Insert your Azure Storage key -- ";
    

    참고

    accountName 값을 Azure Storage 서비스 이름 및 accountKey 값으로 Azure Portal의 Azure Storage 서비스에 있는 키 값으로 바꿉니다(아래 이미지 참조).

    계정 키 가져오기

  7. 이제 Start()Awake() 메서드를 추가하여 클래스를 초기화합니다.

        /// <summary>
        /// Triggers before initialization
        /// </summary>
        void Awake()
        {
            // static instance of this class
            instance = this;
        }
    
        /// <summary>
        /// Use this for initialization
        /// </summary>
        void Start()
        {  
            // Call method to populate the scene with new objects as 
            // pecified in the Azure Table
            PopulateSceneFromTableAsync();
        }
    
  8. TableToScene 클래스 내에서 Azure Table에서 값을 검색하고 이를 사용하여 장면에 적절한 기본 형식을 생성하는 메서드를 추가합니다.

        /// <summary>    
        /// Populate the scene with new objects as specified in the Azure Table    
        /// </summary>    
        private async void PopulateSceneFromTableAsync()
        {
            // Obtain credentials for the Azure Storage
            StorageCredentials creds = new StorageCredentials(accountName, accountKey);
    
            // Storage account
            CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true);
    
            // Storage client
            CloudTableClient client = account.CreateCloudTableClient(); 
    
            // Table reference
            CloudTable table = client.GetTableReference("SceneObjectsTable");
    
            TableContinuationToken token = null;
    
            // Query the table for every existing Entity
            do
            {
                // Queries the whole table by breaking it into segments
                // (would happen only if the table had huge number of Entities)
                TableQuerySegment<AzureTableEntity> queryResult = await table.ExecuteQuerySegmentedAsync(new TableQuery<AzureTableEntity>(), token); 
    
                foreach (AzureTableEntity entity in queryResult.Results)
                {
                    GameObject newSceneGameObject = null;
                    Color newColor;
    
                    // check for the Entity Type and spawn in the scene the appropriate Primitive
                    switch (entity.Type)
                    {
                        case "Cube":
                            // Create a Cube in the scene
                            newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
                            newColor = Color.blue;
                            break;
    
                        case "Sphere":
                            // Create a Sphere in the scene
                            newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                            newColor = Color.red;
                            break;
    
                        case "Cylinder":
                            // Create a Cylinder in the scene
                            newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                            newColor = Color.yellow;
                            break;
                        default:
                            newColor = Color.white;
                            break;
                    }
    
                    newSceneGameObject.name = entity.RowKey;
    
                    newSceneGameObject.GetComponent<MeshRenderer>().material = new Material(Shader.Find("Diffuse"))
                    {
                        color = newColor
                    };
    
                    //check for the Entity X,Y,Z and move the Primitive at those coordinates
                    newSceneGameObject.transform.position = new Vector3((float)entity.X, (float)entity.Y, (float)entity.Z);
                }
    
                // if the token is null, it means there are no more segments left to query
                token = queryResult.ContinuationToken;
            }
    
            while (token != null);
        }
    
  9. TableToScene 클래스 외부에서는 애플리케이션에서 Table Entities를 직렬화하고 역직렬화하는 데 사용하는 클래스를 정의해야 합니다.

        /// <summary>
        /// This objects is used to serialize and deserialize the Azure Table Entity
        /// </summary>
        [System.Serializable]
        public class AzureTableEntity : TableEntity
        {
            public AzureTableEntity(string partitionKey, string rowKey)
                : base(partitionKey, rowKey) { }
    
            public AzureTableEntity() { }
            public string Type { get; set; }
            public double X { get; set; }
            public double Y { get; set; }
            public double Z { get; set; }
        }
    
  10. Unity 편집기로 돌아가기 전에 저장 해야 합니다.

  11. 계층 구조 패널에서 기본 카메라를 클릭하여 해당 속성이 검사기에서 표시되도록 합니다.

  12. Scripts 폴더가 열려 있는 상태에서 TableToScene 스크립트 파일을 선택하고 주 카메라로 끕니다. 결과는 다음과 같습니다.

    기본 카메라에 스크립트 추가

10장 - Desktop Unity 프로젝트에서 CloudScene 클래스 만들기

만들어야 하는 두 번째 스크립트는 CloudScene입니다. 이 스크립트는 다음을 담당합니다.

  • 사용자가 장면 주위에 개체를 끌 수 있도록 왼쪽 클릭 이벤트를 등록합니다.

  • 이 Unity 장면에서 개체 데이터를 직렬화하고 Azure Function App으로 보냅니다.

두 번째 스크립트를 만들려면 다음을 수행합니다.

  1. Scripts 폴더 내부를 마우스 오른쪽 단추로 클릭하고 만들기, C# 스크립트를 클릭합니다. 스크립트 이름을 CloudScene으로 지정합니다.

    새 'CloudScene' 스크립트를 만드는 방법을 보여 주는 스크린샷rename CloudScene

  2. 다음 네임스페이스를 추가합니다.

    using Newtonsoft.Json;
    using System.Collections;
    using System.Text;
    using System.Threading.Tasks;
    using UnityEngine;
    using UnityEngine.Networking;
    
  3. 다음 변수를 삽입합니다.

        /// <summary>
        /// Allows this class to behave like a singleton
        /// </summary>
        public static CloudScene instance;
    
        /// <summary>
        /// Insert here you Azure Function Url
        /// </summary>
        private string azureFunctionEndpoint = "--Insert here you Azure Function Endpoint--";
    
        /// <summary>
        /// Flag for object being moved
        /// </summary>
        private bool gameObjHasMoved;
    
        /// <summary>
        /// Transform of the object being dragged by the mouse
        /// </summary>
        private Transform gameObjHeld;
    
        /// <summary>
        /// Class hosted in the TableToScene script
        /// </summary>
        private AzureTableEntity azureTableEntity;
    
  4. 아래 이미지와 같이 azureFunctionEndpoint 값을 Azure Portal의 Azure Function App Service 있는 Azure Function App URL로 대체합니다.

    get 함수 URL

  5. 이제 Start()Awake() 메서드를 추가하여 클래스를 초기화합니다.

        /// <summary>
        /// Triggers before initialization
        /// </summary>
        void Awake()
        {
            // static instance of this class
            instance = this;
        }
    
        /// <summary>
        /// Use this for initialization
        /// </summary>
        void Start()
        {
            // initialise an AzureTableEntity
            azureTableEntity = new AzureTableEntity();
        }
    
  6. Update() 메서드 내에서 마우스 입력을 감지하고 끌어서 장면에서 GameObjects를 이동하는 다음 코드를 추가합니다. 사용자가 개체를 끌어서 놓은 경우 개체의 이름과 좌표를 UpdateCloudScene() 메서드에 전달합니다. 이 메서드는 Azure 함수 앱 서비스를 호출하여 Azure 테이블을 업데이트하고 알림을 트리거합니다.

        /// <summary>
        /// Update is called once per frame
        /// </summary>
        void Update()
        {
            //Enable Drag if button is held down
            if (Input.GetMouseButton(0))
            {
                // Get the mouse position
                Vector3 mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10);
    
                Vector3 objPos = Camera.main.ScreenToWorldPoint(mousePosition);
    
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    
                RaycastHit hit;
    
                // Raycast from the current mouse position to the object overlapped by the mouse
                if (Physics.Raycast(ray, out hit))
                {
                    // update the position of the object "hit" by the mouse
                    hit.transform.position = objPos;
    
                    gameObjHasMoved = true;
    
                    gameObjHeld = hit.transform;
                }
            }
    
            // check if the left button mouse is released while holding an object
            if (Input.GetMouseButtonUp(0) && gameObjHasMoved)
            {
                gameObjHasMoved = false;
    
                // Call the Azure Function that will update the appropriate Entity in the Azure Table
                // and send a Notification to all subscribed Apps
                Debug.Log("Calling Azure Function");
    
                StartCoroutine(UpdateCloudScene(gameObjHeld.name, gameObjHeld.position.x, gameObjHeld.position.y, gameObjHeld.position.z));
            }
        }
    
  7. 이제 아래와 같이 UpdateCloudScene() 메서드를 추가합니다.

        private IEnumerator UpdateCloudScene(string objName, double xPos, double yPos, double zPos)
        {
            WWWForm form = new WWWForm();
    
            // set the properties of the AzureTableEntity
            azureTableEntity.RowKey = objName;
    
            azureTableEntity.X = xPos;
    
            azureTableEntity.Y = yPos;
    
            azureTableEntity.Z = zPos;
    
            // Serialize the AzureTableEntity object to be sent to Azure
            string jsonObject = JsonConvert.SerializeObject(azureTableEntity);
    
            using (UnityWebRequest www = UnityWebRequest.Post(azureFunctionEndpoint, jsonObject))
            {
                byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(jsonObject);
    
                www.uploadHandler = new UploadHandlerRaw(jsonToSend);
    
                www.uploadHandler.contentType = "application/json";
    
                www.downloadHandler = new DownloadHandlerBuffer();
    
                www.SetRequestHeader("Content-Type", "application/json");
    
                yield return www.SendWebRequest();
    
                string response = www.responseCode.ToString();
            }
        }
    
  8. 코드를 저장하고 Unity로 돌아갑니다.

  9. CloudScene 스크립트를주 카메라로 끌어옵니다.

    1. 계층 구조 패널에서 기본 카메라를 클릭하여 해당 속성이 검사기에서 표시되도록 합니다.

    2. Scripts 폴더가 열려 있는 상태에서 CloudScene 스크립트를 선택하고 주 카메라로 끕니다. 결과는 다음과 같습니다.

      클라우드 스크립트를 기본 카메라로 끌어다 놓기

11장 - UWP에 데스크톱 프로젝트 빌드

이제 이 프로젝트의 Unity 섹션에 필요한 모든 작업이 완료되었습니다.

  1. 빌드 설정(파일>빌드 설정)으로 이동합니다.

  2. 빌드 설정 창에서 빌드를 클릭합니다.

    유니버설 Windows 플랫폼 선택한 빌드 설정 창과 오른쪽 아래에 '빌드' 단추가 강조 표시된 스크린샷

  3. 파일 탐색기 창이 팝업되어 빌드할 위치를 묻는 메시지가 표시됩니다. 왼쪽 위 모서리에서 새 폴더를 클릭하여 새 폴더 를 만들고 이름을 BUILDS로 지정합니다.

    빌드용 새 폴더

    1. BUILDS 폴더를 열고 새 폴더를 한 번 더 사용하여 다른 폴더 를 만들고 이름을 NH_Desktop_App.

      폴더 이름 NH_Desktop_App

    2. NH_Desktop_App 선택되어 있습니다. 폴더 선택을 클릭합니다. 프로젝트를 빌드하는 데 1분 정도 걸립니다.

  4. 빌드 후 새 프로젝트의 위치를 보여 주는 파일 탐색기 표시됩니다. 하지만 다음 몇 챕터에서 먼저 다른 Unity 프로젝트를 만들어야 하므로 열 필요가 없습니다.

챕터 12 - Mixed Reality Unity 프로젝트 설정

다음은 혼합 현실로 개발하기 위한 일반적인 설정이며, 따라서 다른 프로젝트에 적합한 템플릿입니다.

  1. Unity를 열고 새로 만들기를 클릭합니다.

    오른쪽 위에 '새로 만들기'가 강조 표시된 Unity 프로젝트 창을 보여 주는 스크린샷

  2. 이제 Unity 프로젝트 이름을 제공하고 UnityMRNotifHub를 삽입해야 합니다. 프로젝트 형식이 3D로 설정되어 있는지 확인합니다. 위치를 적절한 위치로 설정합니다(루트 디렉터리에 더 가까울수록 좋습니다). 그런 다음 프로젝트 만들기를 클릭합니다.

    Name UnityMRNotifHub

  3. Unity를 열면 기본 스크립트 편집 기가 Visual Studio로 설정되어 있는지 확인할 필요가 있습니다. 기본 설정편집>으로 이동한 다음 새 창에서 외부 도구로 이동합니다. 외부 스크립트 편집기를 Visual Studio 2017로 변경합니다. 기본 설정 창을 닫습니다.

    외부 편집기를 VS로 설정

  4. 다음으로, 파일>빌드 설정으로 이동하여 플랫폼 전환 단추를 클릭하여 플랫폼을 유니버설 Windows 플랫폼전환합니다.

    플랫폼을 UWP로 전환

  5. 파일>빌드 설정으로 이동하여 다음을 확인합니다.

    1. 대상 디바이스모든 디바이스로 설정됩니다.

      Microsoft HoloLens 대상 디바이스HoloLens로 설정합니다.

    2. 빌드 유형D3D로 설정됨

    3. SDK최신 설치됨으로 설정됨

    4. Visual Studio 버전최신 설치됨으로 설정됨

    5. 빌드 및 실행로컬 컴퓨터로 설정됩니다.

    6. 여기서는 장면을 저장하고 빌드에 추가하는 것이 좋습니다.

      1. 열린 장면 추가를 선택하여 이 작업을 수행합니다. 저장 창이 나타납니다.

        오른쪽 위에 '열린 장면 추가' 단추가 강조 표시된 빌드 설정 창을 보여 주는 스크린샷

      2. 이에 대한 새 폴더를 만들고 이후의 장면에 대해 새 폴더 를 만든 다음 새 폴더 단추를 선택하여 새 폴더를 만들고 이름을 Scenes로 지정 합니다.

        장면 저장 창의 왼쪽 위에 강조 표시된 '새 폴더'를 보여 주는 스크린샷

      3. 새로 만든 Scenes 폴더를 연 다음 파일 이름: 텍스트 필드에 NH_MR_Scene 입력한 다음 저장을 누릅니다.

        새 장면 - NH_MR_Scene

    7. 빌드 설정의 나머지 설정은 현재 기본값으로 남아 있어야 합니다.

  6. 동일한 창에서 플레이어 설정 단추를 클릭하면 Inspector 가 있는 공간에서 관련 패널이 열립니다.

    플레이어 설정 열기

  7. 이 패널에서 몇 가지 설정을 확인해야 합니다.

    1. 기타 설정 탭에서 다음을 수행합니다.

      1. 런타임 버전 스크립팅실험적 이어야 합니다(.NET 4.6 동등).

      2. 백 엔드 스크립팅.NET이어야 합니다.

      3. API 호환성 수준은.NET 4.6이어야 합니다.

        api 호환성

    2. 패널 아래쪽의 XR 설정(게시 설정 아래에 있음)에서 Virtual Reality 지원됨을 체크하고 Windows Mixed Reality SDK가 추가되었는지 확인합니다.

      xr 설정 업데이트

    3. 게시 설정 탭의 기능에서 다음을 검사.

      • InternetClient

        InternetClient가 선택된 게시 설정 탭을 보여 주는 스크린샷

  8. 빌드 설정으로 돌아가면 Unity C# 프로젝트가 더 이상 회색으로 표시되지 않습니다. 옆의 확인란을 선택합니다.

  9. 이러한 변경이 완료되면 빌드 설정 창을 닫습니다.

  10. 장면 및 프로젝트 파일>저장 장면/파일>저장 프로젝트를 저장합니다.

    중요

    이 프로젝트의 Unity 설정 구성 요소(혼합 현실 앱)를 건너뛰고 코드를 계속 진행하려면 이 .unitypackage를 자유롭게 다운로드하고 사용자 지정 패키지로 프로젝트로 가져온 다음 챕터 14에서 계속 진행하세요. 스크립트 구성 요소를 추가해야 합니다.

13장 - Mixed Reality Unity 프로젝트에서 DLL 가져오기

Unity용 Azure Storage 라이브러리(Azure용 .Net SDK 사용)를 사용합니다. Unity에서 Azure Storage를 사용하는 방법에 대한 이 링크를 따르세요. 현재 Unity에는 가져온 후 플러그 인을 다시 구성해야 하는 알려진 문제가 있습니다. 버그가 해결된 후에는 이러한 단계(이 섹션의 4~7)가 더 이상 필요하지 않습니다.

SDK를 사용자 고유의 프로젝트로 가져오려면 최신 .unitypackage를 다운로드했는지 확인합니다. 그런 후 다음을 수행합니다.

  1. 자산 패키지 가져오기사용자 지정 패키지 메뉴 옵션을 사용하여 위에서 다운로드한 .unitypackage를 Unity에 추가합니다>>.

  2. 팝업되는 Unity 패키지 가져오기 상자에서 플러그 인>스토리지에서 모든 항목을 선택할 수 있습니다.

    패키지 가져오기

  3. 가져오기 단추를 클릭하여 프로젝트에 항목을 추가합니다.

  4. 프로젝트 보기의 플러그 인 아래에 있는 Storage 폴더로 이동하여 다음 플러그 인 선택합니다.

    • Microsoft.Data.Edm
    • Microsoft.Data.OData
    • Microsoft.WindowsAzure.Storage
    • Newtonsoft.Json
    • System.Spatial

    플러그 인 선택

  5. 이러한 특정 플러그 인을 선택한 상태에서 모든 플랫폼의 선택을 취소하고 WSAPlayer의 선택을 취소한 다음 적용을 클릭합니다.

    플랫폼 변경 적용

    참고

    이러한 특정 플러그 인을 Unity 편집기에서만 사용하도록 표시하고 있습니다. 이는 프로젝트를 Unity에서 내보낸 후 사용될 WSA 폴더에 동일한 플러그 인의 버전이 서로 다르기 때문입니다.

  6. Storage 플러그 인 폴더에서 다음만 선택합니다.

    • Microsoft.Data.Services.Client

      데이터 서비스 클라이언트 선택

  7. 플랫폼 설정에서 처리 안 함 상자를 선택하고 적용을 클릭합니다.

    처리 안 함

    참고

    Unity 어셈블리 패치가 이 플러그 인을 처리하는 데 어려움을 겪기 때문에 이 플러그 인을 "처리 안 함"으로 표시하고 있습니다. 플러그 인은 처리되지 않더라도 계속 작동합니다.

14장 - 혼합 현실 Unity 프로젝트에서 TableToScene 클래스 만들기

TableToScene 클래스는 9장에 설명된 클래스와 동일합니다. 9장에서 설명한 것과 동일한 절차에 따라 혼합 현실 Unity 프로젝트에서 동일한 클래스를 만듭니다.

이 챕터를 완료하면 두 Unity 프로젝트 모두 주 카메라에 이 클래스를 설정합니다.

15장 - Mixed Reality Unity 프로젝트에서 NotificationReceiver 클래스 만들기

만들어야 하는 두 번째 스크립트는 NotificationReceiver입니다. 이 스크립트는 다음을 담당합니다.

  • 초기화 시 알림 허브에 앱을 등록합니다.
  • 알림 허브에서 오는 알림을 수신 대기합니다.
  • 받은 알림에서 개체 데이터를 역직렬화합니다.
  • 역직렬화된 데이터에 따라 장면에서 GameObjects를 이동합니다.

NotificationReceiver 스크립트를 만들려면 다음을 수행합니다.

  1. Scripts 폴더 내부를 마우스 오른쪽 단추로 클릭하고 만들기, C# 스크립트를 클릭합니다. 스크립트 이름을 NotificationReceiver로 지정합니다.

    새 c# 스크립트이름을 NotificationReceiver로 만듭니다.

  2. 스크립트를 두 번 클릭하여 엽니다.

  3. 다음 네임스페이스를 추가합니다.

    //using Microsoft.WindowsAzure.Messaging;
    using Newtonsoft.Json;
    using System;
    using System.Collections;
    using UnityEngine;
    
    #if UNITY_WSA_10_0 && !UNITY_EDITOR
    using Windows.Networking.PushNotifications;
    #endif
    
  4. 다음 변수를 삽입합니다.

        /// <summary>
        /// allows this class to behave like a singleton
        /// </summary>
        public static NotificationReceiver instance;
    
        /// <summary>
        /// Value set by the notification, new object position
        /// </summary>
        Vector3 newObjPosition;
    
        /// <summary>
        /// Value set by the notification, object name
        /// </summary>
        string gameObjectName;
    
        /// <summary>
        /// Value set by the notification, new object position
        /// </summary>
        bool notifReceived;
    
        /// <summary>
        /// Insert here your Notification Hub Service name 
        /// </summary>
        private string hubName = " -- Insert the name of your service -- ";
    
        /// <summary>
        /// Insert here your Notification Hub Service "Listen endpoint"
        /// </summary>
        private string hubListenEndpoint = "-Insert your Notification Hub Service Listen endpoint-";
    
  5. hubName 값을 Notification Hub 서비스 이름으로 대체하고 hubListenEndpoint 값을 Azure Portal의 액세스 정책 탭인 Azure Notification Hub Service에 있는 엔드포인트 값으로 바꿉니다(아래 이미지 참조).

    알림 허브 정책 엔드포인트 삽입

  6. 이제 Start()Awake() 메서드를 추가하여 클래스를 초기화합니다.

        /// <summary>
        /// Triggers before initialization
        /// </summary>
        void Awake()
        {
            // static instance of this class
            instance = this;
        }
    
        /// <summary>
        /// Use this for initialization
        /// </summary>
        void Start()
        {
            // Register the App at launch
            InitNotificationsAsync();
    
            // Begin listening for notifications
            StartCoroutine(WaitForNotification());
        }
    
  7. WaitForNotification 메서드를 추가하여 앱이 주 스레드와 충돌하지 않고 알림 허브 라이브러리에서 알림을 받을 수 있도록 합니다.

        /// <summary>
        /// This notification listener is necessary to avoid clashes 
        /// between the notification hub and the main thread   
        /// </summary>
        private IEnumerator WaitForNotification()
        {
            while (true)
            {
                // Checks for notifications each second
                yield return new WaitForSeconds(1f);
    
                if (notifReceived)
                {
                    // If a notification is arrived, moved the appropriate object to the new position
                    GameObject.Find(gameObjectName).transform.position = newObjPosition;
    
                    // Reset the flag
                    notifReceived = false;
                }
            }
        }
    
  8. 다음 메서드 InitNotificationAsync()는 초기화 시 알림 허브 서비스에 애플리케이션을 등록합니다. Unity에서 프로젝트를 빌드할 수 없기 때문에 코드가 주석 처리됩니다. Visual Studio에서 Azure Messaging Nuget 패키지를 가져올 때 주석을 제거합니다.

        /// <summary>
        /// Register this application to the Notification Hub Service
        /// </summary>
        private async void InitNotificationsAsync()
        {
            // PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
            // NotificationHub hub = new NotificationHub(hubName, hubListenEndpoint);
    
            // Registration result = await hub.RegisterNativeAsync(channel.Uri);
    
            // If registration was successful, subscribe to Push Notifications
            // if (result.RegistrationId != null)
            // {
            //     Debug.Log($"Registration Successful: {result.RegistrationId}");
            //     channel.PushNotificationReceived += Channel_PushNotificationReceived;
            // }
        }
    
  9. 다음 처리기 인 Channel_PushNotificationReceived()는 알림을 받을 때마다 트리거됩니다. 데스크톱 애플리케이션에서 이동된 Azure 테이블 엔터티인 알림을 역직렬화한 다음 MR 장면의 해당 GameObject를 동일한 위치로 이동합니다.

    중요

    코드는 Visual Studio 내에서 Nuget 패키지 관리자를 사용하여 Unity 프로젝트를 빌드한 후 추가할 Azure 메시징 라이브러리를 참조하기 때문에 주석 처리됩니다. 따라서 Unity 프로젝트는 주석 처리되지 않는 한 빌드할 수 없습니다. 프로젝트를 빌드한 다음 Unity로 돌아가려면 해당 코드를 다시 주석 으로 작성해야 합니다.

        ///// <summary>
        ///// Handler called when a Push Notification is received
        ///// </summary>
        //private void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args)    
        //{
        //    Debug.Log("New Push Notification Received");
        //
        //    if (args.NotificationType == PushNotificationType.Raw)
        //    {
        //        //  Raw content of the Notification
        //        string jsonContent = args.RawNotification.Content;
        //
        //        // Deserialise the Raw content into an AzureTableEntity object
        //        AzureTableEntity ate = JsonConvert.DeserializeObject<AzureTableEntity>(jsonContent);
        //
        //        // The name of the Game Object to be moved
        //        gameObjectName = ate.RowKey;          
        //
        //        // The position where the Game Object has to be moved
        //        newObjPosition = new Vector3((float)ate.X, (float)ate.Y, (float)ate.Z);
        //
        //        // Flag thats a notification has been received
        //        notifReceived = true;
        //    }
        //}
    
  10. Unity 편집기로 돌아가기 전에 변경 내용을 저장해야 합니다.

  11. 계층 구조 패널에서 기본 카메라를 클릭하여 해당 속성이 검사기에서 표시되도록 합니다.

  12. Scripts 폴더가 열려 있는 상태에서 NotificationReceiver 스크립트를 선택하고 주 카메라로 끕니다. 결과는 다음과 같습니다.

    알림 수신기 스크립트를 카메라로 끌기

    참고

    Microsoft HoloLens 대해 개발 중인 경우 주 카메라카메라 구성 요소를 업데이트하여 다음을 수행해야 합니다.

    • 플래그 지우기: 단색
    • 배경색: 검은색

16장 - UWP에 Mixed Reality 프로젝트 빌드

이 챕터는 이전 프로젝트의 빌드 프로세스와 동일합니다. 이제 이 프로젝트의 Unity 섹션에 필요한 모든 항목이 완료되었으므로 Unity에서 빌드해야 합니다.

  1. 빌드 설정(파일>빌드 설정)으로 이동합니다.

  2. 빌드 설정 메뉴에서 Unity C# 프로젝트*가 선택되어 있는지 확인합니다(빌드 후 이 프로젝트의 스크립트를 편집할 수 있음).

  3. 이 작업이 완료되면 빌드를 클릭합니다.

    오른쪽 아래에 '빌드' 단추가 강조 표시된 빌드 설정 창을 보여 주는 스크린샷

  4. 파일 탐색기 창이 팝업되어 빌드할 위치를 묻는 메시지가 표시됩니다. 왼쪽 위 모서리에서 새 폴더 를 클릭하여 새 폴더를 만들고 이름을 BUILDS로 지정합니다.

    builds 폴더 만들기

    1. BUILDS 폴더를 열고 다른 폴더( 새 폴더 사용)를 만들고 이름을 NH_MR_App.

      NH_MR_Apps 폴더 만들기

    2. NH_MR_App 선택합니다. 폴더 선택을 클릭합니다. 프로젝트를 빌드하는 데 1분 정도 걸릴 수 있습니다.

  5. 빌드 후 새 프로젝트의 위치에 파일 탐색기 창이 열립니다.

17장 - UnityMRNotifHub 솔루션에 NuGet 패키지 추가

경고

다음 NuGet 패키지를 추가하고 다음 챕터에서 코드의 주석 처리를 제거하면 Unity 프로젝트 내에서 다시 열면 오류가 발생합니다. 다시 돌아가서 Unity 편집기에서 편집을 계속하려면 해당 오류 코드에 대한 주석이 필요하고 나중에 Visual Studio로 돌아가면 다시 주석 처리를 제거해야 합니다.

혼합 현실 빌드가 완료되면 빌드한 혼합 현실 프로젝트로 이동하고 해당 폴더 내의 솔루션(.sln) 파일을 두 번 클릭하여 Visual Studio 2017에서 솔루션을 엽니다. 이제 WindowsAzure.Messaging.managed NuGet 패키지를 추가해야 합니다. 알림 허브에서 알림을 받는 데 사용되는 라이브러리입니다.

NuGet 패키지를 가져오려면 다음을 수행합니다.

  1. 솔루션 탐색기 솔루션을 마우스 오른쪽 단추로 클릭합니다.

  2. NuGet 패키지 관리를 클릭합니다.

    nuget 관리자 열기

  3. 찾아보기 탭을 선택하고 WindowsAzure.Messaging.managed를 검색합니다.

    Windows Azure 메시징 패키지 찾기

  4. 아래와 같이 결과를 선택하고 오른쪽 창에서 프로젝트 옆의 확인란을 선택합니다. 그러면 Project 옆의 확인란에 어셈블리-CSharpUnityMRNotifHub 프로젝트 옆의 확인란이 표시됩니다.

    모든 프로젝트 체크

  5. 처음에 제공된 버전은 이 프로젝트와 호환 되지 않을 수 있습니다 . 따라서 버전 옆에 있는 드롭다운 메뉴를 클릭하고 버전 0.1.7.9를 클릭한 다음 설치를 클릭합니다.

  6. 이제 NuGet 패키지 설치를 완료했습니다. NotificationReceiver 클래스에 입력한 주석 처리된 코드를 찾아 주석을 제거합니다.

18장 - UnityMRNotifHub 애플리케이션 편집, NotificationReceiver 클래스

NuGet 패키지를 추가한 후 NotificationReceiver 클래스 내에서 일부 코드의 주석 처리를 제거해야 합니다.

다음 내용이 포함됩니다.

  1. 맨 위에 있는 네임스페이스:

    using Microsoft.WindowsAzure.Messaging;
    
  2. InitNotificationsAsync() 메서드 내의 모든 코드:

        /// <summary>
        /// Register this application to the Notification Hub Service
        /// </summary>
        private async void InitNotificationsAsync()
        {
            PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
            NotificationHub hub = new NotificationHub(hubName, hubListenEndpoint);
    
            Registration result = await hub.RegisterNativeAsync(channel.Uri);
    
            // If registration was successful, subscribe to Push Notifications
            if (result.RegistrationId != null)
            {
                Debug.Log($"Registration Successful: {result.RegistrationId}");
                channel.PushNotificationReceived += Channel_PushNotificationReceived;
            }
        }
    

경고

위의 코드에는 주석이 있습니다. 해당 주석의 주석을 실수로 주석 처리하지 않았는지 확인합니다(코드가 있는 경우 컴파일되지 않으므로!).

  1. 마지막으로 Channel_PushNotificationReceived 이벤트:

        /// <summary>
        /// Handler called when a Push Notification is received
        /// </summary>
        private void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args)
        {
            Debug.Log("New Push Notification Received");
    
            if (args.NotificationType == PushNotificationType.Raw)
            {
                //  Raw content of the Notification
                string jsonContent = args.RawNotification.Content;
    
                // Deserialize the Raw content into an AzureTableEntity object
                AzureTableEntity ate = JsonConvert.DeserializeObject<AzureTableEntity>(jsonContent);
    
                // The name of the Game Object to be moved
                gameObjectName = ate.RowKey;
    
                // The position where the Game Object has to be moved
                newObjPosition = new Vector3((float)ate.X, (float)ate.Y, (float)ate.Z);
    
                // Flag thats a notification has been received
                notifReceived = true;
            }
        }
    

이러한 주석 처리를 사용하지 않고 저장했는지 확인하고 다음 챕터로 진행합니다.

19장 - 혼합 현실 프로젝트를 스토어 앱에 연결

이제 랩 시작 시 만든 Store 앱에 혼합 현실 프로젝트를 연결해야 합니다.

  1. 솔루션을 엽니다.

  2. 솔루션 탐색기 패널에서 UWP 앱 프로젝트를 마우스 오른쪽 단추로 클릭하고 스토어로 이동한 다음 스토어와 앱 연결...을 클릭합니다.

    오픈 스토어 연결

  3. 앱과 Windows 스토어 연결이라는 새 창이 나타납니다. 다음을 클릭합니다.

    다음 화면으로 이동

  4. 로그인한 계정과 연결된 모든 애플리케이션이 로드됩니다. 계정에 로그인하지 않은 경우 이 페이지에서 로그인 할 수 있습니다.

  5. 이 자습서의 시작 부분에 만든 스토어 앱 이름을 찾아 선택합니다. 그런 후 Next 를 클릭합니다.

    스토어 이름 찾기 및 선택

  6. 연결을 클릭합니다.

    앱 연결

  7. 이제 앱이 스토어 앱과 연결됩니다 . 알림을 사용하도록 설정하는 데 필요합니다.

20장 - UnityMRNotifHub 및 UnityDesktopNotifHub 애플리케이션 배포

이 챕터는 두 사람이 더 쉬울 수 있습니다. 그 결과 실행 중인 앱, 컴퓨터 데스크톱에서 실행되는 앱, 몰입형 헤드셋 내에서 실행되는 앱이 모두 포함되기 때문에 더 쉬울 수 있습니다.

몰입형 헤드셋 앱은 장면의 변경 내용(로컬 GameObjects의 위치 변경)을 받기 위해 대기하고 있으며 데스크톱 앱은 MR 앱에 공유되는 로컬 장면(위치 변경)을 변경합니다. 수신기가 수신 대기를 시작할 수 있도록 먼저 MR 앱을 배포한 다음 데스크톱 앱을 배포하는 것이 좋습니다.

로컬 컴퓨터에 UnityMRNotifHub 앱을 배포하려면 다음을 수행합니다.

  1. Visual Studio 2017에서 UnityMRNotifHub 앱의 솔루션 파일을 엽니다.

  2. 솔루션 플랫폼에서x86, 로컬 머신을 선택합니다.

  3. 솔루션 구성에서 디버그를 선택합니다.

    도구 모음에서 솔루션 구성이 '디버그'로 설정된 것을 보여 주는 스크린샷

  4. 빌드 메뉴로 이동하고 솔루션 배포를 클릭하여 애플리케이션을 컴퓨터에 테스트용으로 로드합니다.

  5. 이제 앱이 설치된 앱 목록에 표시되고 시작할 준비가 되었습니다.

로컬 컴퓨터에 UnityDesktopNotifHub 앱을 배포하려면 다음을 수행합니다.

  1. Visual Studio 2017에서 UnityDesktopNotifHub 앱의 솔루션 파일을 엽니다.

  2. 솔루션 플랫폼에서x86, 로컬 머신을 선택합니다.

  3. 솔루션 구성에서 디버그를 선택합니다.

    솔루션 구성이 '디버그'로 설정된 것을 보여 주는 스크린샷

  4. 빌드 메뉴로 이동하고 솔루션 배포를 클릭하여 애플리케이션을 컴퓨터에 테스트용으로 로드합니다.

  5. 이제 앱이 설치된 앱 목록에 표시되고 시작할 준비가 되었습니다.

  6. 혼합 현실 애플리케이션을 시작하고 데스크톱 애플리케이션을 실행합니다.

두 애플리케이션이 모두 실행되면 데스크톱 장면에서 개체를 이동합니다(왼쪽 마우스 단추를 사용). 이러한 위치 변경은 로컬로, 직렬화되고, 함수 앱 서비스로 전송됩니다. 그러면 함수 앱 서비스가 Notification Hub와 함께 테이블을 업데이트합니다. 업데이트를 받은 알림 허브는 업데이트된 데이터를 등록된 모든 애플리케이션(이 경우 몰입형 헤드셋 앱)에 직접 전송합니다. 그러면 들어오는 데이터를 역직렬화하고 새 위치 데이터를 로컬 개체에 적용하여 장면에서 이동합니다.

완료된 Azure Notification Hubs 애플리케이션

축하합니다. Azure Notification Hubs 서비스를 활용하고 앱 간 통신을 허용하는 혼합 현실 앱을 빌드했습니다.

최종 제품 -end

보너스 연습

연습 1

GameObjects의 색을 변경하고 해당 알림을 장면을 보는 다른 앱에 보내는 방법을 알아보시나요?

연습 2

GAMEObjects의 이동을 MR 앱에 추가하고 데스크톱 앱에서 업데이트된 장면을 볼 수 있나요?