HoloLens(1세대) 및 Azure 308: 디바이스 간 알림
참고 항목
Mixed Reality 아카데미 자습서는 HoloLens(1세대) 및 Mixed Reality 몰입형 헤드셋을 염두에 두고 설계되었습니다. 따라서 이러한 디바이스 개발에 대한 지침을 계속 찾고 있는 개발자를 위해 이러한 자습서를 그대로 두는 것이 중요합니다. 이러한 자습서는 HoloLens 2에 사용되는 최신 도구 집합 또는 상호 작용으로 업데이트되지 않습니다. 대신 지원되는 디바이스에서 계속 작동하도록 유지 관리됩니다. HoloLens 2용으로 개발하는 방법을 보여 주는 새로운 자습서 시리즈가 향후 게시될 예정입니다. 이 알림은 해당 자습서가 게시될 때 해당 자습서에 대한 링크로 업데이트됩니다.
이 과정에서는 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 애플리케이션이 있으며, 이 애플리케이션은 다음을 수행할 수 있습니다.
데스크톱 PC 앱을 사용하면 사용자가 마우스를 사용하여 2D 공간(X 및 Y)에서 개체를 이동할 수 있습니다.
PC 앱 내에서 개체의 이동은 개체 ID, 형식 및 변환 정보(X 및 Y 좌표)를 포함하는 문자열 형식인 JSON을 사용하여 클라우드로 전송됩니다.
데스크톱 앱과 동일한 장면이 있는 혼합 현실 앱은 Notification Hubs 서비스(데스크톱 PC 앱에서 방금 업데이트됨)에서 개체 이동에 대한 알림을 받습니다.
개체 ID, 형식 및 변환 정보를 포함하는 알림을 받으면 혼합 현실 앱은 수신된 정보를 자체 장면에 적용합니다.
애플리케이션에서 결과를 디자인과 통합하는 방법은 사용자에게 달려 있습니다. 이 과정은 Unity 프로젝트와 Azure 서비스를 통합하는 방법을 교육하기 위해 고안되었습니다. 혼합 현실 애플리케이션을 향상시키기 위해이 과정에서 얻은 지식을 사용하는 것이 당신의 일입니다. 이 과정은 다른 Mixed Reality Labs를 직접 포함하지 않는 자체 포함 자습서입니다.
디바이스 지원
과정 | HoloLens | 몰입형 헤드셋 |
---|---|---|
MR 및 Azure 308: 디바이스 간 알림 | ✔️ | ✔️ |
참고 항목
이 과정은 주로 Windows Mixed Reality 몰입형(VR) 헤드셋에 중점을 두고 있지만 이 과정에서 배운 내용을 Microsoft HoloLens에 적용할 수도 있습니다. 과정을 따라가면 HoloLens를 지원하기 위해 사용해야 할 수 있는 변경 내용에 대한 메모가 표시됩니다. HoloLens를 사용하는 경우 음성 캡처 중에 일부 에코를 확인할 수 있습니다.
필수 조건
참고 항목
이 자습서는 Unity 및 C#에 대한 기본 경험이 있는 개발자를 위해 설계되었습니다. 또한 이 문서의 필수 구성 요소와 서면 지침은 작성 당시 테스트 및 확인된 내용을 나타냅니다(2018년 5월). 이 과정의 정보가 아래에 나열된 것보다 최신 소프트웨어에서 찾을 수 있는 것과 완벽하게 일치한다고 가정해서는 안 되지만, 설치 도구 문서에 나열된 대로 최신 소프트웨어를 자유롭게 사용할 수 있습니다.
이 과정에는 다음 하드웨어 및 소프트웨어를 사용하는 것이 좋습니다.
- 몰입형(VR) 헤드셋 개발을 위해 Windows Mixed Reality와 호환되는 개발 PC
- 개발자 모드를 사용하도록 설정된 Windows 10 Fall Creators Update(이상)
- 최신 Windows 10 SDK
- Unity 2017.4
- Visual Studio 2017
- 개발자 모드가 설정된 Windows Mixed Reality 몰입형(VR) 헤드셋 또는 Microsoft HoloLens
- Azure 설치 및 Notification Hubs에 액세스하기 위한 인터넷 액세스
시작하기 전에
- 이 프로젝트를 빌드하는 데 문제가 발생하지 않도록 이 자습서에서 언급한 프로젝트를 루트 또는 루트에 가까운 폴더에 만드는 것이 좋습니다(긴 폴더 경로는 빌드 시 문제를 일으킬 수 있음).
- Microsoft 개발자 포털 및 애플리케이션 등록 포털의 소유자여야 합니다. 그렇지 않으면 2장에서 앱에 액세스할 수 있는 권한이 없습니다.
1장 - Microsoft 개발자 포털에서 애플리케이션 만들기
Azure Notification Hubs Service를 사용하려면 알림을 보내고 받을 수 있도록 애플리케이션을 등록해야 하므로 Microsoft 개발자 포털에서 애플리케이션을 만들어야 합니다.
Microsoft 개발자 포털에 로그인합니다.
Microsoft 계정에 로그인해야 합니다.
대시보드에서 새 앱 만들기를 클릭합니다.
새 앱의 이름을 예약해야 하는 팝업이 나타납니다. 텍스트 상자에 적절한 이름을 삽입합니다. 선택한 이름을 사용할 수 있으면 텍스트 상자 오른쪽에 틱이 나타납니다. 사용 가능한 이름이 삽입되면 팝업의 왼쪽 아래에 있는 제품 이름 예약 단추를 클릭합니다.
이제 앱을 만들었으므로 다음 챕터로 이동할 준비가 되었습니다.
2장 - 새 앱 자격 증명 검색
새 앱이 나열되는 애플리케이션 등록 포털에 로그인하고 Azure Portal 내에서 Notification Hubs 서비스를 설정하는 데 사용할 자격 증명을 검색합니다.
애플리케이션 등록 포털로 이동합니다.
Warning
로그인하려면 Microsoft 계정을 사용해야 합니다.
Windows 스토어 개발자 포털에서 이전 챕터에서 사용한 Microsoft 계정이어야 합니다.내 애플리케이션 섹션에서 앱을 찾을 수 있습니다 . 찾은 후 클릭하여 앱 이름과 등록이 있는 새 페이지로 이동합니다.
등록 페이지를 아래로 스크롤하여 앱에 대한 애플리케이션 비밀 섹션 및 패키지 SID를 찾습니다. 다음 챕터에서 Azure Notification Hubs Service를 설정하는 데 사용할 두 가지 모두를 복사합니다.
3장 - Azure Portal 설정: Notification Hubs 서비스 만들기
앱 자격 증명을 검색하면 Azure Portal로 이동하여 Azure Notification Hubs 서비스를 만들어야 합니다.
Azure Portal에 로그인합니다.
참고 항목
Azure 계정이 아직 없는 경우 계정을 만들어야 합니다. 교실 또는 랩 상황에서 이 자습서를 따르는 경우 강사 또는 프록터 중 한 명에게 새 계정 설정에 대한 도움을 요청하세요.
로그인한 후 왼쪽 위 모서리에서 새로 만들기를 클릭하고 알림 허브를 검색하고 Enter 키를 클릭합니다.
참고 항목
새 단어는 최신 포털에서 리소스 만들기로 대체되었을 수 있습니다.
새 페이지에서 Notification Hubs 서비스에 대한 설명을 제공합니다. 이 프롬프트의 왼쪽 아래에서 만들기 단추를 선택하여 이 서비스와의 연결을 만듭니다.
만들기를 클릭한 후에는 다음을 수행합니다.
이 서비스 인스턴스에 원하는 이름을 삽입합니다.
이 앱과 연결할 수 있는 네임스페이스를 제공합니다.
위치를 선택합니다.
리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 청구를 모니터링, 제어, 프로비전 및 관리하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 랩)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.
Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹을 관리하는 방법에 대한 이 링크를 따르세요.
적절한 구독을 선택합니다.
또한 이 서비스에 적용된 사용 약관을 이해했음을 확인해야 합니다.
만들기를 실행합니다.
만들기를 클릭하면 서비스가 생성될 때까지 기다려야 합니다. 이 작업은 1분 정도 걸릴 수 있습니다.
서비스 인스턴스가 만들어지면 포털에 알림이 표시됩니다.
알림에서 리소스 로 이동 단추를 클릭하여 새 서비스 인스턴스를 탐색합니다. 새 Notification Hub 서비스 인스턴스로 이동합니다.
개요 페이지에서 페이지 중간에 Windows(WNS)를 클릭합니다. 오른쪽 패널은 이전에 설정한 앱에서 패키지 SID 및 보안 키가 필요한 두 개의 텍스트 필드를 표시하도록 변경됩니다.
세부 정보를 올바른 필드에 복사한 후 [저장]을 클릭하면 알림 허브가 성공적으로 업데이트되면 알림이 표시됩니다.
4장 - Azure Portal 설정: Table Service 만들기
Notification Hubs Service 인스턴스를 만든 후 Azure Portal로 다시 이동하여 스토리지 리소스를 만들어 Azure Tables Service를 만듭니다.
아직 로그인하지 않은 경우 Azure Portal에 로그인합니다.
로그인한 후 왼쪽 위 모서리에서 새로 만들기를 클릭하고 Storage 계정을 검색한 다음 Enter 키를 클릭합니다.
참고 항목
새 단어는 최신 포털에서 리소스 만들기로 대체되었을 수 있습니다.
목록에서 Blob, 파일, 테이블, 큐 등 Storage 계정을 선택합니다.
새 페이지에서는 Storage 계정 서비스에 대한 설명을 제공합니다. 이 프롬프트의 왼쪽 아래에서 만들기 단추를 선택하여 이 서비스의 인스턴스를 만듭니다.
만들기를 클릭하면 패널이 표시됩니다.
이 서비스 인스턴스에 원하는 이름을 삽입합니다(모두 소문자여야 합니다).
배포 모델의 경우 Resource Manager를 클릭합니다.
계정 종류의 경우 드롭다운 메뉴를 사용하여 스토리지(범용 v1)를 선택합니다.
적절한 위치를 선택합니다.
복제 드롭다운 메뉴의 경우 RA-GRS(읽기 액세스 지역 중복 스토리지)를 선택합니다.
성능을 위해 표준을 클릭합니다.
보안 전송 필요 섹션 내에서 사용 안 함으로 선택합니다.
구독 드롭다운 메뉴에서 적절한 구독을 선택합니다.
리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 청구를 모니터링, 제어, 프로비전 및 관리하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 랩)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.
Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹을 관리하는 방법에 대한 이 링크를 따르세요.
가상 네트워크가 옵션인 경우 사용 안 함으로 둡니다.
만들기를 클릭합니다.
만들기를 클릭하면 서비스가 생성될 때까지 기다려야 합니다. 이 작업은 1분 정도 걸릴 수 있습니다.
서비스 인스턴스가 만들어지면 포털에 알림이 표시됩니다. 알림을 클릭하여 새 서비스 인스턴스를 탐색합니다.
알림에서 리소스 로 이동 단추를 클릭하여 새 서비스 인스턴스를 탐색합니다. 새 Storage 서비스 인스턴스 개요 페이지로 이동합니다.
개요 페이지의 오른쪽에서 테이블을 클릭합니다.
오른쪽의 패널은 새 테이블을 추가해야 하는 Table Service 정보를 표시하도록 변경됩니다. 왼쪽 위 모서리에 있는 + 표 단추를 클릭하여 이 작업을 수행합니다.
테이블 이름을 입력해야 하는 새 페이지가 표시됩니다. 이 이름은 이후 챕터에서 애플리케이션의 데이터를 참조하는 데 사용할 이름입니다. 적절한 이름을 삽입하고 확인을 클릭합니다.
새 테이블이 만들어지면 테이블 서비스 페이지(아래쪽)에서 볼 수 있습니다.
5장 - Visual Studio에서 Azure 테이블 완료
이제 Table Service Storage 계정이 설정되었으므로 데이터를 추가해야 합니다. 이 계정은 정보를 저장하고 검색하는 데 사용됩니다. 테이블 편집은 Visual Studio를 통해 수행할 수 있습니다.
Visual Studio를 엽니다.
메뉴에서 클라우드 탐색기 보기를>클릭합니다.
클라우드 탐색기는 도킹된 항목으로 열립니다(로드하는 데 시간이 걸릴 수 있으므로 참아야 합니다).
참고 항목
스토리지 계정을 만드는 데 사용한 구독이 표시되지 않는 경우 다음이 있는지 확인합니다 .
Azure Portal에 사용한 계정과 동일한 계정에 로그인했습니다.
계정 관리 페이지에서 구독을 선택했습니다(계정 설정에서 필터를 적용해야 할 수 있음).
Azure 클라우드 서비스가 표시됩니다. 스토리지 계정을 찾고 왼쪽의 화살표를 클릭하여 계정을 확장합니다.
확장되면 새로 만든 Storage 계정을 사용할 수 있어야 합니다. 저장소 왼쪽에 있는 화살표를 클릭한 다음 확장되면 테이블을 찾아 옆의 화살표를 클릭하여 마지막 챕터에서 만든 테이블을 표시합니다. 표를 두 번 클릭합니다.
테이블이 Visual Studio 창의 가운데에 열립니다. (더하기)가 있는 + 테이블 아이콘을 클릭합니다.
엔터티를 추가하라 는 메시지가 표시되는 창이 표시됩니다. 각각 여러 속성을 사용하여 총 세 개의 엔터티를 만듭니다. 테이블이 데이터를 찾는 데 사용되므로 PartitionKey 및 RowKey 가 이미 제공된 것을 알 수 있습니다.
PartitionKey 및 RowKey의 값을 다음과 같이 업데이트합니다(매번 RowKey를 증가하지만 추가하는 각 행 속성에 대해 이 작업을 수행해야 함).
속성 추가를 클릭하여 추가 데이터 행을 추가합니다. 첫 번째 빈 테이블이 아래 표와 일치하게 만듭니다.
작업이 끝나면 확인을 클릭합니다.
Warning
X, Y 및 Z의 형식, 항목을 Double으로 변경해야 합니다.
이제 테이블에 데이터 행이 있음을 알 수 있습니다. (더하기) 아이콘을 + 다시 클릭하여 다른 엔터티를 추가합니다.
추가 속성을 만든 다음 아래 표시된 것과 일치하도록 새 엔터티의 값을 설정합니다.
마지막 단계를 반복하여 다른 엔터티를 추가합니다. 이 엔터티의 값을 아래 표시된 값으로 설정합니다.
이제 테이블이 아래와 같이 표시됩니다.
이 챕터를 완료했습니다. 저장해야 합니다.
6장 - Azure 함수 앱 만들기
Desktop 애플리케이션에서 테이블 서비스를 업데이트하고 알림 허브를 통해 알림을 보내는 Azure Function App을 만듭니다.
먼저 Azure Function에서 필요한 라이브러리를 로드할 수 있는 파일을 만들어야 합니다.
메모장을 엽니다(Windows 키를 누르고 메모장 입력).
메모장을 열고 아래에 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" } } } }
Azure Portal에 로그인합니다.
로그인한 후 왼쪽 위 모서리에서 새로 만들기를 클릭하고 함수 앱을 검색한 다음 Enter 키를 누릅니다.
참고 항목
새 단어는 최신 포털에서 리소스 만들기로 대체되었을 수 있습니다.
새 페이지에서 함수 앱 서비스에 대한 설명을 제공합니다. 이 프롬프트의 왼쪽 아래에서 만들기 단추를 선택하여 이 서비스와의 연결을 만듭니다.
만들기를 클릭하면 다음을 입력합니다.
앱 이름의 경우 이 서비스 인스턴스에 원하는 이름을 삽입합니다.
구독을 선택합니다.
적절한 가격 책정 계층을 선택합니다. 함수 App Service를 처음 만드는 경우 무료 계층을 사용할 수 있어야 합니다.
리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 청구를 모니터링, 제어, 프로비전 및 관리하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 랩)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.
Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹을 관리하는 방법에 대한 이 링크를 따르세요.
OS의 경우 의도한 플랫폼이므로 Windows를 클릭합니다.
호스팅 계획을 선택합니다(이 자습서에서는 소비 계획을 사용합니다.)
위치 선택(이전 단계에서 빌드한 스토리지와 동일한 위치 선택)
Storage 섹션의 경우 이전 단계에서 만든 Storage 서비스를 선택해야 합니다.
이 앱에는 Application Insights가 필요하지 않으므로 자유롭게 끄십시오.
만들기를 클릭합니다.
만들기를 클릭하면 서비스가 생성될 때까지 기다려야 합니다. 이 작업은 1분 정도 걸릴 수 있습니다.
서비스 인스턴스가 만들어지면 포털에 알림이 표시됩니다.
알림을 클릭하여 새 서비스 인스턴스를 탐색합니다.
알림에서 리소스 로 이동 단추를 클릭하여 새 서비스 인스턴스를 탐색합니다.
함수 옆에 있는 + (더하기) 아이콘을 클릭하여 새로 만듭니다.
중앙 패널 내에 함수 만들기 창이 나타납니다. 패널의 위쪽 절반에 있는 정보를 무시하고 아래쪽 근처에 있는 사용자 지정 함수(아래와 같이 파란색 영역)를 클릭합니다.
창 내의 새 페이지에는 다양한 함수 형식이 표시됩니다. 아래로 스크롤하여 자주색 형식을 보고 HTTP PUT 요소를 클릭합니다.
Important
페이지 아래로 스크롤해야 할 수 있습니다(Azure Portal 업데이트가 수행된 경우 이 이미지는 정확히 동일하게 보이지 않을 수 있음). 그러나 HTTP PUT이라는 요소를 찾고 있습니다.
함수를 구성해야 하는 HTTP PUT 창이 나타납니다(이미지의 경우 아래 참조).
언어의 경우 드롭다운 메뉴를 사용하여 C#을 선택합니다.
이름에 적절한 이름을 입력합니다.
인증 수준 드롭다운 메뉴에서 함수를 선택합니다.
테이블 이름 섹션의 경우 이전에 Table Service를 만드는 데 사용한 정확한 이름(동일한 문자 대/소문자 포함)을 사용해야 합니다.
Storage 계정 연결 섹션 내에서 드롭다운 메뉴를 사용하고 여기에서 스토리지 계정을 선택합니다. 없는 경우 섹션 제목과 함께 새 하이퍼링크를 클릭하여 스토리지 계정이 나열되어야 하는 다른 패널을 표시합니다.
만들기를 클릭하면 설정이 성공적으로 업데이트되었다는 알림이 표시됩니다.
만들기를 클릭하면 함수 편집기로 리디렉션됩니다.
함수 편집기에 다음 코드를 삽입합니다(함수의 코드 바꾸기).
#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 서비스를 호출하여 구독된 모든 애플리케이션에 알린다.
코드가 있는 상태에서 저장을 클릭합니다.
그런 다음 페이지의 오른쪽에 있는 (화살표) 아이콘을 클릭합니다 < .
패널이 오른쪽에서 밉니다. 해당 패널에서 업로드를 클릭하면 파일 브라우저가 표시됩니다.
이전에 메모장에서 만든 project.json 파일로 이동하고 클릭한 다음 열기 단추를 클릭합니다. 이 파일은 함수에서 사용할 라이브러리를 정의합니다.
파일이 업로드되면 오른쪽 패널에 표시됩니다. 클릭하면 함수 편집기 내에서 열립니다. 다음 이미지와 정확히 같아야 합니다(23단계 아래).
그런 다음 왼쪽 패널의 Functions 아래에서 통합 링크를 클릭합니다.
다음 페이지의 오른쪽 위 모서리에서 아래와 같이 고급 편집기를 클릭합니다.
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" } ] }
이제 편집기가 아래 이미지와 같이 표시됩니다.
방금 삽입한 입력 매개 변수가 테이블 및 스토리지 세부 정보와 일치하지 않을 수 있으므로 정보로 업데이트해야 합니다. 다음에 설명되므로 여기서는 이 작업을 수행하지 마세요. 페이지의 오른쪽 위 모서리에 있는 표준 편집기 링크를 클릭하면 됩니다.
표준 편집기로 돌아가서 입력에서 Azure Table Storage(테이블)를 클릭합니다.
다음 정보가 다를 수 있으므로 다음 정보와 일치하는 지 확인합니다(다음 단계 아래에 이미지가 있음).
테이블 이름: Azure Storage, Tables 서비스 내에서 만든 테이블의 이름입니다.
스토리지 계정 연결: 드롭다운 메뉴와 함께 표시되는 새로 만들기를 클릭하면 창 오른쪽에 패널이 표시됩니다.
이전에 함수 앱을 호스트하기 위해 만든 스토리지 계정을 선택합니다.
스토리지 계정 연결 값이 생성되었음을 알 수 있습니다.
완료되면 저장을 눌러야 합니다.
이제 입력 페이지가 아래와 일치하여 정보가 표시됩니다.
그런 다음 출력에서 Azure Notification Hub(알림)를 클릭합니다. 다음이 서로 다를 수 있으므로 정보와 일치하는지 확인합니다(다음 단계 아래에 이미지가 있음).
알림 허브 이름: 이전에 만든 Notification Hub 서비스 인스턴스의 이름입니다.
Notification Hubs 네임스페이스 연결: 드롭다운 메뉴와 함께 표시되는 새로 만들기를 클릭합니다.
연결 팝업이 표시됩니다(아래 이미지 참조). 여기서 이전에 설정한 알림 허브의 네임스페이스를 선택해야 합니다.
가운데 드롭다운 메뉴에서 알림 허브 이름을 선택합니다.
정책 드롭다운 메뉴를 DefaultFullSharedAccessSignature로 설정합니다.
선택 단추를 클릭하여 돌아갑니다.
이제 출력 페이지가 아래와 일치하지만 대신 사용자 정보와 일치해야 합니다. 저장을 눌러 야 합니다.
Warning
알림 허브 이름을 직접 편집하지 마세요(이전 단계를 올바르게 수행한 경우 모두 고급 편집기 사용하여 수행해야 합니다.
이 시점에서 함수가 작동하는지 테스트해야 합니다. 방법:
함수 페이지로 다시 한 번 이동합니다.
함수 페이지로 돌아가서 페이지의 맨 오른쪽에 있는 테스트 탭을 클릭하여 테스트 블레이드를 엽니다.
블레이드의 요청 본문 텍스트 상자 내에서 아래 코드를 붙여넣습니다.
{ "Type":null, "X":3, "Y":0, "Z":1, "PartitionKey":null, "RowKey":"Obj2", "Timestamp":"0001-01-01T00:00:00+00:00", "ETag":null }
테스트 코드가 있는 상태에서 오른쪽 아래에 있는 실행 단추를 클릭하면 테스트가 실행됩니다. 테스트의 출력 로그는 함수 코드 아래의 콘솔 영역에 표시됩니다.
Warning
위의 테스트가 실패하는 경우 위의 단계, 특히 통합 패널 내의 설정을 정확하게 따랐는지 다시 확인해야 합니다.
7장 - Desktop Unity 프로젝트 설정
Important
현재 만들고 있는 데스크톱 애플리케이션은 Unity 편집기에서 작동하지 않습니다 . Visual Studio(또는 배포된 애플리케이션)를 사용하여 애플리케이션 빌드 다음에 편집기 외부에서 실행해야 합니다.
다음은 Unity 및 혼합 현실로 개발하기 위한 일반적인 설정이며, 따라서 다른 프로젝트에 적합한 템플릿입니다.
혼합 현실 몰입형 헤드셋을 설정하고 테스트합니다.
참고 항목
이 과정에는 모션 컨트롤러가 필요하지 않습니다. 몰입형 헤드셋 설정을 지원해야 하는 경우 Windows Mixed Reality를 설정하는 방법에 대한 이 링크를 따르세요.
Unity를 열고 새로 만들기를 클릭합니다.
Unity 프로젝트 이름을 제공하고 UnityDesktopNotifHub를 삽입해야 합니다. 프로젝트 형식이 3D로 설정되어 있는지 확인합니다. 위치를 적절한 위치로 설정합니다(루트 디렉터리에 더 가깝습니다.). 그런 다음 프로젝트 만들기를 클릭합니다.
Unity가 열려 있으면 기본 스크립트 편집 기가 Visual Studio로 설정되어 있는지 확인할 필요가 있습니다. 기본 설정 편집>으로 이동한 다음 새 창에서 외부 도구로 이동합니다. 외부 스크립트 편집기를 Visual Studio 2017로 변경합니다. 기본 설정 창을 닫습니다.
다음으로 파일>빌드 설정으로 이동하여 유니버설 Windows 플랫폼 선택한 다음 플랫폼 전환 단추를 클릭하여 선택 항목을 적용합니다.
파일>빌드 설정에 있는 동안 다음을 확인합니다.
대상 디바이스 가 모든 디바이스로 설정됩니다.
이 애플리케이션은 데스크톱용이므로 모든 디바이스여야 합니다.
빌드 유형 이 D3D로 설정됨
SDK 가 최신 설치됨으로 설정됨
Visual Studio 버전 이 설치된 최신 버전으로 설정됨
빌드 및 실행 이 로컬 컴퓨터로 설정됩니다.
여기서는 장면을 저장하고 빌드에 추가할 가치가 있습니다.
열린 장면 추가를 선택하여 이 작업을 수행합니다. 저장 창이 나타납니다.
이에 대한 새 폴더 및 이후의 장면, 새 폴더 단추를 선택하여 새 폴더를 만들고 이름을 Scenes로 지정합니다.
새로 만든 Scenes 폴더를 연 다음 파일 이름: 텍스트 필드에 NH_Desktop_Scene 입력한 다음 Save 키를 누릅니다.
빌드 설정의 나머지 설정은 현재 기본값으로 남아 있어야 합니다.
동일한 창에서 플레이어 설정 단추를 클릭하면 Inspector가 있는 공간에서 관련 패널이 열립니다.
이 패널에서 몇 가지 설정을 확인해야 합니다.
기타 설정 탭에서 다음을 수행 합니다.
런타임 버전 스크립팅은 실험적이어야 합니다(.NET 4.6 해당 버전).
백 엔드 스크립팅은 .NET이어야 합니다.
API 호환성 수준은 .NET 4.6이어야 합니다.
게시 설정 탭의 기능 아래에서 다음을 확인합니다.
InternetClient
빌드 설정으로 돌아가면 Unity C# 프로젝트가 더 이상 회색으로 표시되지 않습니다. 이 옆에 있는 확인란을 선택합니다.
빌드 설정 창을 닫습니다.
장면 및 프로젝트 파일>저장 장면/파일>저장 프로젝트를 저장합니다.
8장 - Unity에서 DLL 가져오기
Unity용 Azure Storage를 사용합니다(자체에서 Azure용 .Net SDK를 활용). 자세한 내용은 Unity용 Azure Storage에 대한 이 링크를 따르세요.
현재 Unity에는 가져온 후 플러그 인을 다시 구성해야 하는 알려진 문제가 있습니다. 버그가 해결된 후에는 이러한 단계(이 섹션의 4-7)가 더 이상 필요하지 않습니다.
SDK를 사용자 고유의 프로젝트로 가져오려면 GitHub에서 최신 .unitypackage 를 다운로드했는지 확인합니다. 그런 후 다음을 수행합니다.
자산 패키지 사용자 지정 패키지 > 가져오기 메뉴 옵션을 사용하여 Unity에 .unitypackage를 추가합니다>.
팝업되는 Unity 패키지 가져오기 상자에서 플러그 인>스토리지에서 모든 항목을 선택할 수 있습니다. 이 과정에 필요하지 않으므로 다른 모든 항목을 선택 취소합니다.
가져오기 단추를 클릭하여 프로젝트에 항목을 추가합니다.
프로젝트 보기의 플러그 인 아래에 있는 Storage 폴더로 이동하여 다음 플러그 인만 선택합니다.
- Microsoft.Data.Edm
- Microsoft.Data.OData
- Microsoft.WindowsAzure.Storage
- Newtonsoft.Json
- System.Spatial
이러한 특정 플러그 인을 선택한 상태에서 모든 플랫폼의 선택을 취소하고 WSAPlayer를 선택 취소한 다음 적용을 클릭합니다.
참고 항목
이러한 특정 플러그 인을 Unity 편집기에서만 사용하도록 표시하고 있습니다. 이는 프로젝트를 Unity에서 내보낸 후 사용할 WSA 폴더에 동일한 플러그 인의 다른 버전이 있기 때문입니다.
Storage 플러그 인 폴더에서 다음만 선택합니다.
Microsoft.Data.Services.Client
플랫폼 설정에서 처리 안 함 상자를 선택하고 적용을 클릭합니다.
참고 항목
Unity 어셈블리 패치가 이 플러그 인을 처리하는 데 어려움을 겪기 때문에 이 플러그 인을 "처리 안 함"으로 표시하고 있습니다. 플러그 인은 처리되지 않더라도 계속 작동합니다.
9장 - Desktop Unity 프로젝트에서 TableToScene 클래스 만들기
이제 이 애플리케이션을 실행하기 위해 코드가 포함된 스크립트를 만들어야 합니다.
만들어야 하는 첫 번째 스크립트는 다음과 같은 작업을 담당하는 TableToScene입니다.
- Azure Table 내에서 엔터티를 읽습니다.
- 테이블 데이터를 사용하여 생성할 개체와 위치를 결정합니다.
만들어야 하는 두 번째 스크립트는 CloudScene입니다. 이 스크립트는 다음을 담당합니다.
- 사용자가 장면 주위에 개체를 끌 수 있도록 왼쪽 클릭 이벤트를 등록합니다.
- 이 Unity 장면에서 개체 데이터를 직렬화하고 Azure Function App으로 보냅니다.
이 클래스를 만들려면 다음을 수행합니다.
프로젝트 패널에 있는 [폴더 만들기]에 있는 자산 폴더를 마우스 오른쪽 단추로>클릭합니다. 폴더 이름을 스크립트로 지정합니다.
방금 만든 폴더를 두 번 클릭하여 엽니다.
스크립트 폴더 내부를 마우스 오른쪽 단추로 클릭하고 C# 스크립트 만들기>를 클릭합니다. 스크립트 이름을 TableToScene로 지정합니다.
스크립트를 두 번 클릭하여 Visual Studio 2017에서 엽니다.
다음 네임스페이스를 추가합니다.
using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Auth; using Microsoft.WindowsAzure.Storage.Table; using UnityEngine;
클래스 내에서 다음 변수를 삽입합니다.
/// <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 서비스에 있는 키 값으로 대체합니다(아래 이미지 참조).
이제 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(); }
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); }
TableToScene 클래스 외부에서는 애플리케이션에서 테이블 엔터티를 직렬화하고 역직렬화하는 데 사용하는 클래스를 정의해야 합니다.
/// <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; } }
Unity 편집기로 돌아가기 전에 저장해야 합니다.
[검사기]에 속성이 표시되도록 계층 구조 패널에서 주 카메라를 클릭합니다.
Scripts 폴더가 열려 있는 상태에서 TableToScene 스크립트 파일을 선택하고 주 카메라로 끕니다. 결과는 다음과 같습니다.
10장 - Desktop Unity 프로젝트에서 CloudScene 클래스 만들기
만들어야 하는 두 번째 스크립트는 CloudScene입니다. 이 스크립트는 다음을 담당합니다.
사용자가 장면 주위에 개체를 끌 수 있도록 왼쪽 클릭 이벤트를 등록합니다.
이 Unity 장면에서 개체 데이터를 직렬화하고 Azure Function App으로 보냅니다.
두 번째 스크립트를 만들려면 다음을 수행합니다.
스크립트 폴더 내부를 마우스 오른쪽 단추로 클릭하고 만들기, C# 스크립트를 클릭합니다. CloudScene 스크립트 이름 지정
다음 네임스페이스를 추가합니다.
using Newtonsoft.Json; using System.Collections; using System.Text; using System.Threading.Tasks; using UnityEngine; using UnityEngine.Networking;
다음 변수를 삽입합니다.
/// <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;
아래 이미지와 같이 azureFunctionEndpoint 값을 Azure Portal의 Azure Function App Service에 있는 Azure Function App URL로 대체합니다.
이제 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(); }
Update() 메서드 내에서 마우스 입력 및 끌기를 감지하는 다음 코드를 추가합니다. 그러면 장면에서 GameObjects가 이동합니다. 사용자가 개체를 끌어서 놓은 경우 개체의 이름과 좌표를 Azure 함수 앱 서비스를 호출하는 UpdateCloudScene() 메서드에 전달합니다. 그러면 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)); } }
이제 아래와 같이 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(); } }
코드를 저장하고 Unity로 돌아갑니다.
CloudScene 스크립트를 주 카메라로 끕니다.
[검사기]에 속성이 표시되도록 계층 구조 패널에서 주 카메라를 클릭합니다.
Scripts 폴더가 열려 있는 상태에서 CloudScene 스크립트를 선택하고 주 카메라로 끕니다. 결과는 다음과 같습니다.
11장 - UWP에 데스크톱 프로젝트 빌드
이제 이 프로젝트의 Unity 섹션에 필요한 모든 작업이 완료되었습니다.
빌드 설정(파일>빌드 설정)으로 이동합니다.
빌드 설정 창에서 빌드를 클릭합니다.
파일 탐색기 창이 팝업되어 빌드할 위치를 묻는 메시지가 표시됩니다. 왼쪽 위 모서리에서 새 폴더를 클릭하여 새 폴더 를 만들고 이름을 BUILDS로 지정합니다.
새 BUILDS 폴더를 열고 다른 폴더(새 폴더 사용)를 만들고 이름을 NH_Desktop_App.
NH_Desktop_App 선택되어 있습니다. 폴더 선택을 클릭합니다. 프로젝트를 빌드하는 데 1분 정도 소요됩니다.
빌드 후 새 프로젝트의 위치를 보여 주는 파일 탐색기 표시됩니다. 하지만 다음 몇 챕터에서 먼저 다른 Unity 프로젝트를 만들어야 하므로 열 필요가 없습니다.
12장 - Mixed Reality Unity 프로젝트 설정
다음은 혼합 현실로 개발하기 위한 일반적인 설정이며, 따라서 다른 프로젝트에 적합한 템플릿입니다.
Unity를 열고 새로 만들기를 클릭합니다.
이제 Unity 프로젝트 이름을 제공하고 UnityMRNotifHub를 삽입해야 합니다. 프로젝트 형식이 3D로 설정되어 있는지 확인합니다. 위치를 적절한 위치로 설정합니다(루트 디렉터리에 더 가깝습니다.). 그런 다음 프로젝트 만들기를 클릭합니다.
Unity가 열려 있으면 기본 스크립트 편집 기가 Visual Studio로 설정되어 있는지 확인할 필요가 있습니다. 기본 설정 편집>으로 이동한 다음 새 창에서 외부 도구로 이동합니다. 외부 스크립트 편집기를 Visual Studio 2017로 변경합니다. 기본 설정 창을 닫습니다.
다음으로 파일 빌드 설정으로> 이동하여 플랫폼 전환 단추를 클릭하여 플랫폼을 유니버설 Windows 플랫폼 전환합니다.
파일>빌드 설정으로 이동하여 다음을 확인합니다.
대상 디바이스 가 모든 디바이스로 설정됩니다.
Microsoft HoloLens의 경우 대상 디바이스를 HoloLens로 설정합니다.
빌드 유형 이 D3D로 설정됨
SDK 가 최신 설치됨으로 설정됨
Visual Studio 버전 이 설치된 최신 버전으로 설정됨
빌드 및 실행 이 로컬 컴퓨터로 설정됩니다.
여기서는 장면을 저장하고 빌드에 추가할 가치가 있습니다.
열린 장면 추가를 선택하여 이 작업을 수행합니다. 저장 창이 나타납니다.
이에 대한 새 폴더 및 이후의 장면, 새 폴더 단추를 선택하여 새 폴더를 만들고 이름을 Scenes로 지정합니다.
새로 만든 Scenes 폴더를 연 다음 파일 이름: 텍스트 필드에서 NH_MR_Scene 입력한 다음 Save 키를 누릅니다.
빌드 설정의 나머지 설정은 현재 기본값으로 남아 있어야 합니다.
동일한 창에서 플레이어 설정 단추를 클릭하면 Inspector가 있는 공간에서 관련 패널이 열립니다.
이 패널에서 몇 가지 설정을 확인해야 합니다.
기타 설정 탭에서 다음을 수행 합니다.
런타임 버전 스크립팅은 실험적이어야 합니다(.NET 4.6 해당 버전).
백 엔드 스크립팅은 .NET이어야 합니다.
API 호환성 수준은 .NET 4.6이어야 합니다.
패널 아래에서 XR 설정(게시 설정 아래에 있음)에서 Virtual Reality 지원 확인에서 Windows Mixed Reality SDK가 추가되었는지 확인합니다.
게시 설정 탭의 기능 아래에서 다음을 확인합니다.
InternetClient
빌드 설정으로 돌아가면 Unity C# 프로젝트가 더 이상 회색으로 표시되지 않습니다. 이 옆에 있는 확인란을 선택합니다.
이러한 변경이 완료되면 빌드 설정 창을 닫습니다.
장면 및 프로젝트 파일>저장 장면/파일>저장 프로젝트를 저장합니다.
13장 - Mixed Reality Unity 프로젝트에서 DLL 가져오기
Unity용 Azure Storage 라이브러리(Azure용 .Net SDK 사용)를 사용합니다. Unity에서 Azure Storage를 사용하는 방법에 대한 이 링크를 따르세요. 현재 Unity에는 가져온 후 플러그 인을 다시 구성해야 하는 알려진 문제가 있습니다. 버그가 해결된 후에는 이러한 단계(이 섹션의 4-7)가 더 이상 필요하지 않습니다.
SDK를 사용자 고유의 프로젝트로 가져오려면 최신 .unitypackage를 다운로드했는지 확인합니다. 그런 후 다음을 수행합니다.
자산 패키지 사용자 지정 패키지> 가져오기 메뉴 옵션을 사용하여 위에서 다운로드한 .unitypackage를 Unity에 추가합니다.>
팝업되는 Unity 패키지 가져오기 상자에서 플러그 인>스토리지에서 모든 항목을 선택할 수 있습니다.
가져오기 단추를 클릭하여 프로젝트에 항목을 추가합니다.
프로젝트 보기의 플러그 인 아래에 있는 Storage 폴더로 이동하여 다음 플러그 인만 선택합니다.
- Microsoft.Data.Edm
- Microsoft.Data.OData
- Microsoft.WindowsAzure.Storage
- Newtonsoft.Json
- System.Spatial
이러한 특정 플러그 인을 선택한 상태에서 모든 플랫폼의 선택을 취소하고 WSAPlayer를 선택 취소한 다음 적용을 클릭합니다.
참고 항목
이러한 특정 플러그 인은 Unity 편집기에서만 사용하도록 표시합니다. 이는 프로젝트를 Unity에서 내보낸 후 사용할 WSA 폴더에 동일한 플러그 인의 다른 버전이 있기 때문입니다.
Storage 플러그 인 폴더에서 다음만 선택합니다.
Microsoft.Data.Services.Client
플랫폼 설정에서 처리 안 함 상자를 선택하고 적용을 클릭합니다.
참고 항목
Unity 어셈블리 패치가 이 플러그 인을 처리하는 데 어려움을 겪기 때문에 이 플러그 인을 "처리 안 함"으로 표시하고 있습니다. 플러그 인은 처리되지 않더라도 계속 작동합니다.
14장 - 혼합 현실 Unity 프로젝트에서 TableToScene 클래스 만들기
TableToScene 클래스는 9장에서 설명한 클래스와 동일합니다. 9장에서 설명한 것과 동일한 절차에 따라 혼합 현실 Unity 프로젝트에서 동일한 클래스를 만듭니다.
이 챕터를 완료하면 두 Unity 프로젝트 모두 주 카메라에 이 클래스를 설정합니다.
15장 - Mixed Reality Unity 프로젝트에서 NotificationReceiver 클래스 만들기
만들어야 하는 두 번째 스크립트는 NotificationReceiver입니다. 이 스크립트는 다음을 담당합니다.
- 초기화 시 알림 허브에 앱을 등록합니다.
- 알림 허브에서 들어오는 알림을 수신 대기합니다.
- 받은 알림에서 개체 데이터를 역직렬화합니다.
- 역직렬화된 데이터에 따라 장면에서 GameObjects를 이동합니다.
NotificationReceiver 스크립트를 만들려면:
스크립트 폴더 내부를 마우스 오른쪽 단추로 클릭하고 만들기, C# 스크립트를 클릭합니다. 스크립트 이름을 NotificationReceiver로 지정합니다.
스크립트를 두 번 클릭하여 엽니다.
다음 네임스페이스를 추가합니다.
//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
다음 변수를 삽입합니다.
/// <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-";
hubName 값을 Notification Hub 서비스 이름 및 hubListenEndpoint 값으로 Azure Portal의 액세스 정책 탭, Azure Notification Hub Service에 있는 엔드포인트 값으로 대체합니다(아래 이미지 참조).
이제 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()); }
주 스레드와 충돌하지 않고 앱이 알림 허브 라이브러리에서 알림을 받을 수 있도록 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; } } }
다음 방법인 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; // } }
알림이 수신될 때마다 다음 처리기 Channel_PushNotificationReceived()가 트리거됩니다. 데스크톱 애플리케이션에서 이동된 Azure Table Entity인 알림을 역직렬화한 다음 MR 장면의 해당 GameObject를 동일한 위치로 이동합니다.
Important
코드는 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; // } //}
Unity 편집기로 돌아가기 전에 변경 내용을 저장해야 합니다.
[검사기]에 속성이 표시되도록 계층 구조 패널에서 주 카메라를 클릭합니다.
Scripts 폴더가 열려 있는 상태에서 NotificationReceiver 스크립트를 선택하고 주 카메라로 끕니다. 결과는 다음과 같습니다.
참고 항목
Microsoft HoloLens용으로 개발하는 경우 주 카메라의 카메라 구성 요소를 업데이트하여 다음을 수행해야 합니다.
- 플래그 지우기: 단색
- 배경색: 검은색
16장 - UWP에 Mixed Reality 프로젝트 빌드
이 장은 이전 프로젝트의 빌드 프로세스와 동일합니다. 이제 이 프로젝트의 Unity 섹션에 필요한 모든 항목이 완료되었으므로 Unity에서 빌드해야 합니다.
빌드 설정(파일>빌드 설정)으로 이동합니다.
빌드 설정 메뉴에서 Unity C# 프로젝트*가 선택되어 있는지 확인합니다(빌드 후 이 프로젝트의 스크립트를 편집할 수 있도록 허용).
이 작업이 완료되면 빌드를 클릭합니다.
파일 탐색기 창이 팝업되어 빌드할 위치를 묻는 메시지가 표시됩니다. 왼쪽 위 모서리에서 새 폴더를 클릭하여 새 폴더 를 만들고 이름을 BUILDS로 지정합니다.
새 BUILDS 폴더를 열고 다른 폴더(새 폴더 사용)를 만들고 이름을 NH_MR_App.
NH_MR_App 선택합니다. 폴더 선택을 클릭합니다. 프로젝트를 빌드하는 데 1분 정도 소요됩니다.
빌드 후 새 프로젝트의 위치에 파일 탐색기 창이 열립니다.
17장 - UnityMRNotifHub 솔루션에 NuGet 패키지 추가
Warning
다음 NuGet 패키지를 추가하고 다음 챕터에서 코드의 주석 처리를 제거하면 Unity 프로젝트 내에서 다시 열면 오류가 발생합니다. 다시 돌아가서 Unity 편집기에서 편집을 계속하려면 해당 오류 코드를 주석으로 처리한 다음 나중에 Visual Studio로 돌아가면 주석 처리를 다시 제거해야 합니다.
혼합 현실 빌드가 완료되면 빌드한 혼합 현실 프로젝트로 이동하고 해당 폴더 내의 솔루션(.sln) 파일을 두 번 클릭하여 Visual Studio 2017에서 솔루션을 엽니다. 이제 WindowsAzure.Messaging.managed NuGet 패키지를 추가해야 합니다. 알림 허브에서 알림을 받는 데 사용되는 라이브러리입니다.
NuGet 패키지를 가져오려면:
솔루션 탐색기 솔루션을 마우스 오른쪽 단추로 클릭합니다.
NuGet 패키지 관리를 클릭합니다.
찾아보기 탭을 선택하고 WindowsAzure.Messaging.managed를 검색합니다.
아래와 같이 결과를 선택하고 오른쪽 창에서 Project 옆에 있는 확인란을 선택합니다. 그러면 Project 옆의 확인란에 틱이 표시되고 Assembly-CSharp 및 UnityMRNotifHub 프로젝트 옆의 확인란이 표시됩니다.
처음에 제공된 버전은 이 프로젝트와 호환되지 않을 수 있습니다. 따라서 버전 옆의 드롭다운 메뉴를 클릭하고 버전 0.1.7.9를 클릭한 다음 설치를 클릭합니다.
이제 NuGet 패키지 설치를 완료했습니다. NotificationReceiver 클래스에서 입력한 주석 처리된 코드를 찾아 주석을 제거합니다.
18장 - UnityMRNotifHub 애플리케이션 편집, NotificationReceiver 클래스
NuGet 패키지를 추가한 후 NotificationReceiver 클래스 내에서 일부 코드의 주석 처리를 제거해야 합니다.
다음 내용이 포함됩니다.
맨 위에 있는 네임스페이스:
using Microsoft.WindowsAzure.Messaging;
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; } }
Warning
위의 코드에는 주석이 있습니다. 해당 주석의 주석을 실수로 제거하지 않았는지 확인합니다(있는 경우 코드가 컴파일되지 않으므로!).
마지막으로 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장 - 혼합 현실 프로젝트를 스토어 앱에 연결
이제 랩 시작 시 만든 스토어 앱에 혼합 현실 프로젝트를 연결해야 합니다.
솔루션을 엽니다.
솔루션 탐색기 패널에서 UWP 앱 프로젝트를 마우스 오른쪽 단추로 클릭하고 스토어로 이동한 다음 스토어와 앱 연결...을 클릭합니다.
앱과 Windows 스토어 연결이라는 새 창이 나타납니다. 다음을 클릭합니다.
로그인한 계정과 연결된 모든 애플리케이션이 로드됩니다. 계정에 로그인하지 않은 경우 이 페이지에서 로그인할 수 있습니다.
이 자습서의 시작 부분에 만든 스토어 앱 이름을 찾아 선택합니다. 그런 후 Next 를 클릭합니다.
연결을 클릭합니다.
이제 앱이 스토어 앱과 연결됩니다 . 알림을 사용하도록 설정하는 데 필요합니다.
20장 - UnityMRNotifHub 및 UnityDesktopNotifHub 애플리케이션 배포
이 챕터는 두 사람이 더 쉬울 수 있습니다. 그 결과 실행 중인 앱, 컴퓨터 데스크톱에서 실행되는 앱, 몰입형 헤드셋 내에서 실행되는 앱이 모두 포함됩니다.
몰입형 헤드셋 앱은 장면 변경 내용(로컬 GameObjects의 위치 변경)을 받기 위해 대기하고 있으며 데스크톱 앱은 MR 앱에 공유되는 로컬 장면(위치 변경)을 변경합니다. 수신기가 수신 대기를 시작할 수 있도록 먼저 MR 앱을 배포한 다음 데스크톱 앱을 배포하는 것이 좋습니다.
로컬 컴퓨터에 UnityMRNotifHub 앱을 배포하려면 다음을 수행합니다.
Visual Studio 2017에서 UnityMRNotifHub 앱의 솔루션 파일을 엽니다.
솔루션 플랫폼에서 x86, 로컬 머신을 선택합니다.
솔루션 구성에서 디버그를 선택합니다.
빌드 메뉴로 이동하여 솔루션 배포를 클릭하여 애플리케이션을 컴퓨터에 테스트용으로 로드합니다.
이제 앱이 설치된 앱 목록에 표시되고 시작할 준비가 되었습니다.
로컬 컴퓨터에 UnityDesktopNotifHub 앱을 배포하려면 다음을 수행합니다.
Visual Studio 2017에서 UnityDesktopNotifHub 앱의 솔루션 파일을 엽니다.
솔루션 플랫폼에서 x86, 로컬 머신을 선택합니다.
솔루션 구성에서 디버그를 선택합니다.
빌드 메뉴로 이동하여 솔루션 배포를 클릭하여 애플리케이션을 컴퓨터에 테스트용으로 로드합니다.
이제 앱이 설치된 앱 목록에 표시되고 시작할 준비가 되었습니다.
혼합 현실 애플리케이션을 시작하고 데스크톱 애플리케이션을 시작합니다.
두 애플리케이션이 모두 실행 중인 상태에서 데스크톱 장면에서 개체를 이동합니다(왼쪽 마우스 단추를 사용). 이러한 위치 변경은 로컬로, 직렬화되고, 함수 앱 서비스로 전송됩니다. 그러면 함수 앱 서비스가 알림 허브와 함께 테이블을 업데이트합니다. 업데이트를 받은 알림 허브는 업데이트된 데이터를 등록된 모든 애플리케이션(이 경우 몰입형 헤드셋 앱)에 직접 전송합니다. 그러면 들어오는 데이터를 역직렬화하고 새 위치 데이터를 로컬 개체에 적용하여 장면에서 이동합니다.
완료된 Azure Notification Hubs 애플리케이션
축하합니다. Azure Notification Hubs 서비스를 활용하고 앱 간의 통신을 허용하는 혼합 현실 앱을 빌드했습니다.
보너스 연습
연습 1
GameObjects의 색을 변경하고 해당 알림을 장면을 보는 다른 앱에 보내는 방법을 알아낼 수 있나요?
연습 2
MR 앱에 GameObjects의 이동을 추가하고 데스크톱 앱에서 업데이트된 장면을 볼 수 있나요?