注意

Mixed Reality Academy チュートリアルは、HoloLens (第1世代) と Mixed Reality イマーシブヘッドセットを念頭に置いて設計されています。The Mixed Reality Academy tutorials were designed with HoloLens (1st gen) and Mixed Reality Immersive Headsets in mind. そのため、これらのデバイスの開発に関するガイダンスをまだ探している開発者には、これらのチュートリアルを残しておくことが重要です。As such, we feel it is important to leave these tutorials in place for developers who are still looking for guidance in developing for those devices. これらのチュートリアルは いない 最新のツールセットや相互作用が使用されている HoloLens 2 で更新されます。These tutorials will not be updated with the latest toolsets or interactions being used for HoloLens 2. サポートされているデバイスでの作業を続行するために管理されます。They will be maintained to continue working on the supported devices. 今後、HoloLens 2 向けの開発方法を示す新しい一連のチュートリアルが掲載されています。There will be a new series of tutorials that will be posted in the future that will demonstrate how to develop for HoloLens 2. この通知は、これらのチュートリアルが投稿されたときのリンクと共に更新されます。This notice will be updated with a link to those tutorials when they are posted.


MR と Azure 309:Application insightsMR and Azure 309: Application insights

最終製品-開始

このコースでは、Azure アプリケーション Insights API を使用してユーザーの行動に関する分析を収集することにより、Application Insights 機能を混合の現実アプリケーションに追加する方法について説明します。In this course, you will learn how to add Application Insights capabilities to a mixed reality application, using the Azure Application Insights API to collect analytics regarding user behavior.

Application Insights は Microsoft のサービスであり、開発者はアプリケーションから分析を収集し、使いやすいポータルから管理できます。Application Insights is a Microsoft service, allowing developers to collect analytics from their applications and manage it from an easy-to-use portal. 分析には、パフォーマンスから収集するカスタム情報まで、あらゆるものを選択できます。The analytics can be anything from performance to custom information you would like to collect. 詳細については、 Application Insights のページを参照してください。For more information, visit the Application Insights page.

このコースを完了すると、現実のイマーシブヘッドセットアプリケーションが完成し、次のことができるようになります。Having completed this course, you will have a mixed reality immersive headset application which will be able to do the following:

  1. シーンを見つめて移動することをユーザーに許可します。Allow the user to gaze and move around a scene.
  2. シーン内オブジェクトとの間での使用を通じて、 Application Insights サービスへの分析の送信をトリガーします。Trigger the sending of analytics to the Application Insights Service, through the use of Gaze and Proximity to in-scene objects.
  3. また、アプリはサービスに対してを呼び出し、過去24時間以内にユーザーによって最も頻繁に近づいたオブジェクトに関する情報を取得します。The app will also call upon the Service, fetching information about which object has been approached the most by the user, within the last 24 hours. そのオブジェクトの色が緑色に変わります。That object will change its color to green.

このコースでは、Application Insights サービスから Unity ベースのサンプルアプリケーションに結果を取得する方法について説明します。This course will teach you how to get the results from the Application Insights Service, into a Unity-based sample application. これらの概念は、構築しているカスタムアプリケーションに適用する必要があります。It will be up to you to apply these concepts to a custom application you might be building.

デバイスのサポートDevice support

までCourse HoloLensHoloLens イマーシブ ヘッドセットImmersive headsets
MR と Azure 309:Application insightsMR and Azure 309: Application insights ✔️✔️ ✔️✔️

注意

このコースでは主に Windows Mixed Reality イマーシブ (VR) ヘッドセットに焦点を当てていますが、このコースで学習した内容を Microsoft HoloLens に適用することもできます。While this course primarily focuses on Windows Mixed Reality immersive (VR) headsets, you can also apply what you learn in this course to Microsoft HoloLens. このコースに従うと、HoloLens をサポートするために必要となる可能性のある変更に関する注意事項が表示されます。As you follow along with the course, you will see notes on any changes you might need to employ to support HoloLens. HoloLens を使用する場合、音声キャプチャ中にエコーが発生することがあります。When using HoloLens, you may notice some echo during voice capture.

必須コンポーネントPrerequisites

注意

このチュートリアルは、Unity とC#の基本的な経験を持つ開発者向けに設計されています。This tutorial is designed for developers who have basic experience with Unity and C#. また、このドキュメントに記載されている前提条件と記述に記載されている手順は、作成時にテストおよび検証された内容 (2018 年7月) を表しています。Please also be aware that the prerequisites and written instructions within this document represent what has been tested and verified at the time of writing (July 2018). ツールのインストール」の記事に記載されているように、最新のソフトウェアを自由に使用できます。ただし、このコースの情報は、以下に記載されているものより新しいソフトウェアの内容と完全に一致するとは限りません。You are free to use the latest software, as listed within the install the tools article, though it should not be assumed that the information in this course will perfectly match what you will find in newer software than what is listed below.

このコースでは、次のハードウェアとソフトウェアをお勧めします。We recommend the following hardware and software for this course:

開始前の準備Before you start

このプロジェクトのビルドで問題が発生しないように、このチュートリアルで説明されているプロジェクトをルートまたはほぼルートフォルダーに作成することを強くお勧めします (長いフォルダーパスはビルド時に問題を引き起こす可能性があります)。To avoid encountering issues building this project, it is strongly suggested that you create the project mentioned in this tutorial in a root or near-root folder (long folder paths can cause issues at build-time).

警告

Application Insightsするデータには時間がかかるため、しばらくお待ちください。Be aware, data going to Application Insights takes time, so be patient. サービスがデータを受信したかどうかを確認する場合は、 14 章を参照してください。この章では、ポータル内を移動する方法を説明しています。If you want to check if the Service has received your data, check out Chapter 14, which will show you how to navigate the portal.

章 1-Azure PortalChapter 1 - The Azure Portal

Application Insightsを使用するには、Azure portal でApplication Insights サービスを作成および構成する必要があります。To use Application Insights, you will need to create and configure an Application Insights Service in the Azure portal.

  1. Azure ポータル にログインします。Log in to the Azure Portal.

    注意

    まだ Azure アカウントを持っていない場合は、アカウントを作成する必要があります。If you do not already have an Azure account, you will need to create one. このチュートリアルを教室またはラボの状況で行っている場合は、新しいアカウントの設定について、インストラクターまたはそのいずれかの対処を依頼してください。If you are following this tutorial in a classroom or lab situation, ask your instructor or one of the proctors for help setting up your new account.

  2. ログインしたら、左上隅にある [新規] をクリックし、 Application Insightsを検索して、 Enter キーを押します。Once you are logged in, click on New in the top left corner, and search for Application Insights, and click Enter.

    注意

    新しいポータルで、 Newという単語がリソースの作成に置き換えられました。The word New may have been replaced with Create a resource, in newer portals.

    Azure ポータル

  3. 右側の新しいページには、 Azure アプリケーション Insightsサービスの説明が表示されます。The new page to the right will provide a description of the Azure Application Insights Service. このページの左下にある [作成] ボタンを選択して、このサービスとの関連付けを作成します。At the bottom left of this page, select the Create button, to create an association with this Service.

    Azure ポータル

  4. 作成:Once you have clicked on Create:

    1. このサービスインスタンスに必要な名前を挿入します。Insert your desired Name for this Service instance.

    2. アプリケーションの種類として [全般] を選択します。As Application Type, select General.

    3. 適切なサブスクリプションを選択します。Select an appropriate Subscription.

    4. リソースグループを選択するか、新しいリソースグループを作成します。Choose a Resource Group or create a new one. リソースグループは、Azure 資産のコレクションの課金を監視、制御する方法を提供します。A resource group provides a way to monitor, control access, provision and manage billing for a collection of Azure assets. 1つのプロジェクトに関連付けられているすべての Azure サービス (たとえば、これらのコースなど) を共通のリソースグループに保持することをお勧めします。It is recommended to keep all the Azure Services associated with a single project (e.g. such as these courses) under a common resource group).

      Azure リソースグループの詳細については、リソースグループに関する記事をご覧ください。If you wish to read more about Azure Resource Groups, please visit the resource group article.

    5. 場所を選択します。Select a Location.

    6. また、このサービスに適用されている使用条件を理解していることを確認する必要があります。You will also need to confirm that you have understood the Terms and Conditions applied to this Service.

    7. [作成] を選択します。Select Create.

      Azure ポータル

  5. [作成] をクリックした後、サービスが作成されるまで待機する必要があります。これには1分かかることがあります。Once you have clicked on Create, you will have to wait for the Service to be created, this might take a minute.

  6. サービスインスタンスが作成されると、ポータルに通知が表示されます。A notification will appear in the portal once the Service instance is created.

    Azure ポータル

  7. 通知をクリックして、新しいサービスインスタンスを探索します。Click on the notifications to explore your new Service instance.

    Azure ポータル

  8. 通知の [リソースへのジャンプ] ボタンをクリックして、新しいサービスインスタンスを探索します。Click the Go to resource button in the notification to explore your new Service instance. 新しいApplication Insights サービスインスタンスが表示されます。You will be taken to your new Application Insights Service instance.

    Azure ポータル

    注意

    この web ページを開いたまま、簡単にアクセスできるようにします。収集されたデータを確認するために頻繁に使用します。Keep this web page open and easy to access, you will come back here often to see the data collected.

    重要

    Application Insights を実装するには、次の3つの固有の値を使用する必要があります。インストルメンテーションキーアプリケーション ID、およびAPI キーTo implement Application Insights, you will need to use three (3) specific values: Instrumentation Key, Application ID, and API Key. 以下では、これらの値をサービスから取得する方法について説明します。Below you will see how to retrieve these values from your Service. これらの値は、コードですぐに使用されるため、空のメモ帳ページでメモしておいてください。Make sure to note these values on a blank Notepad page, because you will use them soon in your code.

  9. インストルメンテーションキーを検索するには、サービス関数の一覧を下にスクロールし、[プロパティ] をクリックする必要があります。表示されるタブにサービスキーが表示されます。To find the Instrumentation Key, you will need to scroll down the list of Service functions, and click on Properties, the tab displayed will reveal the Service Key.

    Azure ポータル

  10. 以下のプロパティを使用すると、クリックする必要があるAPI アクセスがわかります。A little below Properties, you will find API Access, which you need to click. 右側のパネルに、アプリのアプリケーション IDが表示されます。The panel to the right will provide the Application ID of your app.

    Azure ポータル

  11. [アプリケーション ID ] パネルを開いたまま、[ Api キーの作成] をクリックすると、[ api キーの作成] パネルが開きます。With the Application ID panel still open, click Create API Key, which will open the Create API key panel.

    Azure ポータル

  12. ここで、[ API キーの作成] パネルを開き、説明を入力して、 3 つのボックスを目盛りします。Within the now open Create API key panel, type a description, and tick the three boxes.

  13. [キーの生成] をクリックします。Click Generate Key. API キーが作成されて表示されます。Your API Key will be created and displayed.

    Azure ポータル

    警告

    これは、サービスキーが表示される唯一の時間であるため、ここでコピーを作成してください。This is the only time your Service Key will be displayed, so ensure you make a copy of it now.

Chapter 2-Unity プロジェクトの設定Chapter 2 - Set up the Unity project

次に示すのは、mixed reality で開発するための一般的な設定です。そのため、他のプロジェクトに適したテンプレートです。The following is a typical set up for developing with the mixed reality, and as such, is a good template for other projects.

  1. Unityを開き、[新規] をクリックします。Open Unity and click New.

    Unity プロジェクトを設定する

  2. ここで、Unity プロジェクト名を指定し、「 MR_Azure_Application_Insights」と入力する必要があります。You will now need to provide a Unity Project name, insert MR_Azure_Application_Insights. テンプレート3dに設定されていることを確認します。Make sure the Template is set to 3D. 場所を適切な場所に設定します (ルートディレクトリの方が適していることに注意してください)。Set the Location to somewhere appropriate for you (remember, closer to root directories is better). 次に、[プロジェクトの作成] をクリックします。Then, click Create project.

    Unity プロジェクトを設定する

  3. 既定値を確認する必要が開いている Unity、 スクリプト エディター に設定されている Visual Studio します。With Unity open, it is worth checking the default Script Editor is set to Visual Studio. [設定の>編集] に移動し、新しいウィンドウで [外部ツール] に移動します。Go to Edit > Preferences and then from the new window, navigate to External Tools. 変更 External Script EditorVisual Studio 2017 します。Change External Script Editor to Visual Studio 2017. [基本設定] ウィンドウを閉じます。Close the Preferences window.

    Unity プロジェクトを設定する

  4. 次に、[ファイル> ] [ビルドの設定] の順に移動し、[プラットフォームの切り替え] ボタンをクリックして、プラットフォームをユニバーサル Windows プラットフォームに切り替えます。Next, go to File > Build Settings and switch the platform to Universal Windows Platform, by clicking on the Switch Platform button.

    Unity プロジェクトを設定する

  5. ファイル>のビルド設定にアクセスして、次のことを確認してください。Go to File > Build Settings and make sure that:

    1. ターゲットデバイス任意のデバイスに設定されていますTarget Device is set to Any device

      Microsoft HoloLens の場合は、ターゲットデバイスHoloLensに設定します。For the Microsoft HoloLens, set Target Device to HoloLens.

    2. ビルドの種類D3Dに設定されていますBuild Type is set to D3D

    3. SDKは最新のインストールに設定されていますSDK is set to Latest installed

    4. ビルドと実行ローカルコンピューターに設定されていますBuild and Run is set to Local Machine

    5. シーンを保存し、ビルドに追加します。Save the scene and add it to the build.

      1. これを行うには、[開いているシーンの追加] を選択します。Do this by selecting Add Open Scenes. 保存ウィンドウが表示されます。A save window will appear.

        Unity プロジェクトを設定する

      2. このための新しいフォルダーを作成し、その後のシーンで、[新しいフォルダー ] ボタンをクリックして新しいフォルダーを作成し、その名前を「シーン」にします。Create a new folder for this, and any future scene, then click the New folder button, to create a new folder, name it Scenes.

        Unity プロジェクトを設定する

      3. 新しく作成した [シーン] フォルダーを開き、[ファイル名: テキスト] フィールドに「 ApplicationInsightsScene」と入力し、[保存] をクリックします。Open your newly created Scenes folder, and then in the File name: text field, type ApplicationInsightsScene, then click Save.

        Unity プロジェクトを設定する

  6. それ以外の設定は、[ビルド設定] の [既定] のままにしておきます。The remaining settings, in Build Settings, should be left as default for now.

  7. [ビルドの設定] ウィンドウで、[プレーヤーの設定] ボタンをクリックします。これにより、インスペクターが配置されている領域の関連パネルが開きます。In the Build Settings window, click on the Player Settings button, this will open the related panel in the space where the Inspector is located.

    Unity プロジェクトを設定する

  8. このパネルでは、いくつかの設定を確認する必要があります。In this panel, a few settings need to be verified:

    1. [その他の設定] タブで、次のようにします。In the Other Settings tab:

      1. スクリプト ランタイムバージョンは、エディターを再起動する必要がある場合に、実験的 (.Net 4.6 と同等) である必要があります。Scripting Runtime Version should be Experimental (.NET 4.6 Equivalent), which will trigger a need to restart the Editor.

      2. バックエンド.netである必要がありますScripting Backend should be .NET

      3. API 互換性レベル.net 4.6である必要がありますAPI Compatibility Level should be .NET 4.6

      Unity プロジェクトを設定する

    2. [発行の設定] タブの [機能] で、次の項目を確認します。Within the Publishing Settings tab, under Capabilities, check:

      • InternetClientInternetClient

        Unity プロジェクトを設定する

    3. パネルの下にある [ XR settings (発行設定] の下にあります) で、[ Virtual Reality がサポートされている] をオンにして、 Windows Mixed reality SDKが追加されていることを確認します。Further down the panel, in XR Settings (found below Publishing Settings), tick Virtual Reality Supported, make sure the Windows Mixed Reality SDK is added.

      Unity プロジェクトを設定する

  9. ビルド設定に戻ります 。 C# Unity プロジェクトはグレーで表示されなくなりました。このの横にあるチェックボックスをオンにします。Back in Build Settings, Unity C# Projects is no longer greyed out; tick the checkbox next to this.

  10. [ビルドの設定] ウィンドウを閉じます。Close the Build Settings window.

  11. シーンとプロジェクトを保存します (ファイル > 保存シーン/ファイル > 保存プロジェクト)。Save your Scene and Project (FILE > SAVE SCENE / FILE > SAVE PROJECT).

章 3-Unity パッケージをインポートするChapter 3 - Import the Unity package

重要

このコースの構成要素をスキップし、コードに直接移動する場合は、このunitypackageを無料でダウンロードして、カスタムパッケージとしてプロジェクトにインポートしてください。If you wish to skip the Unity Set up components of this course, and continue straight into code, feel free to download this Azure-MR-309.unitypackage, import it into your project as a Custom Package. これには、次の章の Dll も含まれます。This will also contain the DLLs from the next Chapter. インポート後、第6章から続行します。After import, continue from Chapter 6.

重要

Unity 内で Application Insights を使用するには、その DLL を Newtonsoft DLL と共にインポートする必要があります。To use Application Insights within Unity, you need to import the DLL for it, along with the Newtonsoft DLL. 現在、Unity には、インポート後にプラグインを再構成する必要がある既知の問題があります。There is currently a known issue in Unity which requires plugins to be reconfigured after import. バグが解決された後、これらの手順 (このセクションでは 4-7) は不要になりました。These steps (4 - 7 in this section) will no longer be required after the bug has been resolved.

Application Insights を独自のプロジェクトにインポートするには、プラグインを含む ' unitypackage ' をダウンロードしていることを確認してください。To import Application Insights into your own project, make sure you have downloaded the '.unitypackage', containing the plugins. その後、次の手順を実行します。Then, do the following:

  1. [ アセット>インポートパッケージ>のカスタムパッケージ] メニューオプションを使用して、 unitypackageを Unity に追加します。Add the .unitypackage to Unity by using the Assets > Import Package > Custom Package menu option.

  2. ポップアップ表示された [ Unity パッケージのインポート] ボックスで、プラグイン(およびそれを含む) のすべてが選択されていることを確認します。In the Import Unity Package box that pops up, ensure everything under (and including) Plugins is selected.

    Unity パッケージをインポートする

  3. [インポート] ボタンをクリックして、プロジェクトに項目を追加します。Click the Import button, to add the items to your project.

  4. プロジェクトビューの [プラグイン] の下にある [ Insights ] フォルダーにアクセスし、次のプラグインのみを選択します。Go to the Insights folder under Plugins in the Project view and select the following plugins only:

    • Microsoft ApplicationInsightsMicrosoft.ApplicationInsights

    Unity パッケージをインポートする

  5. このプラグインを選択した状態で、任意のプラットフォームオフになっていることを確認し、[ wsaplayer ] もオフになっていることを確認して、[適用] をクリックします。With this plugin selected, ensure that Any Platform is unchecked, then ensure that WSAPlayer is also unchecked, then click Apply. これを行うのは、ファイルが正しく構成されていることを確認することだけです。Doing this is just to confirm that the files are configured correctly.

    Unity パッケージをインポートする

    注意

    このようなプラグインをマークすると、Unity エディターでのみ使用されるように構成されます。Marking the plugins like this, configures them to only be used in the Unity Editor. WSA フォルダーには、Unity からプロジェクトがエクスポートされた後に使用される、異なる Dll のセットがあります。There are a different set of DLLs in the WSA folder which will be used after the project is exported from Unity.

  6. 次に、[ Insights ] フォルダー内のWSAフォルダーを開く必要があります。Next, you need to open the WSA folder, within the Insights folder. 先ほど構成したものと同じファイルのコピーが表示されます。You will see a copy of the same file you just configured. このファイルを選択し、インスペクターで、すべてのプラットフォームオフになっていることを確認してから、[ wsaplayer ]のみオンになっていることを確認します。Select this file, and then in the inspector, ensure that Any Platform is unchecked, then ensure that only WSAPlayer is checked. [適用] をクリックします。Click Apply.

    Unity パッケージをインポートする

  7. ここで、手順 4-6に従う必要がありますが、代わりにnewtonsoftプラグインの場合は、You will now need to follow steps 4-6, but for the Newtonsoft plugins instead. 結果がどのように表示されるかについては、以下のスクリーンショットを参照してください。See the below screenshot for what the outcome should look like.

    Unity パッケージをインポートする

Chapter 4-カメラとユーザーコントロールを設定するChapter 4 - Set up the camera and user controls

この章では、カメラとコントロールを設定して、ユーザーがシーン内を表示して移動できるようにします。In this Chapter you will set up the camera and the controls to allow the user to see and move in the scene.

  1. [階層] パネルの空の領域を右クリックし、[作成 > ] をクリックします。Right-click in an empty area in the Hierarchy Panel, then on Create > Empty.

    カメラとユーザーコントロールを設定する

  2. 新しい空の作成オブジェクトの名前をCamera Parentに変更します。Rename the new empty GameObject to Camera Parent.

    カメラとユーザーコントロールを設定する

  3. [階層] パネルの空の領域を右クリックし、[ 3D オブジェクト]、[] の順にクリックします。Right-click in an empty area in the Hierarchy Panel, then on 3D Object, then on Sphere.

  4. 球の名前をに変更します。Rename the Sphere to Right Hand.

  5. 右側の変換スケール0.1、0.1、0.1に設定します。Set the Transform Scale of the Right Hand to 0.1, 0.1, 0.1

    カメラとユーザーコントロールを設定する

  6. 球体 colliderコンポーネントの歯車をクリックし、[コンポーネントの削除] をクリックして、右側から球の colliderコンポーネントを削除します。Remove the Sphere Collider component from the Right Hand by clicking on the Gear in the Sphere Collider component, and then Remove Component.

    カメラとユーザーコントロールを設定する

  7. [階層] パネルで、メインカメラ右側のオブジェクトをカメラのオブジェクトにドラッグします。In the Hierarchy Panel drag the Main Camera and the Right Hand objects onto the Camera Parent object.

    カメラとユーザーコントロールを設定する

  8. メインカメラ右側のオブジェクトの両方の変換位置0、0、0に設定します。Set the Transform Position of both the Main Camera and the Right Hand object to 0, 0, 0.

    カメラとユーザーコントロールを設定する

    カメラとユーザーコントロールを設定する

章 5-Unity シーンでのオブジェクトの設定Chapter 5 - Set up the objects in the Unity scene

ここで、ユーザーが対話できるシーンの基本図形をいくつか作成します。You will now create some basic shapes for your scene, with which the user can interact.

  1. [階層] パネルの空の領域を右クリックし、[ 3d オブジェクト] で [平面] を選択します。Right-click in an empty area in the Hierarchy Panel, then on 3D Object, then select Plane.

  2. 平面の変換位置0、-1、0に設定します。Set the Plane Transform Position to 0, -1, 0.

  3. 平面の変換スケール5、1、5に設定します。Set the Plane Transform Scale to 5, 1, 5.

    Unity シーンでのオブジェクトの設定

  4. 平面オブジェクトと共に使用する基本的な素材を作成して、他の図形が見やすくなるようにします。Create a basic material to use with your Plane object, so that the other shapes are easier to see. プロジェクトパネルに移動し、を右クリックして、[作成] をクリックします。次にフォルダーを作成し、新しいフォルダーを作成します。Navigate to your Project Panel, right-click, then Create, followed by Folder, to create a new folder. 名前を「マテリアル」にします。Name it Materials.

    Unity シーンでのオブジェクトの設定 Unity シーンでのオブジェクトの設定

  5. [素材] フォルダーを開き、右クリックして [作成]、[素材] の順にクリックし、新しい素材を作成します。Open the Materials folder, then right-click, click Create, then Material, to create a new material. Blueという名前を指定します。Name it Blue.

    Unity シーンでのオブジェクトの設定 Unity シーンでのオブジェクトの設定

  6. 新しい青色のマテリアルを選択した状態で、インスペクターを見て、[ albedo] の横にある四角形のウィンドウをクリックします。With the new Blue material selected, look at the Inspector, and click the rectangular window alongside Albedo. 青い色を選択します (次の図は、16進数の色です。#3592FFFF)。Select a blue color (the one picture below is Hex Color: #3592FFFF). 選択したら、[閉じる] ボタンをクリックします。Click the close button once you have chosen.

    Unity シーンでのオブジェクトの設定

  7. 新しい素材を [マテリアル] フォルダーから、新しく作成した平面のシーンにドラッグします (または、階層内の [平面] オブジェクトにドロップします)。Drag your new material from the Materials folder, onto your newly created Plane, within your scene (or drop it on the Plane object within the Hierarchy).

    Unity シーンでのオブジェクトの設定

  8. [階層] パネルの空の領域を右クリックし、[ 3d オブジェクト] の [カプセル] をクリックします。Right-click in an empty area in the Hierarchy Panel, then on 3D Object, Capsule.

    • Capsule変更選択すると、その変換 位置を: -10, 1, 0します。With the Capsule selected, change its Transform Position to: -10, 1, 0.
  9. [階層] パネルの空の領域を右クリックし、[ 3d オブジェクト] の [キューブ] をクリックします。Right-click in an empty area in the Hierarchy Panel, then on 3D Object, Cube.

    • キューブ変更選択すると、その変換 位置に。0、0、10With the Cube selected, change its Transform Position to: 0, 0, 10.
  10. [階層] パネルの空の領域を右クリックし、[ 3d オブジェクト]、[球] の順にクリックします。Right-click in an empty area in the Hierarchy Panel, then on 3D Object, Sphere.

    • 変更選択すると、その 変換 位置 に。10、0、0With the Sphere selected, change its Transform Position to: 10, 0, 0.

    Unity シーンでのオブジェクトの設定

    注意

    これらの位置の値は提案です。These Position values are suggestions. オブジェクトの位置は自由に設定できますが、オブジェクトの距離がカメラから遠く離れていない場合は、アプリケーションのユーザーにとっても簡単です。You are free to set the positions of the objects to whatever you would like, though it is easier for the user of the application if the objects distances are not too far from the camera.

  11. アプリケーションが実行されている場合は、シーン内のオブジェクトを識別できる必要があります。これを実現するには、そのオブジェクトにタグを付ける必要があります。When your application is running, it needs to be able to identify the objects within the scene, to achieve this, they need to be tagged. オブジェクトの1つを選択し、[インスペクター ] パネルで [タグの追加... ] をクリックします。これにより、インスペクタータグ & レイヤーパネルが表示されます。Select one of the objects, and in the Inspector panel, click Add Tag..., which will swap the Inspector with the Tags & Layers panel.

    Unity シーンでのオブジェクトの設定Set up the objects in the Unity Scene

  12. [+] 記号 (プラス記号) をクリックし、タグ名を「テキスト」として入力します。Click the + (plus) symbol, then type the tag name as ObjectInScene.

    Unity シーンでのオブジェクトの設定

    警告

    タグに別の名前を使用する場合は、シーン内でオブジェクトが検出され、検出されるように、この変更によってDataFromAnalyticsObjecttrigger、および宝石のスクリプトも後で作成されるようにする必要があります。If you use a different name for your tag, you will need to ensure this change is also made the DataFromAnalytics, ObjectTrigger, and Gaze, scripts later, so that your objects are found, and detected, within your scene.

  13. タグを作成したら、3つのオブジェクトすべてに適用する必要があります。With the tag created, you now need to apply it to all three of your objects. 階層から、 shiftキーを押したまま、[カプセル]、[キューブ]、[]、[オブジェクト] の順にクリックし、次に [インスペクター] の下にあるドロップダウンメニューをクリックして、[オブジェクト] をクリックします。作成したタグ。From the Hierarchy, hold the Shift key, then click the Capsule, Cube, and Sphere, objects, then in the Inspector, click the dropdown menu alongside Tag, then click the ObjectInScene tag you created.

    Unity シーンでのオブジェクトの設定Set up the objects in the Unity Scene

Chapter 6-ApplicationInsightsTracker クラスの作成Chapter 6 - Create the ApplicationInsightsTracker class

作成する必要のある最初のスクリプトはApplicationInsightsTrackerです。これは次の役割を担います。The first script you need to create is ApplicationInsightsTracker, which is responsible for:

  1. ユーザーの操作に基づいてイベントを作成し、Azure アプリケーション Insights に送信します。Creating events based on user interactions to submit to Azure Application Insights.

  2. ユーザーの操作に応じて、適切なイベント名を作成します。Creating appropriate Event names, depending on user interaction.

  3. Application Insights サービスインスタンスにイベントを送信しています。Submitting events to the Application Insights Service instance.

このクラスを作成するには:To create this class:

  1. [プロジェクト] パネル内を右クリックし、[フォルダー作成 > ] をクリックします。Right-click in the Project Panel, then Create > Folder. フォルダーにスクリプトの名前を指定します。Name the folder Scripts.

    ApplicationInsightsTracker クラスを作成する ApplicationInsightsTracker クラスを作成する

  2. Scriptsフォルダーを作成したら、それをダブルクリックして開きます。With the Scripts folder created, double-click it, to open. 次に、そのフォルダー内でを右クリックし、[ C#スクリプト作成 > ] をクリックします。Then, within that folder, right-click, Create > C# Script. スクリプトにApplicationInsightsTrackerという名前を指定します。Name the script ApplicationInsightsTracker.

  3. 新しいApplicationInsightsTrackerスクリプトをダブルクリックして、 Visual Studioで開きます。Double-click on the new ApplicationInsightsTracker script to open it with Visual Studio.

  4. スクリプトの先頭にある名前空間を次のように更新します。Update namespaces at the top of the script to be as below:

        using Microsoft.ApplicationInsights;
        using Microsoft.ApplicationInsights.DataContracts;
        using Microsoft.ApplicationInsights.Extensibility;
        using UnityEngine;
    
  5. クラス内で、次の変数を挿入します。Inside the class insert the following variables:

        /// <summary>
        /// Allows this class to behavior like a singleton
        /// </summary>
        public static ApplicationInsightsTracker Instance;
    
        /// <summary>
        /// Insert your Instrumentation Key here
        /// </summary>
        internal string instrumentationKey = "Insert Instrumentation Key here";
    
        /// <summary>
        /// Insert your Application Id here
        /// </summary>
        internal string applicationId = "Insert Application Id here";
    
        /// <summary>
        /// Insert your API Key here
        /// </summary>
        internal string API_Key = "Insert API Key here";
    
        /// <summary>
        /// Represent the Analytic Custom Event object
        /// </summary>
        private TelemetryClient telemetryClient;
    
        /// <summary>
        /// Represent the Analytic object able to host gaze duration
        /// </summary>
        private MetricTelemetry metric;
    

    注意

    InstrumentationKey、applicationId、API_Keyの値を適切に設定します。これを行うには、Azure Portal のサービスキーを使用します (手順9のの説明を参照)。Set the instrumentationKey, applicationId and API_Key values appropriately, using the Service Keys from the Azure Portal as mentioned in Chapter 1, step 9 onwards.

  6. 次に、クラスが初期化されるときに呼び出されるStart () メソッドと起動前 () メソッドを追加します。Then add the Start() and Awake() methods, which will be called when the class initializes:

        /// <summary>
        /// Sets this class instance as a singleton
        /// </summary>
        void Awake()
        {
            Instance = this;
        }
    
        /// <summary>
        /// Use this for initialization
        /// </summary>
        void Start()
        {
            // Instantiate telemetry and metric
            telemetryClient = new TelemetryClient();
    
            metric = new MetricTelemetry();
    
            // Assign the Instrumentation Key to the Event and Metric objects
            TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey;
    
            telemetryClient.InstrumentationKey = instrumentationKey;
        }
    
  7. アプリケーションによって登録されたイベントとメトリックの送信を担当するメソッドを追加します。Add the methods responsible for sending the events and metrics registered by your application:

        /// <summary>
        /// Submit the Event to Azure Analytics using the event trigger object
        /// </summary>
        public void RecordProximityEvent(string objectName)
        {
            telemetryClient.TrackEvent(CreateEventName(objectName));
        }
    
        /// <summary>
        /// Uses the name of the object involved in the event to create 
        /// and return an Event Name convention
        /// </summary>
        public string CreateEventName(string name)
        {
            string eventName = $"User near {name}";
            return eventName;
        }
    
        /// <summary>
        /// Submit a Metric to Azure Analytics using the metric gazed object
        /// and the time count of the gaze
        /// </summary>
        public void RecordGazeMetrics(string objectName, int time)
        {
            // Output Console information about gaze.
            Debug.Log($"Finished gazing at {objectName}, which went for <b>{time}</b> second{(time != 1 ? "s" : "")}");
    
            metric.Name = $"Gazed {objectName}";
    
            metric.Value = time;
    
            telemetryClient.TrackMetric(metric);
        }
    
  8. Unityに戻る前に、変更内容をVisual Studioに保存してください。Be sure to save your changes in Visual Studio before returning to Unity.

第7章-宝石のスクリプトを作成するChapter 7 - Create the Gaze script

次に作成するスクリプトは、見つめスクリプトです。The next script to create is the Gaze script. このスクリプトは、ユーザーがどのオブジェクトを調べているかを検出するために、メインカメラから投影されるRaycastを作成する役割を担います。This script is responsible for creating a Raycast that will be projected forward from the Main Camera, to detect which object the user is looking at. この場合、 Raycastは、ユーザーがオブジェクトでオブジェクトを見ているかどうかを特定し、そのオブジェクトに対するユーザーのgazes時間をカウントする必要があります。In this case, the Raycast will need to identify if the user is looking at an object with the ObjectInScene tag, and then count how long the user gazes at that object.

  1. [ Scripts ] フォルダーをダブルクリックして開きます。Double-click on the Scripts folder, to open it.

  2. Scriptsフォルダー内を右クリックし、[ C#スクリプト作成 > ] をクリックします。Right-click inside the Scripts folder, click Create > C# Script. スクリプトに「」という名前を指定します。Name the script Gaze.

  3. スクリプトをダブルクリックして、Visual Studio で開きます。Double-click on the script to open it with Visual Studio.

  4. 既存のコードを次のコードに置き換えます。Replace the existing code with the following:

        using UnityEngine;
    
        public class Gaze : MonoBehaviour
        {
            /// <summary>
            /// Provides Singleton-like behavior to this class.
            /// </summary>
            public static Gaze Instance;
    
            /// <summary>
            /// Provides a reference to the object the user is currently looking at.
            /// </summary>
            public GameObject FocusedGameObject { get; private set; }
    
            /// <summary>
            /// Provides whether an object has been successfully hit by the raycast.
            /// </summary>
            public bool Hit { get; private set; }
    
            /// <summary>
            /// Provides a reference to compare whether the user is still looking at 
            /// the same object (and has not looked away).
            /// </summary>
            private GameObject _oldFocusedObject = null;
    
            /// <summary>
            /// Max Ray Distance
            /// </summary>
            private float _gazeMaxDistance = 300;
    
            /// <summary>
            /// Max Ray Distance
            /// </summary>
            private float _gazeTimeCounter = 0;
    
            /// <summary>
            /// The cursor object will be created when the app is running,
            /// this will store its values. 
            /// </summary>
            private GameObject _cursor;
        }
    
  5. 起動可能な () メソッドとStart () メソッドのコードを追加する必要があります。Code for the Awake() and Start() methods now needs to be added.

        private void Awake()
        {
            // Set this class to behave similar to singleton
            Instance = this;
            _cursor = CreateCursor();
        }
    
        void Start()
        {
            FocusedGameObject = null;
        }
    
        /// <summary>
        /// Create a cursor object, to provide what the user
        /// is looking at.
        /// </summary>
        /// <returns></returns>
        private GameObject CreateCursor()    
        {
            GameObject newCursor = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    
            // Remove the collider, so it does not block raycast.
            Destroy(newCursor.GetComponent<SphereCollider>());
    
            newCursor.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
    
            newCursor.GetComponent<MeshRenderer>().material.color = 
            Color.HSVToRGB(0.0223f, 0.7922f, 1.000f);
    
            newCursor.SetActive(false);
            return newCursor;
        }
    
  6. 見つめクラス内で、 Update () メソッドに次のコードを追加してRaycastを射影し、ターゲットのヒットを検出します。Inside the Gaze class, add the following code in the Update() method to project a Raycast and detect the target hit:

        /// <summary>
        /// Called every frame
        /// </summary>
        void Update()
        {
            // Set the old focused gameobject.
            _oldFocusedObject = FocusedGameObject;
    
            RaycastHit hitInfo;
    
            // Initialize Raycasting.
            Hit = Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hitInfo, _gazeMaxDistance);
    
            // Check whether raycast has hit.
            if (Hit == true)
            {
                // Check whether the hit has a collider.
                if (hitInfo.collider != null)
                {
                    // Set the focused object with what the user just looked at.
                    FocusedGameObject = hitInfo.collider.gameObject;
    
                    // Lerp the cursor to the hit point, which helps to stabilize the gaze.
                    _cursor.transform.position = Vector3.Lerp(_cursor.transform.position, hitInfo.point, 0.6f);
    
                    _cursor.SetActive(true);
                }
                else
                {
                    // Object looked on is not valid, set focused gameobject to null.
                    FocusedGameObject = null;
    
                    _cursor.SetActive(false);
                }
            }
            else
            {
                // No object looked upon, set focused gameobject to null.
                FocusedGameObject = null;
    
                _cursor.SetActive(false);
            }
    
            // Check whether the previous focused object is this same object. If so, reset the focused object.
            if (FocusedGameObject != _oldFocusedObject)
            {
                ResetFocusedObject();
            }
            // If they are the same, but are null, reset the counter. 
            else if (FocusedGameObject == null && _oldFocusedObject == null)
            {
                _gazeTimeCounter = 0;
            }
            // Count whilst the user continues looking at the same object.
            else
            {
                _gazeTimeCounter += Time.deltaTime;
            }
        }
    
  7. ResetFocusedObject () メソッドを追加して、ユーザーがオブジェクトを参照したときにApplication Insightsにデータを送信します。Add the ResetFocusedObject() method, to send data to Application Insights when the user has looked at an object.

        /// <summary>
        /// Reset the old focused object, stop the gaze timer, and send data if it
        /// is greater than one.
        /// </summary>
        public void ResetFocusedObject()
        {
            // Ensure the old focused object is not null.
            if (_oldFocusedObject != null)
            {
                // Only looking for objects with the correct tag.
                if (_oldFocusedObject.CompareTag("ObjectInScene"))
                {
                    // Turn the timer into an int, and ensure that more than zero time has passed.
                    int gazeAsInt = (int)_gazeTimeCounter;
    
                    if (gazeAsInt > 0)
                    {
                        //Record the object gazed and duration of gaze for Analytics
                        ApplicationInsightsTracker.Instance.RecordGazeMetrics(_oldFocusedObject.name, gazeAsInt);
                    }
                    //Reset timer
                    _gazeTimeCounter = 0;
                }
            }
        }
    
  8. これで、宝石スクリプトが完成しました。You have now completed the Gaze script. Unityに戻る前に、変更をVisual Studioに保存します。Save your changes in Visual Studio before returning to Unity.

章 8-ObjectTrigger クラスを作成するChapter 8 - Create the ObjectTrigger class

次のスクリプトを作成する必要があります。 Objecttriggerは次の役割を担います。The next script you need to create is ObjectTrigger, which is responsible for:

  • メインカメラとの競合に必要なコンポーネントを追加します。Adding components needed for collision to the Main Camera.
  • カメラがオブジェクトの近くにあるかどうかを検出しています。Detecting if the camera is near an object tagged as ObjectInScene.

スクリプトを作成するには:To create the script:

  1. [ Scripts ] フォルダーをダブルクリックして開きます。Double-click on the Scripts folder, to open it.

  2. Scriptsフォルダー内を右クリックし、[ C#スクリプト作成 > ] をクリックします。Right-click inside the Scripts folder, click Create > C# Script. スクリプトObjecttriggerにという名前を指定します。Name the script ObjectTrigger.

  3. スクリプトをダブルクリックして、Visual Studio で開きます。Double-click on the script to open it with Visual Studio. 既存のコードを次のコードに置き換えます。Replace the existing code with the following:

        using UnityEngine;
    
        public class ObjectTrigger : MonoBehaviour
        {
            private void Start()
            {
                // Add the Collider and Rigidbody components, 
                // and set their respective settings. This allows for collision.
                gameObject.AddComponent<SphereCollider>().radius = 1.5f;
    
                gameObject.AddComponent<Rigidbody>().useGravity = false;
            }
    
            /// <summary>
            /// Triggered when an object with a collider enters this objects trigger collider.
            /// </summary>
            /// <param name="collision">Collided object</param>
            private void OnCollisionEnter(Collision collision)
            {
                CompareTriggerEvent(collision, true);
            }
    
            /// <summary>
            /// Triggered when an object with a collider exits this objects trigger collider.
            /// </summary>
            /// <param name="collision">Collided object</param>
            private void OnCollisionExit(Collision collision)
            {
                CompareTriggerEvent(collision, false);
            }
    
            /// <summary>
            /// Method for providing debug message, and sending event information to InsightsTracker.
            /// </summary>
            /// <param name="other">Collided object</param>
            /// <param name="enter">Enter = true, Exit = False</param>
            private void CompareTriggerEvent(Collision other, bool enter)
            {
                if (other.collider.CompareTag("ObjectInScene"))
                {
                    string message = $"User is{(enter == true ? " " : " no longer ")}near <b>{other.gameObject.name}</b>";
    
                    if (enter == true)
                    {
                        ApplicationInsightsTracker.Instance.RecordProximityEvent(other.gameObject.name);
                    }
                    Debug.Log(message);
                }
            }
        }
    
  4. Unityに戻る前に、変更内容をVisual Studioに保存してください。Be sure to save your changes in Visual Studio before returning to Unity.

第9章-DataFromAnalytics クラスの作成Chapter 9 - Create the DataFromAnalytics class

次の役割を果たすDataFromAnalyticsスクリプトを作成する必要があります。You will now need to create the DataFromAnalytics script, which is responsible for:

  • カメラによって最もよく使用されているオブジェクトに関する分析データをフェッチしています。Fetching analytics data about which object has been approached by the camera the most.
  • サービスキーを使用して、Azure アプリケーション Insights サービスインスタンスと通信できるようにします。Using the Service Keys, that allow communication with your Azure Application Insights Service instance.
  • イベント数が最も多いに従って、シーン内のオブジェクトを並べ替えます。Sorting the objects in scene, according to which has the highest event count.
  • 最も近づいたオブジェクトのマテリアルの色を緑色に変更します。Changing the material color, of the most approached object, to green.

スクリプトを作成するには:To create the script:

  1. [ Scripts ] フォルダーをダブルクリックして開きます。Double-click on the Scripts folder, to open it.

  2. Scriptsフォルダー内を右クリックし、[ C#スクリプト作成 > ] をクリックします。Right-click inside the Scripts folder, click Create > C# Script. スクリプトにDataFromAnalyticsという名前を指定します。Name the script DataFromAnalytics.

  3. スクリプトをダブルクリックして、Visual Studio で開きます。Double-click on the script to open it with Visual Studio.

  4. 次の名前空間を挿入します。Insert the following namespaces:

        using Newtonsoft.Json;
        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. スクリプト内に次の内容を挿入します。Inside the script, insert the following:

        /// <summary>
        /// Number of most recent events to be queried
        /// </summary>
        private int _quantityOfEventsQueried = 10;
    
        /// <summary>
        /// The timespan with which to query. Needs to be in hours.
        /// </summary>
        private int _timepspanAsHours = 24;
    
        /// <summary>
        /// A list of the objects in the scene
        /// </summary>
        private List<GameObject> _listOfGameObjectsInScene;
    
        /// <summary>
        /// Number of queries which have returned, after being sent.
        /// </summary>
        private int _queriesReturned = 0;
    
        /// <summary>
        /// List of GameObjects, as the Key, with their event count, as the Value.
        /// </summary>
        private List<KeyValuePair<GameObject, int>> _pairedObjectsWithEventCount = new List<KeyValuePair<GameObject, int>>();
    
        // Use this for initialization
        void Start()
        {
            // Find all objects in scene which have the ObjectInScene tag (as there may be other GameObjects in the scene which you do not want).
            _listOfGameObjectsInScene = GameObject.FindGameObjectsWithTag("ObjectInScene").ToList();
    
            FetchAnalytics();
        }
    
  6. DataFromAnalyticsクラス内で、 Start () メソッドの直後に、 fetchanalytics () という次のメソッドを追加します。Within the DataFromAnalytics class, right after the Start() method, add the following method called FetchAnalytics(). このメソッドは、キーと値のペアのリストを作成します。これには、設定オブジェクトとプレースホルダーイベント数を指定します。This method is responsible for populating the list of key value pairs, with a GameObject and a placeholder event count number. 次に、 Getwebrequest () コルーチンを初期化します。It then initializes the GetWebRequest() coroutine. Application Insightsの呼び出しのクエリ構造は、クエリ URLエンドポイントとしてもこのメソッド内にあります。The query structure of the call to Application Insights can be found within this method also, as the Query URL endpoint.

        private void FetchAnalytics()
        {
            // Iterate through the objects in the list
            for (int i = 0; i < _listOfGameObjectsInScene.Count; i++)
            {
                // The current event number is not known, so set it to zero.
                int eventCount = 0;
    
                // Add new pair to list, as placeholder, until eventCount is known.
                _pairedObjectsWithEventCount.Add(new KeyValuePair<GameObject, int>(_listOfGameObjectsInScene[i], eventCount));
    
                // Set the renderer of the object to the default color, white
                _listOfGameObjectsInScene[i].GetComponent<Renderer>().material.color = Color.white;
    
                // Create the appropriate object name using Insights structure
                string objectName = _listOfGameObjectsInScene[i].name;
    
                // Build the queryUrl for this object.
                string queryUrl = Uri.EscapeUriString(string.Format(
                    "https://api.applicationinsights.io/v1/apps/{0}/events/$all?timespan=PT{1}H&$search={2}&$select=customMetric/name&$top={3}&$count=true",
                    ApplicationInsightsTracker.Instance.applicationId, _timepspanAsHours, "Gazed " + objectName, _quantityOfEventsQueried));
    
    
                // Send this object away within the WebRequest Coroutine, to determine it is event count.
                StartCoroutine("GetWebRequest", new KeyValuePair<string, int>(queryUrl, i));
            }
        }
    
  7. Fetchanalytics () メソッドのすぐ下に、 IEnumeratorを返すgetwebrequest () というメソッドを追加します。Right below the FetchAnalytics() method, add a method called GetWebRequest(), which returns an IEnumerator. このメソッドは、特定のオブジェクトに対応するイベントがApplication Insights内で呼び出された回数を要求します。This method is responsible for requesting the number of times an event, corresponding with a specific GameObject, has been called within Application Insights. 送信されたすべてのクエリが返されると、決定E勝者 () メソッドが呼び出されます。When all the sent queries have returned, the DetermineWinner() method is called.

        /// <summary>
        /// Requests the data count for number of events, according to the
        /// input query URL.
        /// </summary>
        /// <param name="webQueryPair">Query URL and the list number count.</param>
        /// <returns></returns>
        private IEnumerator GetWebRequest(KeyValuePair<string, int> webQueryPair)
        {
            // Set the URL and count as their own variables (for readibility).
            string url = webQueryPair.Key;
            int currentCount = webQueryPair.Value;
    
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(url))
            {
                DownloadHandlerBuffer handlerBuffer = new DownloadHandlerBuffer();
    
                unityWebRequest.downloadHandler = handlerBuffer;
    
                unityWebRequest.SetRequestHeader("host", "api.applicationinsights.io");
    
                unityWebRequest.SetRequestHeader("x-api-key", ApplicationInsightsTracker.Instance.API_Key);
    
                yield return unityWebRequest.SendWebRequest();
    
                if (unityWebRequest.isNetworkError)
                {
                    // Failure with web request.
                    Debug.Log("<color=red>Error Sending:</color> " + unityWebRequest.error);
                }
                else
                {
                    // This query has returned, so add to the current count.
                    _queriesReturned++;
    
                    // Initialize event count integer.
                    int eventCount = 0;
    
                    // Deserialize the response with the custom Analytics class.
                    Analytics welcome = JsonConvert.DeserializeObject<Analytics>(unityWebRequest.downloadHandler.text);
    
                    // Get and return the count for the Event
                    if (int.TryParse(welcome.OdataCount, out eventCount) == false)
                    {
                        // Parsing failed. Can sometimes mean that the Query URL was incorrect.
                        Debug.Log("<color=red>Failure to Parse Data Results. Check Query URL for issues.</color>");
                    }
                    else
                    {
                        // Overwrite the current pair, with its actual values, now that the event count is known.
                        _pairedObjectsWithEventCount[currentCount] = new KeyValuePair<GameObject, int>(_pairedObjectsWithEventCount[currentCount].Key, eventCount);
                    }
    
                    // If all queries (compared with the number which was sent away) have 
                    // returned, then run the determine winner method. 
                    if (_queriesReturned == _pairedObjectsWithEventCount.Count)
                    {
                        DetermineWinner();
                    }
                }
            }
        }
    
  8. 次のメソッドは、最も高いイベント数に従って、判別オブジェクトIntのペアのリストを並べ替える、決定e勝者 () です。The next method is DetermineWinner(), which sorts the list of GameObject and Int pairs, according to the highest event count. 次に、そのオブジェクトの素材の色を緑色に変更します (最大カウントがあることに関するフィードバックとして)。It then changes the material color of that GameObject to green (as feedback for it having the highest count). これにより、分析結果を含むメッセージが表示されます。This displays a message with the analytics results.

        /// <summary>
        /// Call to determine the keyValue pair, within the objects list, 
        /// with the highest event count.
        /// </summary>
        private void DetermineWinner()
        {
            // Sort the values within the list of pairs.
            _pairedObjectsWithEventCount.Sort((x, y) => y.Value.CompareTo(x.Value));
    
            // Change its colour to green
            _pairedObjectsWithEventCount.First().Key.GetComponent<Renderer>().material.color = Color.green;
    
            // Provide the winner, and other results, within the console window. 
            string message = $"<b>Analytics Results:</b>\n " +
                $"<i>{_pairedObjectsWithEventCount.First().Key.name}</i> has the highest event count, " +
                $"with <i>{_pairedObjectsWithEventCount.First().Value.ToString()}</i>.\nFollowed by: ";
    
            for (int i = 1; i < _pairedObjectsWithEventCount.Count; i++)
            {
                message += $"{_pairedObjectsWithEventCount[i].Key.name}, " +
                    $"with {_pairedObjectsWithEventCount[i].Value.ToString()} events.\n";
            }
    
            Debug.Log(message);
        }
    
  9. Application Insightsから受信した JSON オブジェクトを逆シリアル化するために使用されるクラス構造を追加します。Add the class structure which will be used to deserialize the JSON object, received from Application Insights. これらのクラスは、クラス定義の外部にあるDataFromAnalyticsクラスファイルの一番下に追加します。Add these classes at the very bottom of your DataFromAnalytics class file, outside of the class definition.

        /// <summary>
        /// These classes represent the structure of the JSON response from Azure Insight
        /// </summary>
        [Serializable]
        public class Analytics
        {
            [JsonProperty("@odata.context")]
            public string OdataContext { get; set; }
    
            [JsonProperty("@odata.count")]
            public string OdataCount { get; set; }
    
            [JsonProperty("value")]
            public Value[] Value { get; set; }
        }
    
        [Serializable]
        public class Value
        {
            [JsonProperty("customMetric")]
            public CustomMetric CustomMetric { get; set; }
        }
    
        [Serializable]
        public class CustomMetric
        {
            [JsonProperty("name")]
            public string Name { get; set; }
        }
    
  10. Unityに戻る前に、変更内容をVisual Studioに保存してください。Be sure to save your changes in Visual Studio before returning to Unity.

Chapter 10-移動クラスを作成するChapter 10 - Create the Movement class

移動スクリプトは、次に作成する必要があるスクリプトです。The Movement script is the next script you will need to create. 次の役割があります。It is responsible for:

  • カメラが見ている方向に従って、メインカメラを移動します。Moving the Main Camera according to the direction the camera is looking towards.
  • シーンオブジェクトに他のすべてのスクリプトを追加します。Adding all other scripts to scene objects.

スクリプトを作成するには:To create the script:

  1. [ Scripts ] フォルダーをダブルクリックして開きます。Double-click on the Scripts folder, to open it.

  2. Scriptsフォルダー内を右クリックし、[ C#スクリプト作成 > ] をクリックします。Right-click inside the Scripts folder, click Create > C# Script. スクリプトの移動に名前を指定します。Name the script Movement.

  3. スクリプトをダブルクリックして、 Visual Studioで開きます。Double-click on the script to open it with Visual Studio.

  4. 既存のコードを次のコードに置き換えます。Replace the existing code with the following:

        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
    
        public class Movement : MonoBehaviour
        {
            /// <summary>
            /// The rendered object representing the right controller.
            /// </summary>
            public GameObject Controller;
    
            /// <summary>
            /// The movement speed of the user.
            /// </summary>
            public float UserSpeed;
    
            /// <summary>
            /// Provides whether source updates have been registered.
            /// </summary>
            private bool _isAttached = false;
    
            /// <summary>
            /// The chosen controller hand to use. 
            /// </summary>
            private InteractionSourceHandedness _handness = InteractionSourceHandedness.Right;
    
            /// <summary>
            /// Used to calculate and proposes movement translation.
            /// </summary>
            private Vector3 _playerMovementTranslation;
    
            private void Start()
            {
                // You are now adding components dynamically 
                // to ensure they are existing on the correct object  
    
                // Add all camera related scripts to the camera. 
                Camera.main.gameObject.AddComponent<Gaze>();
                Camera.main.gameObject.AddComponent<ObjectTrigger>();
    
                // Add all other scripts to this object.
                gameObject.AddComponent<ApplicationInsightsTracker>();
                gameObject.AddComponent<DataFromAnalytics>();
            }
    
            // Update is called once per frame
            void Update()
            {
    
            }
        }
    
  5. 移動クラス内で、空のUpdate () メソッドのに、ユーザーがハンドコントローラーを使用して仮想空間内を移動できるようにする次のメソッドを挿入します。Within the Movement class, below the empty Update() method, insert the following methods that allow the user to use the hand controller to move in the virtual space:

        /// <summary>
        /// Used for tracking the current position and rotation of the controller.
        /// </summary>
        private void UpdateControllerState()
        {
    #if UNITY_WSA && UNITY_2017_2_OR_NEWER
            // Check for current connected controllers, only if WSA.
            string message = string.Empty;
    
            if (InteractionManager.GetCurrentReading().Length > 0)
            {
                foreach (var sourceState in InteractionManager.GetCurrentReading())
                {
                    if (sourceState.source.kind == InteractionSourceKind.Controller && sourceState.source.handedness == _handness)
                    {
                        // If a controller source is found, which matches the selected handness, 
                        // check whether interaction source updated events have been registered. 
                        if (_isAttached == false)
                        {
                            // Register events, as not yet registered.
                            message = "<color=green>Source Found: Registering Controller Source Events</color>";
                            _isAttached = true;
    
                            InteractionManager.InteractionSourceUpdated += InteractionManager_InteractionSourceUpdated;
                        }
    
                        // Update the position and rotation information for the controller.
                        Vector3 newPosition;
                        if (sourceState.sourcePose.TryGetPosition(out newPosition, InteractionSourceNode.Pointer) && ValidPosition(newPosition))
                        {
                            Controller.transform.localPosition = newPosition;
                        }
    
                        Quaternion newRotation;
    
                        if (sourceState.sourcePose.TryGetRotation(out newRotation, InteractionSourceNode.Pointer) && ValidRotation(newRotation))
                        {
                            Controller.transform.localRotation = newRotation;
                        }
                    }
                }
            }
            else
            {
                // Controller source not detected. 
                message = "<color=blue>Trying to detect controller source</color>";
    
                if (_isAttached == true)
                {
                    // A source was previously connected, however, has been lost. Disconnected
                    // all registered events. 
    
                    _isAttached = false;
    
                    InteractionManager.InteractionSourceUpdated -= InteractionManager_InteractionSourceUpdated;
    
                    message = "<color=red>Source Lost: Detaching Controller Source Events</color>";
                }
            }
    
            if(message != string.Empty)
            {
                Debug.Log(message);
            }
    #endif
        }
    
        /// <summary>
        /// This registered event is triggered when a source state has been updated.
        /// </summary>
        /// <param name="obj"></param>
        private void InteractionManager_InteractionSourceUpdated(InteractionSourceUpdatedEventArgs obj)
        {
            if (obj.state.source.handedness == _handness)
            {
                if(obj.state.thumbstickPosition.magnitude > 0.2f)
                {
                    float thumbstickY = obj.state.thumbstickPosition.y;
    
                    // Vertical Input.
                    if (thumbstickY > 0.3f || thumbstickY < -0.3f)
                    {
                        _playerMovementTranslation = Camera.main.transform.forward;
                        _playerMovementTranslation.y = 0;
                        transform.Translate(_playerMovementTranslation * UserSpeed * Time.deltaTime * thumbstickY, Space.World);
                    }
                }
            }
        }
    
        /// <summary>
        /// Check that controller position is valid. 
        /// </summary>
        /// <param name="inputVector3">The Vector3 to check</param>
        /// <returns>The position is valid</returns>
        private bool ValidPosition(Vector3 inputVector3)
        {
            return !float.IsNaN(inputVector3.x) && !float.IsNaN(inputVector3.y) && !float.IsNaN(inputVector3.z) && !float.IsInfinity(inputVector3.x) && !float.IsInfinity(inputVector3.y) && !float.IsInfinity(inputVector3.z);
        }
    
        /// <summary>
        /// Check that controller rotation is valid. 
        /// </summary>
        /// <param name="inputQuaternion">The Quaternion to check</param>
        /// <returns>The rotation is valid</returns>
        private bool ValidRotation(Quaternion inputQuaternion)
        {
            return !float.IsNaN(inputQuaternion.x) && !float.IsNaN(inputQuaternion.y) && !float.IsNaN(inputQuaternion.z) && !float.IsNaN(inputQuaternion.w) && !float.IsInfinity(inputQuaternion.x) && !float.IsInfinity(inputQuaternion.y) && !float.IsInfinity(inputQuaternion.z) && !float.IsInfinity(inputQuaternion.w);
        }   
    
  6. 最後に、 Update () メソッド内にメソッド呼び出しを追加します。Lastly add the method call within the Update() method.

        // Update is called once per frame
        void Update()
        {
            UpdateControllerState();
        }
    
  7. Unityに戻る前に、変更内容をVisual Studioに保存してください。Be sure to save your changes in Visual Studio before returning to Unity.

Chapter 11-スクリプト参照の設定Chapter 11 - Setting up the scripts references

この章では、移動スクリプトをカメラの親に配置し、その参照ターゲットを設定する必要があります。In this Chapter you need to place the Movement script onto the Camera Parent and set its reference targets. そのスクリプトは、必要な場所にある他のスクリプトの配置を処理します。That script will then handle placing the other scripts where they need to be.

  1. [プロジェクト] パネルの [スクリプト] フォルダーで、[階層] パネルにある [カメラ] 親オブジェクトに移動スクリプトをドラッグします。From the Scripts folder in the Project Panel, drag the Movement script to the Camera Parent object, located in the Hierarchy Panel.

    Unity シーンでのスクリプト参照の設定

  2. カメラの親をクリックします。Click on the Camera Parent. [階層] パネルで、[階層] パネルの右側のオブジェクトを [インスペクター] パネルの [参照ターゲット] の [コントローラー] にドラッグします。In the Hierarchy Panel, drag the Right Hand object from the Hierarchy Panel to the reference target, Controller, in the Inspector Panel. 次の図に示すように、ユーザーの速度5に設定します。Set the User Speed to 5, as shown in the image below.

    Unity シーンでのスクリプト参照の設定

第12章-Unity プロジェクトのビルドChapter 12 - Build the Unity project

このプロジェクトの Unity セクションに必要なものはすべて完了したので、Unity から構築します。Everything needed for the Unity section of this project has now been completed, so it is time to build it from Unity.

  1. [ビルドの設定]、([ファイル > ビルドの設定]) の順に移動します。Navigate to Build Settings, (File > Build Settings).

  2. [ビルドの設定] ウィンドウで、[ビルド] をクリックします。From the Build Settings window, click Build.

    Unity プロジェクトを UWP ソリューションにビルドする

  3. エクスプローラーウィンドウがポップアップ表示され、ビルドの場所を入力するように求められます。A File Explorer window will pop-up, prompting you for a location for the build. (左上隅にある [新しいフォルダー ] をクリックして) 新しいフォルダーを作成し、ビルドという名前を指定します。Create a new folder (by clicking New Folder in the top-left corner), and name it BUILDS.

    Unity プロジェクトを UWP ソリューションにビルドする

    1. [新しいビルド] フォルダーを開き、別のフォルダーを作成し ([新しいフォルダー ] をもう一度使用)、「 MR_Azure_Application_Insights」という名前を指定します。Open the new BUILDS folder, and create another folder (using New Folder once more), and name it MR_Azure_Application_Insights.

      Unity プロジェクトを UWP ソリューションにビルドする

    2. MR_Azure_ApplicationInsights_ フォルダーを選択した状態で、[フォルダーの選択] をクリックします。With the MR_Azure_Application_Insights folder selected, click Select Folder. プロジェクトがビルドされるまでに1分ほどかかります。The project will take a minute or so to build.

  4. 次のビルドでは、新しいプロジェクトの場所を示すファイルエクスプローラーが表示されます。Following Build, File Explorer will appear showing you the location of your new project.

第13章: MR_Azure_Application_Insights アプリをコンピューターにデプロイするChapter 13 - Deploy MR_Azure_Application_Insights app to your machine

ローカルコンピューターにMR_Azure_Application_Insightsアプリをデプロイするには、次のようにします。To deploy the MR_Azure_Application_Insights app on your Local Machine:

  1. Visual StudioMR__Azure Application_Insightsアプリのソリューションファイルを開きます。Open the solution file of your MR_Azure_Application_Insights app in Visual Studio.

  2. ソリューションプラットフォームで、[ X86, ローカルコンピューター] を選択します。In the Solution Platform, select x86, Local Machine.

  3. ソリューション構成で、[デバッグ] を選択します。In the Solution Configuration select Debug.

    Unity プロジェクトを UWP ソリューションにビルドする

  4. [ビルド] メニューの [ソリューションの配置] をクリックして、アプリケーションをコンピューターにサイドロードします。Go to Build menu and click on Deploy Solution to sideload the application to your machine.

  5. アプリがインストール済みのアプリの一覧に表示され、起動できる状態になります。Your app should now appear in the list of installed apps, ready to be launched.

  6. Mixed reality アプリケーションを起動します。Launch the mixed reality application.

  7. シーン内を移動し、オブジェクトに近づいて、それらを確認すると、 Azure Insights サービスが十分なイベントデータを収集したときに、最も近いオブジェクトが緑色に設定されます。Move around the scene, approaching objects and looking at them, when the Azure Insight Service has collected enough event data, it will set the object that has been approached the most to green.

重要

サービスによって収集されるイベントとメトリックの平均待機時間は約15分かかりますが、場合によっては最大1時間かかることがあります。While the average waiting time for the Events and Metrics to be collected by the Service takes around 15 min, in some occasions it might take up to 1 hour.

第14章-Application Insights サービスポータルChapter 14 - The Application Insights Service portal

複数のオブジェクトでシーンと gazed を移動すると、 Application Insights サービスポータルで収集されたデータを確認できます。Once you have roamed around the scene and gazed at several objects you can see the data collected in the Application Insights Service portal.

  1. Application Insights サービスポータルに戻ります。Go back to your Application Insights Service portal.

  2. [メトリックスエクスプローラー] をクリックします。Click on Metrics Explorer.

    収集したデータの表示

  3. これは、アプリケーションに関連するイベントとメトリックを表すグラフを含むタブで開きます。It will open in a tab containing the graph which represent the Events and Metrics related to your application. 前述のように、データがグラフに表示されるまでに時間がかかる場合があります (最大1時間)。As mentioned above, it might take some time (up to 1 hour) for the data to be displayed in the graph

    収集したデータの表示

  4. [アプリケーションバージョンごとのイベントの総数] のイベントバーをクリックすると、イベントの詳細な内訳が名前と共に表示されます。Click on the Events bar in the Total of Events by Application Version, to see a detailed breakdown of the events with their names.

    収集したデータの表示

Application Insights サービスアプリケーションが完成しましたYour finished your Application Insights Service application

これで、Application Insights サービスを活用してアプリ内でユーザーのアクティビティを監視する、mixed reality アプリが作成されました。Congratulations, you built a mixed reality app that leverages the Application Insights Service to monitor user's activity within your app.

コースの結果

ボーナスの演習Bonus Exercises

演習1Exercise 1

オブジェクトを手動で作成するのではなく、オブジェクトを手動で作成し、スクリプト内の平面上に座標を設定します。Try spawning, rather than manually creating, the ObjectInScene objects and set their coordinates on the plane within your scripts. このようにして、最も人気のあるオブジェクト (つまり、宝石または近接の結果) を Azure に要求し、それらのオブジェクトのうちの1つを生成することができます。In this way, you could ask Azure what the most popular object was (either from gaze or proximity results) and spawn an extra one of those objects.

演習2Exercise 2

Application Insights の結果を時間で並べ替えて、最も関連性の高いデータを取得し、その時間に依存するデータをアプリケーションに実装します。Sort your Application Insights results by time, so that you get the most relevant data, and implement that time sensitive data in your application.