305. Смешанная реальность и Azure: функции и хранилищеMR and Azure 305: Functions and storage


Примечание

Руководства 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.


окончательный продукт — запуск

В этом курсе вы узнаете, как создавать и использовать функции Azure и хранить данные в ресурсе службы хранилища Azure в приложении смешанной реальности.In this course, you will learn how to create and use Azure Functions and store data with an Azure Storage resource, within a mixed reality application.

Функции Azure — это служба Майкрософт, которая позволяет разработчикам запускать небольшие фрагменты кода "функции" в Azure.Azure Functions is a Microsoft service, which allows developers to run small pieces of code, 'functions', in Azure. Это позволяет делегировать работу в облако, а не локальное приложение, которое может иметь множество преимуществ.This provides a way to delegate work to the cloud, rather than your local application, which can have many benefits. Функции Azure поддерживают несколько языков разработки, включая C # , F # , Node.js, Java и PHP.Azure Functions supports several development languages, including C#, F#, Node.js, Java, and PHP. Дополнительные сведения см. в статье о функциях Azure.For more information, visit the Azure Functions article.

Хранилище Azure — это облачная служба Майкрософт, которая позволяет разработчикам хранить данные с страховкой, которая будет высокодоступной, безопасной, устойчивой, масштабируемой и избыточной.Azure Storage is a Microsoft cloud service, which allows developers to store data, with the insurance that it will be highly available, secure, durable, scalable, and redundant. Это означает, что корпорация Майкрософт будет выполнять все задачи обслуживания и критические проблемы.This means Microsoft will handle all maintenance, and critical problems for you. Дополнительные сведения см. в статье о службе хранилища Azure.For more information, visit the Azure Storage article.

Прополнив этот курс, вы получите иммерсивное приложение для наушников, которое сможет сделать следующее: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 around a scene.
  2. Активировать порождение объектов, когда пользователь высматривает трехмерную кнопку "Кнопка".Trigger the spawning of objects when the user gazes at a 3D 'button'.
  3. Порожденные объекты будут выбраны функцией Azure.The spawned objects will be chosen by an Azure Function.
  4. При порождении каждого объекта приложение сохранит тип объекта в файле Azure, расположенном в службе хранилища Azure.As each object is spawned, the application will store the object type in an Azure File, located in Azure Storage.
  5. После второй загрузки данные файла Azure будут получены и использованы для воспроизведения порожденных действий от предыдущего экземпляра приложения.Upon loading a second time, the Azure File data will be retrieved, and used to replay the spawning actions from the previous instance of the application.

В приложении вы будете выполнять интеграцию результатов с вашей структурой.In your application, it is up to you as to how you will integrate the results with your design. Этот курс предназначен для изучения того, как интегрировать службу Azure с проектом Unity.This course is designed to teach you how to integrate an Azure Service with your Unity Project. Это ваша задача использовать знания, полученные из этого курса, для улучшения приложения смешанной реальности.It is your job to use the knowledge you gain from this course to enhance your mixed reality Application.

Поддержка устройствDevice support

КурсCourse HoloLensHoloLens Иммерсивные гарнитурыImmersive headsets
305. Смешанная реальность и Azure: функции и хранилищеMR and Azure 305: Functions and storage ✔️✔️ ✔️✔️

Примечание

Хотя этот курс в основном ориентирован на гарнитуры 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.

Предварительные требованияPrerequisites

Примечание

Этот учебник предназначен для разработчиков, имеющих базовый опыт работы с Unity и C#.This tutorial is designed for developers who have basic experience with Unity and C#. Также имейте в виду, что предварительные требования и письменные инструкции в этом документе отражают, что проверялось и проверено во время написания статьи (Май 2018).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 (May 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'll find in newer software than what's 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).

Глава 1. портал AzureChapter 1 - The Azure Portal

Чтобы использовать службу хранилища Azure, вам потребуется создать и настроить учетную запись хранения в портал Azure.To use the Azure Storage Service, you will need to create and configure a Storage Account 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. Войдя в систему, щелкните New ( создать ) в левом верхнем углу, а затем найдите учетную запись хранения и нажмите клавишу Ввод.Once you are logged in, click on New in the top left corner, and search for Storage account, and click Enter.

    Поиск в службе хранилища Azure

    Примечание

    Слово New может быть заменено на создать ресурс в новых порталах.The word New may have been replaced with Create a resource, in newer portals.

  3. На новой странице будет представлено описание службы учетной записи хранения Azure .The new page will provide a description of the Azure Storage account service. В нижнем левом углу этого запроса нажмите кнопку создать , чтобы создать связь с этой службой.At the bottom left of this prompt, select the Create button, to create an association with this service.

    Создание службы

  4. После нажатия кнопки создать:Once you have clicked on Create:

    1. Введите имя для своей учетной записи. Имейте в виду, что это поле принимает только цифры и строчные буквы.Insert a Name for your account, be aware this field only accepts numbers, and lowercase letters.

    2. В качестве модели развертывания выберите Resource Manager.For Deployment model, select Resource manager.

    3. В качестве типа учетной записи выберите хранилище (общее назначение v1).For Account kind, select Storage (general purpose v1).

    4. Определите Расположение группы ресурсов (при создании новой группы ресурсов).Determine the Location for your resource group (if you are creating a new Resource Group). В идеале это расположение будет находиться в регионе, в котором будет выполняться приложение.The location would ideally be in the region where the application would run. Некоторые ресурсы Azure доступны только в определенных регионах.Some Azure assets are only available in certain regions.

    5. Для репликации выберите геоизбыточное хранилище (RA-GRS) с доступом для чтения.For Replication select Read-access-geo-redundant storage (RA-GRS).

    6. В разделе Производительность выберите Стандартная.For Performance, select Standard.

    7. Оставьте защищенное перемещение обязательным , как отключено.Leave Secure transfer required as Disabled.

    8. Выберите подписку.Select a Subscription.

    9. Выберите группу ресурсов или создайте новую.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. Рекомендуется, чтобы все службы Azure, связанные с одним проектом (например, в этих лабораториях), были в общей группе ресурсов.It is recommended to keep all the Azure services associated with a single project (e.g. such as these labs) under a common resource group).

      Если вы хотите ознакомиться с дополнительными сведениями о группах ресурсов Azure, обратитесь к статье о группе ресурсов.If you wish to read more about Azure Resource Groups, please visit the resource group article.

    10. Также необходимо подтвердить, что вы поняли условия, примененные к этой службе.You will also need to confirm that you have understood the Terms and Conditions applied to this Service.

    11. Нажмите кнопку Создать.Select Create.

      сведения о входной службе

  5. После нажатия кнопки создать необходимо подождать, пока не будет создана служба, а это может занять некоторое время.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.

    Переход к ресурсу

  8. Нажмите кнопку " Переход к ресурсу " в уведомлении, чтобы изучить новый экземпляр службы.Click the Go to resource button in the notification to explore your new Service instance. Вы будете перенаправлены на новый экземпляр службы учетной записи хранения .You will be taken to your new Storage account service instance.

    ключи доступа

  9. Щелкните ключи доступа, чтобы отобразить конечные точки для этой облачной службы.Click Access keys, to reveal the endpoints for this cloud service. Чтобы скопировать один из ключей для последующего использования, используйте Блокнот или аналогичный.Use Notepad or similar, to copy one of your keys for use later. Кроме того, обратите внимание на значение строки подключения , так как оно будет использоваться в классе азуресервицес , который будет создан позже.Also, note the Connection string value, as it will be used in the AzureServices class, which you will create later.

    Копировать строку подключения

Глава 2. Настройка функции AzureChapter 2 - Setting up an Azure Function

Теперь вы можете написать функцию Azure Function в службе Azure.You will now write an Azure Function in the Azure Service.

Функцию Azure можно использовать для практически любых действий, выполняемых с классической функцией в коде. разница заключается в том, что доступ к этой функции может осуществляться любым приложением, имеющим учетные данные для доступа к учетной записи Azure.You can use an Azure Function to do nearly anything that you would do with a classic function in your code, the difference being that this function can be accessed by any application that has credentials to access your Azure Account.

Чтобы создать функцию Azure, выполните следующие действия.To create an Azure Function:

  1. На портале Azure щелкните создать в левом верхнем углу и найдите приложение-функция и нажмите клавишу Ввод.From your Azure Portal, click on New in the top left corner, and search for Function App, and click Enter.

    Создание приложения функции

    Примечание

    Слово New может быть заменено на создать ресурс в новых порталах.The word New may have been replaced with Create a resource, in newer portals.

  2. На новой странице будет представлено описание службы приложение-функция Azure .The new page will provide a description of the Azure Function App service. В нижнем левом углу этого запроса нажмите кнопку создать , чтобы создать связь с этой службой.At the bottom left of this prompt, select the Create button, to create an association with this service.

    сведения о приложении функции

  3. После нажатия кнопки создать:Once you have clicked on Create:

    1. Укажите имя приложения.Provide an App name. Здесь можно использовать только буквы и цифры (допускается использование прописных и строчных букв).Only letters and numbers can be used here (either upper or lower case is allowed).

    2. Выберите предпочитаемую подписку.Select your preferred Subscription.

    3. Выберите группу ресурсов или создайте новую.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. Рекомендуется, чтобы все службы Azure, связанные с одним проектом (например, в этих лабораториях), были в общей группе ресурсов.It is recommended to keep all the Azure services associated with a single project (e.g. such as these labs) under a common resource group).

      Если вы хотите ознакомиться с дополнительными сведениями о группах ресурсов Azure, обратитесь к статье о группе ресурсов.If you wish to read more about Azure Resource Groups, please visit the resource group article.

    4. В этом упражнении выберите Windows в качестве выбранной ОС.For this exercise, select Windows as the chosen OS.

    5. Выберите план потребления для плана размещения.Select Consumption Plan for the Hosting Plan.

    6. Определите Расположение группы ресурсов (при создании новой группы ресурсов).Determine the Location for your resource group (if you are creating a new Resource Group). В идеале это расположение будет находиться в регионе, в котором будет выполняться приложение.The location would ideally be in the region where the application would run. Некоторые ресурсы Azure доступны только в определенных регионах.Some Azure assets are only available in certain regions. Для оптимальной производительности выберите тот же регион, что и для учетной записи хранения.For optimal performance, select the same region as the storage account.

    7. В поле хранилище выберите использовать существующий, а затем в раскрывающемся меню найдите созданное ранее хранилище.For Storage, select Use existing, and then using the dropdown menu, find your previously created storage.

    8. Для этого упражнения не выполняйте Application Insights .Leave Application Insights off for this exercise.

      сведения о приложении входной функции

  4. Нажмите кнопку Создать .Click the Create button.

  5. После нажатия кнопки создать необходимо подождать, пока не будет создана служба, а это может занять некоторое время.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.

    Переход к приложению функции ресурсов

  8. Нажмите кнопку " Переход к ресурсу " в уведомлении, чтобы изучить новый экземпляр службы.Click the Go to resource button in the notification to explore your new Service instance. Вы будете перенаправлены на новый экземпляр службы приложение-функция .You will be taken to your new Function App service instance.

  9. На панели мониторинга приложение-функция наведите указатель мыши на функции, расположенные на панели слева, а затем щелкните символ + (плюс) .On the Function App dashboard, hover your mouse over Functions, found within the panel on the left, and then click the + (plus) symbol.

    создать новую функцию

  10. На следующей странице убедитесь, что веб-перехватчик + API выбран, и для выбора языка выберите CSharp, так как это будет язык, используемый в этом руководстве.On the next page, ensure Webhook + API is selected, and for Choose a language, select CSharp, as this will be the language used for this tutorial. Наконец, нажмите кнопку создать эту функцию .Lastly, click the Create this function button.

    Выбор веб-перехватчика CSharp

  11. Вы должны присутствовать на кодовой странице (Run. CSX), если это не так, щелкните созданную функцию в списке функции на панели слева.You should be taken to the code page (run.csx), if not though, click on the newly created Function in the Functions list within the panel on the left.

    открыть новую функцию

  12. Скопируйте следующий код в функцию.Copy the following code into your function. Эта функция будет просто возвращать случайное целое число от 0 до 2 при вызове.This function will simply return a random integer between 0 and 2 when called. Не беспокойтесь о существующем коде, вы можете вставить его в верхнюю часть.Do not worry about the existing code, feel free to paste over the top of it.

        using System.Net;
        using System.Threading.Tasks;
    
        public static int Run(CustomObject req, TraceWriter log)
        {
            Random rnd = new Random();
            int randomInt = rnd.Next(0, 3);
            return randomInt;
        }
    
        public class CustomObject
        {
            public String name {get; set;}
        }
    
  13. Нажмите кнопку Сохранить.Select Save.

  14. Результат должен выглядеть, как показано на рисунке ниже.The result should look like the image below.

  15. Щелкните получить URL-адрес функции и обратите внимание на отображаемую конечную точку .Click on Get function URL and take note of the endpoint displayed. Его необходимо вставить в класс азуресервицес , который будет создан далее в этом курсе.You will need to insert it into the AzureServices class that you will create later in this course.

    Получение конечной точки функции

    Вставить конечную точку функции

Глава 3. Настройка проекта UnityChapter 3 - Setting up the Unity project

Ниже приведена типичная Настройка для разработки с использованием смешанной реальности, которая является хорошим шаблоном для других проектов.The following is a typical set up for developing with Mixed Reality, and as such, is a good template for other projects.

Настройка и тестирование иммерсивного наушников смешанной реальности.Set up and test your mixed reality immersive headset.

Примечание

Для этого курса не потребуется использовать контроллеры движения.You will not require Motion Controllers for this course. Если вам нужна поддержка настройки иммерсивного головного телефона, посетите статью Настройка смешанной реальности.If you need support setting up the immersive headset, please visit the mixed reality set up article.

  1. Откройте Unity и нажмите кнопку создать.Open Unity and click New.

    Создать новый проект Unity

  2. Теперь необходимо указать имя проекта Unity.You will now need to provide a Unity Project name. Вставка MR_Azure_Functions.Insert MR_Azure_Functions. Убедитесь, что для типа проекта задано значение 3D.Make sure the project type 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. Измените Редактор внешних скриптов на Visual Studio 2017.Change External Script Editor to Visual Studio 2017. Закройте окно настройки .Close the Preferences window.

    Установка Visual Studio в качестве редактора скриптов

  4. Затем перейдите в раздел File > параметры сборки файлов и переключите платформу на универсальная платформа Windows, нажав кнопку коммутатора на платформе .Next, go to File > Build Settings and switch the platform to Universal Windows Platform, by clicking on the Switch Platform button.

    Переключение платформы в UWP

  5. Перейдите в File раздел > параметры сборки файлов и убедитесь в том, что:Go to File > Build Settings and make sure that:

    1. Целевое устройство настроено для любого устройства.Target Device is set to Any Device.

      Для Microsoft HoloLens задайте для параметра целевое устройство значение HoloLens.For Microsoft HoloLens, set Target Device to HoloLens.

    2. Для типа сборки задано значение D3DBuild Type is set to D3D

    3. Пакет SDK установлен в значение " Последняя установка "SDK is set to Latest installed

    4. Для версии Visual Studio установлено значение " Последняя установка "Visual Studio Version is set to Latest installed

    5. Сборка и запуск настроены на локальный компьютерBuild and Run is set to Local Machine

    6. Сохраните сцену и добавьте ее в сборку.Save the scene and add it to the build.

      1. Для этого выберите Добавить открытые сцены.Do this by selecting Add Open Scenes. Появится окно сохранения.A save window will appear.

        Добавление открытых сцен

      2. Создайте новую папку для этого, а также любой будущей сцены, а затем нажмите кнопку создать папку , чтобы создать новую папку, назовите ее « сцены».Create a new folder for this, and any future, scene, then select the New folder button, to create a new folder, name it Scenes.

        создать папку сцен

      3. Откройте созданную папку сцены , а затем в текстовом поле имя файла введите функтионссцене, а затем нажмите кнопку сохранить.Open your newly created Scenes folder, and then in the File name: text field, type FunctionsScene, then press Save.

        Сохранить сцену функций

  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.

    Параметры проигрывателя в инспекторе

  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. Серверная часть сценариев должна быть .NETScripting Backend should be .NET
      3. Уровень совместимости API должен быть .NET 4,6API Compatibility Level should be .NET 4.6
    2. На вкладке Параметры публикации в разделе возможности установите флажок:Within the Publishing Settings tab, under Capabilities, check:

      • InternetClient;InternetClient

        Установка возможностей

    3. На более низких панели в параметрах XR (см. ниже Параметры публикации), поддерживаемая виртуальная реальность Tick, убедитесь, что добавлен пакет SDK для Windows Mixed Reality .Further down the panel, in XR Settings (found below Publishing Settings), tick Virtual Reality Supported, make sure the Windows Mixed Reality SDK is added.

      задать параметры XR

  9. Назад в параметрах сборки проекты C# Unity больше не заключаются; Установите флажок рядом с этим.Back in Build Settings Unity C# Projects is no longer greyed out; tick the checkbox next to this.

    проекты тактов c#

  10. Закройте окно Build Settings (Параметры сборки).Close the Build Settings window.

  11. Сохраните сцену и проект (файл > сохранить сцену/файл > сохранить проект).Save your Scene and Project (FILE > SAVE SCENE / FILE > SAVE PROJECT).

Глава 4. Настройка основной камерыChapter 4 - Setup Main Camera

Важно!

Если вы хотите пропустить настройку Unity, настроили компоненты этого курса и продолжить работу с кодом, Скачайте этот файл. пакет unitypackageи импортируйте его в проект как пользовательский пакет.If you wish to skip the Unity Set up components of this course, and continue straight into code, feel free to download this .unitypackage, and import it into your project as a Custom Package. Это также будет содержать библиотеки DLL из следующей главы.This will also contain the DLLs from the next Chapter. После импорта продолжите работу с главой 7.After import, continue from Chapter 7.

  1. На панели Иерархия вы найдете объект с названием Главная камера, этот объект представляет "головную точку представления", когда вы "внутри приложения".In the Hierarchy Panel, you will find an object called Main Camera, this object represents your "head" point of view once you are "inside" your application.

  2. На панели мониторинга Unity перед вами выберите основную камеру GameObject.With the Unity Dashboard in front of you, select the Main Camera GameObject. Вы заметите, что на панели инспектора (как правило, на панели мониторинга) отображаются различные компоненты этого GameObject, с помощью кнопки преобразовывать в верхней части, за которой следует Камера и некоторые другие компоненты.You will notice that the Inspector Panel (generally found to the right, within the Dashboard) will show the various components of that GameObject, with Transform at the top, followed by Camera, and some other components. Необходимо будет сбросить преобразование основной камеры, чтобы она правильно расположиться.You will need to reset the Transform of the Main Camera, so it is positioned correctly.

  3. Для этого щелкните значок шестеренки рядом с компонентом преобразования камеры и выберите сбросить.To do this, select the Gear icon next to the Camera's Transform component, and select Reset.

    Сброс преобразования

  4. Затем обновите компонент преобразования , чтобы он выглядел следующим образом:Then update the Transform component to look like:

    TRANSFORM-ПОЗИЦИОНИРОВАНИЕTRANSFORM - POSITION
    XX даY ZZ
    00 11 00
    ПОВОРОТ ПРЕОБРАЗОВАНИЯTRANSFORM - ROTATION
    XX даY ZZ
    00 00 00
    ПРЕОБРАЗОВАНИЕ — МАСШТАБИРОВАНИЕTRANSFORM - SCALE
    XX даY ZZ
    11 11 11

    Задание преобразования камеры

Глава 5. Настройка сцены UnityChapter 5 - Setting up the Unity scene

  1. Щелкните правой кнопкой мыши пустую область панели Иерархия в разделе трехмерный объект, добавьте плоскость.Right-click in an empty area of the Hierarchy Panel, under 3D Object, add a Plane.

    Создание новой плоскости

  2. Выбрав объект плоскости , измените следующие параметры на панели инспектора:With the Plane object selected, change the following parameters in the Inspector Panel:

    TRANSFORM-ПОЗИЦИОНИРОВАНИЕTRANSFORM - POSITION
    XX даY ZZ
    00 00 44
    ПРЕОБРАЗОВАНИЕ — МАСШТАБИРОВАНИЕTRANSFORM - SCALE
    XX даY ZZ
    1010 11 1010

    Задание расположения и масштаба плоскости

    представление сцены плоскости

  3. Щелкните правой кнопкой мыши пустую область панели Иерархия в разделе трехмерный объект и добавьте куб.Right-click in an empty area of the Hierarchy Panel, under 3D Object, add a Cube.

    1. Переименование Куба в газебуттон (с выбранным кубом нажмите клавишу "F2").Rename the Cube to GazeButton (with the Cube selected, press 'F2').

    2. Измените следующие параметры на панели инспектора:Change the following parameters in the Inspector Panel:

      TRANSFORM-ПОЗИЦИОНИРОВАНИЕTRANSFORM - POSITION
      XX даY ZZ
      00 33 55

      задать преобразование кнопки взвзгляда

      представление сцены кнопки взгляда

    3. Щелкните раскрывающийся список тег и выберите Добавить тег , чтобы открыть панель Теги & слои.Click on the Tag drop-down button and click on Add Tag to open the Tags & Layers Pane.

      Добавить новый тег

      выбрать плюс

    4. Нажмите кнопку + (плюс) и в поле новое имя тега введите газебуттон и нажмите кнопку сохранить.Select the + (plus) button, and in the New Tag Name field, enter GazeButton, and press Save.

      имя новый тег

    5. Щелкните объект газебуттон на панели Иерархия, а затем на панели инспектора назначьте созданный тег газебуттон .Click on the GazeButton object in the Hierarchy Panel, and in the Inspector Panel, assign the newly created GazeButton tag.

      назначить кнопке "взгляд" новый тег

  4. Щелкните правой кнопкой мыши объект газебуттон на панели Иерархия и добавьте пустой GameObject (который будет добавлен в качестве дочернего объекта).Right-click on the GazeButton object, in the Hierarchy Panel, and add an Empty GameObject (which will be added as a child object).

  5. Выберите новый объект и переименуйте его в шапеспавнпоинт.Select the new object and rename it ShapeSpawnPoint.

    1. Измените следующие параметры на панели инспектора:Change the following parameters in the Inspector Panel:

      TRANSFORM-ПОЗИЦИОНИРОВАНИЕTRANSFORM - POSITION
      XX даY ZZ
      00 -1-1 00

      Обновление преобразования точки порождения фигуры

      представление сцены создания точки порождения фигуры

  6. Далее предстоит создать трехмерный текстовый объект, чтобы оставить отзыв о состоянии службы Azure.Next you will create a 3D Text object to provide feedback on the status of the Azure service.

    Щелкните правой кнопкой мыши газебуттон на панели Иерархия и добавьте трехмерный 3D Object трехмерный объект > 3D Object в качестве дочернего.Right click on the GazeButton in the Hierarchy Panel again and add a 3D Object > 3D Text object as a child.

    создать новый объект объемного текста

  7. Переименуйте трехмерный текстовый объект в азурестатустекст.Rename the 3D Text object to AzureStatusText.

  8. Измените преобразование объекта азурестатустекст следующим образом:Change the AzureStatusText object Transform as follows:

    TRANSFORM-ПОЗИЦИОНИРОВАНИЕTRANSFORM - POSITION
    XX даY ZZ
    00 00 –0,6-0.6
    ПРЕОБРАЗОВАНИЕ — МАСШТАБИРОВАНИЕTRANSFORM - SCALE
    XX даY ZZ
    0,10.1 0,10.1 0,10.1

    Примечание

    Не беспокойтесь, если он находится вне сети, так как это будет исправлено при обновлении компонента сетки текста.Do not worry if it appears to be off-centre, as this will be fixed when the below Text Mesh component is updated.

  9. Измените компонент " Сетка текста " в соответствии с приведенным ниже:Change the Text Mesh component to match the below:

    Настройка компонента сетки текста

    Совет

    Выбранный цвет имеет шестнадцатеричный цвет: 000000FF, хотя вы можете выбрать собственный, просто убедитесь, что он доступен для чтения.The selected color here is Hex color: 000000FF, though feel free to choose your own, just ensure it is readable.

  10. Теперь структура панели иерархии должна выглядеть следующим образом:Your Hierarchy Panel structure should now look like this:

    Сетка текста в иерархии

  11. Теперь сцена должна выглядеть следующим образом:Your scene should now look like this:

    Сетка текста в представлении сцены

Глава 6. Импорт хранилища Azure для UnityChapter 6 - Import Azure Storage for Unity

Вы будете использовать службу хранилища Azure для Unity (которая самостоятельно использует пакет SDK для .NET для Azure).You will be using Azure Storage for Unity (which itself leverages the .Net SDK for Azure). Дополнительные сведения об этом см. в статье хранилище Azure для Unity.You can read more about this at the Azure Storage for Unity article.

В 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.

Чтобы импортировать пакет SDK в собственный проект, убедитесь, что вы скачали последнюю версию ". пакет unitypackage" из GitHub.To import the SDK into your own project, make sure you have downloaded the latest '.unitypackage' from GitHub. Затем сделайте следующее.Then, do the following:

  1. Добавьте файл . пакет unitypackage в Unity с помощью команды Assets > Import Package > меню настраиваемый пакет импорт активов.Add the .unitypackage file to Unity by using the Assets > Import Package > Custom Package menu option.

  2. В появившемся окне Импорт пакета Unity можно выбрать все в разделе хранилище подключаемых модулей > Storage.In the Import Unity Package box that pops up, you can select everything under Plugin > Storage. Снимите флажок все остальное, так как он не требуется для этого курса.Uncheck everything else, as it is not needed for this course.

    Импорт в пакет

  3. Нажмите кнопку Импорт , чтобы добавить элементы в проект.Click the Import button to add the items to your project.

  4. Перейдите в папку хранилища подключаемых модулей в представлении проекта и выберите только следующие подключаемые модули:Go to the Storage folder under Plugins, in the Project view, and select the following plugins only:

    • Microsoft.Data.EdmMicrosoft.Data.Edm

    • Microsoft.Data.ODataMicrosoft.Data.OData

    • Microsoft.WindowsAzure.StorageMicrosoft.WindowsAzure.Storage

    • Newtonsoft.Json.Newtonsoft.Json

    • System.SpatialSystem.Spatial

      снять флажок с любой платформы

  5. Выбрав нужные подключаемые модули , снимите флажок для любой платформы и снимите флажок всаплайер , а затем нажмите кнопку Применить.With these specific plugins selected, uncheck Any Platform and uncheck WSAPlayer then click Apply.

    применение библиотек DLL платформы

    Примечание

    Мы помечаем эти отдельные подключаемые модули для использования только в редакторе Unity.We are marking these particular plugins to only be used in the Unity Editor. Это связано с тем, что в папке WSA существуют разные версии тех же подключаемых модулей, которые будут использоваться после экспорта проекта из Unity.This is because there are different versions of the same plugins in the WSA folder that will be used after the project is exported from Unity.

  6. В папке подключаемый модуль хранилища выберите только:In the Storage plugin folder, select only:

    • Microsoft.Data.Services.ClientMicrosoft.Data.Services.Client

      Set не обрабатывать библиотеки DLL

  7. Установите флажок не обрабатывать в разделе параметры платформы и нажмите кнопку Применить.Check the Don't Process box under Platform Settings and click Apply.

    не применять обработку

    Примечание

    Мы пометили этот подключаемый модуль как "не обрабатывать", так как при обработке этого подключаемого модуля в установщике сборок Unity возникли трудности.We are marking this plugin "Don't process" because the Unity assembly patcher has difficulty processing this plugin. Подключаемый модуль по-прежнему будет работать, даже если он не обрабатывается.The plugin will still work even though it is not processed.

Глава 7. Создание класса АзуресервицесChapter 7 - Create the AzureServices class

Первый класс, который предстоит создать, является классом азуресервицес .The first class you are going to create is the AzureServices class.

Класс азуресервицес будет отвечать за:The AzureServices class will be responsible for:

  • Хранение учетных данных учетной записи Azure.Storing Azure Account credentials.

  • Вызов функции приложения Azure.Calling your Azure App Function.

  • Отправка и скачивание файла данных в облачном хранилище Azure.The upload and download of the data file in your Azure Cloud Storage.

Чтобы создать этот класс, сделайте следующее:To create this Class:

  1. Щелкните правой кнопкой мыши папку Asset , расположенную на панели проект и выберите создать > папку.Right-click in the Asset Folder, located in the Project Panel, Create > Folder. Назовите папку Scripts.Name the folder Scripts.

    создать новую папку

    Папка вызова — скрипты

  2. Дважды щелкните только что созданную папку, чтобы открыть ее.Double click on the folder just created, to open it.

  3. Щелкните правой кнопкой мыши внутри папки и выберите создать > скрипт C#.Right-click inside the folder, Create > C# Script. Вызовите скрипт азуресервицес.Call the script AzureServices.

  4. Дважды щелкните новый класс азуресервицес , чтобы открыть его в Visual Studio.Double click on the new AzureServices class to open it with Visual Studio.

  5. Добавьте следующие пространства имен в верхнюю часть азуресервицес:Add the following namespaces to the top of the AzureServices:

        using System;
        using System.Threading.Tasks;
        using UnityEngine;
        using Microsoft.WindowsAzure.Storage;
        using Microsoft.WindowsAzure.Storage.File;
        using System.IO;
        using System.Net;
    
  6. Добавьте следующие поля инспектора в класс азуресервицес :Add the following Inspector Fields inside the AzureServices class:

        /// <summary>
        /// Provides Singleton-like behavior to this class.
        /// </summary>
        public static AzureServices instance;
    
        /// <summary>
        /// Reference Target for AzureStatusText Text Mesh object
        /// </summary>
        public TextMesh azureStatusText;
    
  7. Затем добавьте следующие переменные члена в класс азуресервицес :Then add the following member variables inside the AzureServices class:

        /// <summary>
        /// Holds the Azure Function endpoint - Insert your Azure Function
        /// Connection String here.
        /// </summary>
    
        private readonly string azureFunctionEndpoint = "--Insert here you AzureFunction Endpoint--";
    
        /// <summary>
        /// Holds the Storage Connection String - Insert your Azure Storage
        /// Connection String here.
        /// </summary>
        private readonly string storageConnectionString = "--Insert here you AzureStorage Connection String--";
    
        /// <summary>
        /// Name of the Cloud Share - Hosts directories.
        /// </summary>
        private const string fileShare = "fileshare";
    
        /// <summary>
        /// Name of a Directory within the Share
        /// </summary>
        private const string storageDirectory = "storagedirectory";
    
        /// <summary>
        /// The Cloud File
        /// </summary>
        private CloudFile shapeIndexCloudFile;
    
        /// <summary>
        /// The Linked Storage Account
        /// </summary>
        private CloudStorageAccount storageAccount;
    
        /// <summary>
        /// The Cloud Client
        /// </summary>
        private CloudFileClient fileClient;
    
        /// <summary>
        /// The Cloud Share - Hosts Directories
        /// </summary>
        private CloudFileShare share;
    
        /// <summary>
        /// The Directory in the share that will host the Cloud file
        /// </summary>
        private CloudFileDirectory dir;
    

    Важно!

    Убедитесь, что значения конечных точек и строк подключения заменены значениями из хранилища Azure, расположенными на портале Azure.Make sure you replace the endpoint and connection string values with the values from your Azure storage, found in the Azure Portal

  8. Теперь необходимо добавить код для методов "спящий" () и "начало" () .Code for Awake() and Start() methods now needs to be added. Эти методы будут вызываться при инициализации класса:These methods will be called when the class initializes:

        private void Awake()
        {
            instance = this;
        }
    
        // Use this for initialization
        private void Start()
        {
            // Set the Status text to loading, whilst attempting connection to Azure.
            azureStatusText.text = "Loading...";
        }
    
        /// <summary>
        /// Call to the Azure Function App to request a Shape.
        /// </summary>
        public async void CallAzureFunctionForNextShape()
        {
    
        }
    

    Важно!

    В следующей главемы будем заполнять код для каллазурефунктионфорнекстшапе () .We will fill in the code for CallAzureFunctionForNextShape() in a future Chapter.

  9. Удалите метод Update () , так как этот класс не будет его использовать.Delete the Update() method since this class will not use it.

  10. Сохраните изменения в Visual Studio, а затем вернитесь в Unity.Save your changes in Visual Studio, and then return to Unity.

  11. Щелкните и перетащите класс азуресервицес из папки Scripts в основной объект Camera на панели Иерархия.Click and drag the AzureServices class from the Scripts folder to the Main Camera object in the Hierarchy Panel.

  12. Выберите основную камеру, затем возьмите дочерний объект азурестатустекст из объекта газебуттон и поместите его в поле Целевой объект ссылки азурестатустекст в инспекторе, чтобы предоставить ссылку на скрипт азуресервицес .Select the Main Camera, then grab the AzureStatusText child object from beneath the GazeButton object, and place it within the AzureStatusText reference target field, in the Inspector, to provide the reference to the AzureServices script.

    Назначение целевой ссылки на текст состояния Azure

Глава 8. Создание класса ШапефакториChapter 8 - Create the ShapeFactory class

Следующий создаваемый скрипт является классом шапефактори .The next script to create, is the ShapeFactory class. Роль этого класса заключается в том, чтобы создать новую фигуру при запросе и удержать историю созданных фигур в списке журнала фигур.The role of this class is to create a new shape, when requested, and keep a history of the shapes created in a Shape History List. Каждый раз при создании фигуры список журнала фигур обновляется в классе AzureService , а затем сохраняется в хранилище Azure.Every time a shape is created, the Shape History list is updated in the AzureService class, and then stored in your Azure Storage. При запуске приложения, если сохраненный файл находится в хранилище Azure, список журнала фигур извлекается и воспроизводится с помощью объекта 3D Text , который указывает, является ли созданная фигура из хранилища или новой.When the application starts, if a stored file is found in your Azure Storage, the Shape History list is retrieved and replayed, with the 3D Text object providing whether the generated shape is from storage, or new.

Чтобы создать этот класс, сделайте следующее:To create this class:

  1. Перейдите к созданной ранее папке Scripts .Go to the Scripts folder you created previously.

  2. Щелкните правой кнопкой мыши внутри папки и выберите создать > скрипт C#.Right-click inside the folder, Create > C# Script. Вызовите скрипт шапефактори.Call the script ShapeFactory.

  3. Дважды щелкните новый скрипт шапефактори , чтобы открыть его в Visual Studio.Double click on the new ShapeFactory script to open it with Visual Studio.

  4. Убедитесь, что класс шапефактори содержит следующие пространства имен:Ensure the ShapeFactory class includes the following namespaces:

        using System.Collections.Generic;
        using UnityEngine;
    
  5. Добавьте указанные ниже переменные в класс шапефактори и замените функции Start () и спящие () на указанные ниже.Add the variables shown below to the ShapeFactory class, and replace the Start() and Awake() functions with those below:

        /// <summary>
        /// Provide this class Singleton-like behaviour
        /// </summary>
        [HideInInspector]
        public static ShapeFactory instance;
    
        /// <summary>
        /// Provides an Inspector exposed reference to ShapeSpawnPoint
        /// </summary>
        [SerializeField]
        public Transform spawnPoint;
    
        /// <summary>
        /// Shape History Index
        /// </summary>
        [HideInInspector]
        public List<int> shapeHistoryList;
    
        /// <summary>
        /// Shapes Enum for selecting required shape
        /// </summary>
        private enum Shapes { Cube, Sphere, Cylinder }
    
        private void Awake()
        {
            instance = this;
        }
    
        private void Start()
        {
            shapeHistoryList = new List<int>();
        }
    
  6. Метод креатешапе () создает примитивные фигуры на основе указанного целочисленного параметра.The CreateShape() method generates the primitive shapes, based upon the provided integer parameter. Логический параметр используется для указания, является ли создаваемая в данный момент фигура из хранилища или новой.The Boolean parameter is used to specify whether the currently created shape is from storage, or new. Поместите следующий код в класс шапефактори под предыдущими методами:Place the following code in your ShapeFactory class, below the previous methods:

        /// <summary>
        /// Use the Shape Enum to spawn a new Primitive object in the scene
        /// </summary>
        /// <param name="shape">Enumerator Number for Shape</param>
        /// <param name="storageShape">Provides whether this is new or old</param>
        internal void CreateShape(int shape, bool storageSpace)
        {
            Shapes primitive = (Shapes)shape;
            GameObject newObject = null;
            string shapeText = storageSpace == true ? "Storage: " : "New: ";
    
            AzureServices.instance.azureStatusText.text = string.Format("{0}{1}", shapeText, primitive.ToString());
    
            switch (primitive)
            {
                case Shapes.Cube:
                newObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
                break;
    
                case Shapes.Sphere:
                newObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                break;
    
                case Shapes.Cylinder:
                newObject = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                break;
            }
    
            if (newObject != null)
            {
                newObject.transform.position = spawnPoint.position;
    
                newObject.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
    
                newObject.AddComponent<Rigidbody>().useGravity = true;
    
                newObject.GetComponent<Renderer>().material.color = UnityEngine.Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f);
            }
        }
    
  7. Не забудьте сохранить изменения в Visual Studio перед возвратом в Unity.Be sure to save your changes in Visual Studio before returning to Unity.

  8. В редакторе Unity щелкните и перетащите класс шапефактори из папки сценарии в объект Main на панели Иерархия.Back in the Unity Editor, click and drag the ShapeFactory class from the Scripts folder to the Main Camera object in the Hierarchy Panel.

  9. Выбрав основную камеру, вы увидите, что в компоненте скрипта шапефактори отсутствует ссылка на точку порождения .With the Main Camera selected you will notice the ShapeFactory script component is missing the Spawn Point reference. Чтобы устранить эту проблему, перетащите объект шапеспавнпоинт с панели Иерархия в целевой объект ссылки на точку порождения .To fix it, drag the ShapeSpawnPoint object from the Hierarchy Panel to the Spawn Point reference target.

    задать целевую объект ссылки на фабрику фигур

Глава 9. Создание класса «взгляд»Chapter 9 - Create the Gaze class

Последний скрипт, который необходимо создать, является классом « взгляд ».The last script you need to create is the Gaze class.

Этот класс отвечает за создание райкаст , который будет проецирован вперед с основной камеры для определения объекта, на котором пользователь смотрит.This class is responsible for creating a Raycast that will be projected forward from the Main Camera, to detect which object the user is looking at. В этом случае Райкаст потребуется выяснить, просматривает ли пользователь объект газебуттон в сцене и инициирует поведение.In this case, the Raycast will need to identify if the user is looking at the GazeButton object in the scene and trigger a behavior.

Чтобы создать этот класс, сделайте следующее:To create this Class:

  1. Перейдите к созданной ранее папке Scripts .Go to the Scripts folder you created previously.

  2. Щелкните правой кнопкой мыши на панели проект и в контекстном меню выберите команду создать > скрипт C#.Right-click in the Project Panel, Create > C# Script. Вызовите скрипт взгляд.Call the script Gaze.

  3. Дважды щелкните новый скрипт " Взгляните ", чтобы открыть его в Visual Studio.Double click on the new Gaze script to open it with Visual Studio.

  4. Убедитесь, что в начале скрипта включено следующее пространство имен:Ensure the following namespace is included at the top of the script:

        using UnityEngine;
    
  5. Затем добавьте следующие переменные в класс Взгляните :Then add the following variables inside the Gaze class:

        /// <summary>
        /// Provides Singleton-like behavior to this class.
        /// </summary>
        public static Gaze instance;
    
        /// <summary>
        /// The Tag which the Gaze will use to interact with objects. Can also be set in editor.
        /// </summary>
        public string InteractibleTag = "GazeButton";
    
        /// <summary>
        /// The layer which will be detected by the Gaze ('~0' equals everything).
        /// </summary>
        public LayerMask LayerMask = ~0;
    
        /// <summary>
        /// The Max Distance the gaze should travel, if it has not hit anything.
        /// </summary>
        public float GazeMaxDistance = 300;
    
        /// <summary>
        /// The size of the cursor, which will be created.
        /// </summary>
        public Vector3 CursorSize = new Vector3(0.05f, 0.05f, 0.05f);
    
        /// <summary>
        /// The color of the cursor - can be set in editor.
        /// </summary>
        public Color CursorColour = Color.HSVToRGB(0.0223f, 0.7922f, 1.000f);
    
        /// <summary>
        /// Provides when the gaze is ready to start working (based upon whether
        /// Azure connects successfully).
        /// </summary>
        internal bool GazeEnabled = false;
    
        /// <summary>
        /// The currently focused object.
        /// </summary>
        internal GameObject FocusedObject { get; private set; }
    
        /// <summary>
        /// The object which was last focused on.
        /// </summary>
        internal GameObject _oldFocusedObject { get; private set; }
    
        /// <summary>
        /// The info taken from the last hit.
        /// </summary>
        internal RaycastHit HitInfo { get; private set; }
    
        /// <summary>
        /// The cursor object.
        /// </summary>
        internal GameObject Cursor { get; private set; }
    
        /// <summary>
        /// Provides whether the raycast has hit something.
        /// </summary>
        internal bool Hit { get; private set; }
    
        /// <summary>
        /// This will store the position which the ray last hit.
        /// </summary>
        internal Vector3 Position { get; private set; }
    
        /// <summary>
        /// This will store the normal, of the ray from its last hit.
        /// </summary>
        internal Vector3 Normal { get; private set; }
    
        /// <summary>
        /// The start point of the gaze ray cast.
        /// </summary>
        private Vector3 _gazeOrigin;
    
        /// <summary>
        /// The direction in which the gaze should be.
        /// </summary>
        private Vector3 _gazeDirection;
    

Важно!

Некоторые из этих переменных могут быть изменены в редакторе.Some of these variables will be able to be edited in the Editor.

  1. Теперь необходимо добавить код для методов спящего режима () и Start () .Code for the Awake() and Start() methods now needs to be added.

        /// <summary>
        /// The method used after initialization of the scene, though before Start().
        /// </summary>
        private void Awake()
        {
            // Set this class to behave similar to singleton
            instance = this;
        }
    
        /// <summary>
        /// Start method used upon initialization.
        /// </summary>
        private void Start()
        {
            FocusedObject = null;
            Cursor = CreateCursor();
        }
    
  2. Добавьте следующий код, который создаст объект курсора при запуске, а также метод Update () , который будет выполнять метод райкаст вместе с переключением логического газинаблед.Add the following code, which will create a cursor object at start, along with the Update() method, which will run the Raycast method, along with being where the GazeEnabled boolean is toggled:

        /// <summary>
        /// Method to create a cursor object.
        /// </summary>
        /// <returns></returns>
        private GameObject CreateCursor()
        {
            GameObject newCursor = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            newCursor.SetActive(false);
    
            // Remove the collider, so it doesn't block raycast.
            Destroy(newCursor.GetComponent<SphereCollider>());
            newCursor.transform.localScale = CursorSize;
    
            newCursor.GetComponent<MeshRenderer>().material = new Material(Shader.Find("Diffuse"))
            {
                color = CursorColour
            };
    
            newCursor.name = "Cursor";
    
            newCursor.SetActive(true);
    
            return newCursor;
        }
    
        /// <summary>
        /// Called every frame
        /// </summary>
        private void Update()
        {
            if(GazeEnabled == true)
            {
                _gazeOrigin = Camera.main.transform.position;
    
                _gazeDirection = Camera.main.transform.forward;
    
                UpdateRaycast();
            }
        }
    
  3. Затем добавьте метод упдатерайкаст () , который выполнит проецирование райкаст и определит цель попадания.Next add the UpdateRaycast() method, which will project a Raycast and detect the hit target.

        private void UpdateRaycast()
        {
            // Set the old focused gameobject.
            _oldFocusedObject = FocusedObject;
    
            RaycastHit hitInfo;
    
            // Initialise Raycasting.
            Hit = Physics.Raycast(_gazeOrigin,
                _gazeDirection,
                out hitInfo,
                GazeMaxDistance, LayerMask);
    
            HitInfo = hitInfo;
    
            // Check whether raycast has hit.
            if (Hit == true)
            {
                Position = hitInfo.point;
    
                Normal = hitInfo.normal;
    
                // Check whether the hit has a collider.
                if (hitInfo.collider != null)
                {
                    // Set the focused object with what the user just looked at.
                    FocusedObject = hitInfo.collider.gameObject;
                }
                else
                {
                    // Object looked on is not valid, set focused gameobject to null.
                    FocusedObject = null;
                }
            }
            else
            {
                // No object looked upon, set focused gameobject to null.
                FocusedObject = null;
    
                // Provide default position for cursor.
                Position = _gazeOrigin + (_gazeDirection * GazeMaxDistance);
    
                // Provide a default normal.
                Normal = _gazeDirection;
            }
    
            // Lerp the cursor to the given position, which helps to stabilize the gaze.
            Cursor.transform.position = Vector3.Lerp(Cursor.transform.position, Position, 0.6f);
    
            // Check whether the previous focused object is this same 
            //    object. If so, reset the focused object.
            if (FocusedObject != _oldFocusedObject)
            {
                ResetFocusedObject();
    
                if (FocusedObject != null)
                {
                if (FocusedObject.CompareTag(InteractibleTag.ToString()))
                {
                        // Set the Focused object to green - success!
                        FocusedObject.GetComponent<Renderer>().material.color = Color.green;
    
                        // Start the Azure Function, to provide the next shape!
                        AzureServices.instance.CallAzureFunctionForNextShape();
                    }
                }
            }
        }
    
  4. Наконец, добавьте метод ресетфокуседобжект () , который будет переключать текущий цвет объектов газебуттон, указывая, создает ли он новую фигуру.Lastly, add the ResetFocusedObject() method, which will toggle the GazeButton objects current color, indicating whether it is creating a new shape or not.

        /// <summary>
        /// Reset the old focused object, stop the gaze timer, and send data if it
        /// is greater than one.
        /// </summary>
        private void ResetFocusedObject()
        {
            // Ensure the old focused object is not null.
            if (_oldFocusedObject != null)
            {
                if (_oldFocusedObject.CompareTag(InteractibleTag.ToString()))
                {
                    // Set the old focused object to red - its original state.
                    _oldFocusedObject.GetComponent<Renderer>().material.color = Color.red;
                }
            }
        }
    
  5. Сохраните изменения в Visual Studio перед возвратом в Unity.Save your changes in Visual Studio before returning to Unity.

  6. Щелкните и Перетащите класс «указатель» из папки «скрипты» в основной объект Camera на панели «Иерархия».Click and drag the Gaze class from the Scripts folder to the Main Camera object in the Hierarchy Panel.

Глава 10. Завершение работы с классом АзуресервицесChapter 10 - Completing the AzureServices class

После выполнения других сценариев теперь можно завершить класс азуресервицес .With the other scripts in place, it is now possible to complete the AzureServices class. Это достигается с помощью следующих средств:This will be achieved through:

  1. Добавление нового метода с именем креатеклаудидентитясинк () для настройки переменных проверки подлинности, необходимых для взаимодействия с Azure.Adding a new method named CreateCloudIdentityAsync(), to set up the authentication variables needed for communicating with Azure.

    Этот метод также проверяет наличие ранее сохраненного файла, содержащего список фигур.This method will also check for the existence of a previously stored File containing the Shape List.

    Если файл найден, он отключает пользовательский взгляд и активирует создание фигур в соответствии с шаблоном фигур, сохраненным в файле хранилища Azure.If the file is found, it will disable the user Gaze, and trigger Shape creation, according to the pattern of shapes, as stored in the Azure Storage file. Пользователь может видеть это, так как в сетке текста будет отображаться "Storage" или "New" в зависимости от источника фигур.The user can see this, as the Text Mesh will provide display 'Storage' or 'New', depending on the shapes origin.

    Если файл не найден, будет включен взгляд, позволяющий пользователю создавать фигуры при просмотре объекта газебуттон в сцене.If no file is found, it will enable the Gaze, enabling the user to create shapes when looking at the GazeButton object in the scene.

        /// <summary>
        /// Create the references necessary to log into Azure
        /// </summary>
        private async void CreateCloudIdentityAsync()
        {
            // Retrieve storage account information from connection string
            storageAccount = CloudStorageAccount.Parse(storageConnectionString);
    
            // Create a file client for interacting with the file service.
            fileClient = storageAccount.CreateCloudFileClient();
    
            // Create a share for organizing files and directories within the storage account.
            share = fileClient.GetShareReference(fileShare);
    
            await share.CreateIfNotExistsAsync();
    
            // Get a reference to the root directory of the share.
            CloudFileDirectory root = share.GetRootDirectoryReference();
    
            // Create a directory under the root directory
            dir = root.GetDirectoryReference(storageDirectory);
    
            await dir.CreateIfNotExistsAsync();
    
            //Check if the there is a stored text file containing the list
            shapeIndexCloudFile = dir.GetFileReference("TextShapeFile");
    
            if (!await shapeIndexCloudFile.ExistsAsync())
            {
                // File not found, enable gaze for shapes creation
                Gaze.instance.GazeEnabled = true;
    
                azureStatusText.text = "No Shape\nFile!";
            }
            else
            {
                // The file has been found, disable gaze and get the list from the file
                Gaze.instance.GazeEnabled = false;
    
                azureStatusText.text = "Shape File\nFound!";
    
                await ReplicateListFromAzureAsync();
            }
        }
    
  2. Следующий фрагмент кода находится в методе Start () ; где выполняется вызов метода креатеклаудидентитясинк () .The next code snippet is from within the Start() method; wherein a call will be made to the CreateCloudIdentityAsync() method. Вы можете скопировать свой текущий метод Start () следующим образом:Feel free to copy over your current Start() method, with the below:

        private void Start()
        {
            // Disable TLS cert checks only while in Unity Editor (until Unity adds support for TLS)
    #if UNITY_EDITOR
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    #endif
    
            // Set the Status text to loading, whilst attempting connection to Azure.
            azureStatusText.text = "Loading...";
    
            //Creating the references necessary to log into Azure and check if the Storage Directory is empty
            CreateCloudIdentityAsync();
        }
    
  3. Заполните код метода каллазурефунктионфорнекстшапе ().Fill in the code for the method CallAzureFunctionForNextShape(). Вы будете использовать ранее созданную приложение-функция Azure для запроса индекса фигуры.You will use the previously created Azure Function App to request a shape index. После получения новой фигуры этот метод отправит форму в класс шапефактори , чтобы создать новую фигуру в сцене.Once the new shape is received, this method will send the shape to the ShapeFactory class to create the new shape in the scene. Используйте приведенный ниже код, чтобы завершить тело каллазурефунктионфорнекстшапе ().Use the code below to complete the body of CallAzureFunctionForNextShape().

        /// <summary>
        /// Call to the Azure Function App to request a Shape.
        /// </summary>
        public async void CallAzureFunctionForNextShape()
        {
            int azureRandomInt = 0;
    
            // Call Azure function
            HttpWebRequest webRequest = WebRequest.CreateHttp(azureFunctionEndpoint);
    
            WebResponse response = await webRequest.GetResponseAsync();
    
            // Read response as string
            using (Stream stream = response.GetResponseStream())
            {
                StreamReader reader = new StreamReader(stream);
    
                String responseString = reader.ReadToEnd();
    
                //parse result as integer
                Int32.TryParse(responseString, out azureRandomInt);
            }
    
            //add random int from Azure to the ShapeIndexList
            ShapeFactory.instance.shapeHistoryList.Add(azureRandomInt);
    
            ShapeFactory.instance.CreateShape(azureRandomInt, false);
    
            //Save to Azure storage
            await UploadListToAzureAsync();
        }
    
  4. Добавьте метод для создания строки путем сцепления целых чисел, хранящихся в списке журнала фигур, и сохранения их в файле хранилища Azure.Add a method to create a string, by concatenating the integers stored in the shape history list, and saving it in your Azure Storage File.

        /// <summary>
        /// Upload the locally stored List to Azure
        /// </summary>
        private async Task UploadListToAzureAsync()
        {
            // Uploading a local file to the directory created above
            string listToString = string.Join(",", ShapeFactory.instance.shapeHistoryList.ToArray());
    
            await shapeIndexCloudFile.UploadTextAsync(listToString);
        }
    
  5. Добавьте метод для получения текста, хранящегося в файле, расположенном в файле хранилища Azure , и десериализация его в список.Add a method to retrieve the text stored in the file located in your Azure Storage File and deserialize it into a list.

  6. После завершения этого процесса метод повторно включает взгляд, чтобы пользователь мог добавить дополнительные фигуры в сцену.Once this process is completed, the method re-enables the gaze so that the user can add more shapes to the scene.

        ///<summary>
        /// Get the List stored in Azure and use the data retrieved to replicate 
        /// a Shape creation pattern
        ///</summary>
        private async Task ReplicateListFromAzureAsync()
        {
            string azureTextFileContent = await shapeIndexCloudFile.DownloadTextAsync();
    
            string[] shapes = azureTextFileContent.Split(new char[] { ',' });
    
            foreach (string shape in shapes)
            {
                int i;
    
                Int32.TryParse(shape.ToString(), out i);
    
                ShapeFactory.instance.shapeHistoryList.Add(i);
    
                ShapeFactory.instance.CreateShape(i, true);
    
                await Task.Delay(500);
            }
    
            Gaze.instance.GazeEnabled = true;
    
            azureStatusText.text = "Load Complete!";
        }
    
  7. Сохраните изменения в Visual Studio перед возвратом в Unity.Save your changes in Visual Studio before returning to Unity.

Глава 11. Создание решения UWPChapter 11 - Build the UWP Solution

Чтобы начать процесс сборки:To begin the Build process:

  1. Перейдите в File раздел > параметры сборки файлов.Go to File > Build Settings.

    сборка приложения

  2. Щелкните Построить.Click Build. Unity запустит окно проводника , в котором необходимо создать, а затем выбрать папку для сборки приложения.Unity will launch a File Explorer window, where you need to create and then select a folder to build the app into. Создайте эту папку сейчас и назовите ее app Name.Create that folder now, and name it App. Затем выберите папку приложения и нажмите кнопку выбрать папку.Then with the App folder selected, press Select Folder.

  3. Unity начнет сборку проекта в папку приложения .Unity will begin building your project to the App folder.

  4. После того как Unity завершит сборку (может занять некоторое время), он откроет окно проводника в расположении сборки (проверьте панель задач, так как она может не всегда отображаться над окнами, но будет уведомлять о добавлении нового окна).Once Unity has finished building (it might take some time), it will open a File Explorer window at the location of your build (check your task bar, as it may not always appear above your windows, but will notify you of the addition of a new window).

Глава 12. Развертывание приложенияChapter 12 - Deploying your application

Чтобы развернуть приложение, выполните следующие действия.To deploy your application:

  1. Перейдите к папке приложения , созданной в последней главе.Navigate to the App folder which was created in the last Chapter. Вы увидите файл с именем приложения с расширением SLN, который следует дважды щелкнуть, чтобы открыть его в Visual Studio.You will see a file with your apps name, with the '.sln' extension, which you should double-click, so to open it within Visual Studio.

  2. На платформе решения выберите x86, локальный компьютер.In the Solution Platform, select x86, Local Machine.

  3. В конфигурации решения выберите Отладка.In the Solution Configuration select Debug.

    Для Microsoft HoloLens может быть проще установить этот параметр на Удаленный компьютер, чтобы вы не были подключены к компьютеру.For the Microsoft HoloLens, you may find it easier to set this to Remote Machine, so that you are not tethered to your computer. Однако необходимо также выполнить следующие действия.Though, you will need to also do the following:

    • Изучите IP-адрес HoloLens, который можно найти в параметрах > Network & reinternet > Wi-Fi > Advanced reoptions; IPv4 — это адрес, который следует использовать.Know the IP Address of your HoloLens, which can be found within the Settings > Network & Internet > Wi-Fi > Advanced Options; the IPv4 is the address you should use.
    • Убедитесь, что включен режим разработчика ; Найдено в параметрах > Update & Security > для разработчиков.Ensure Developer Mode is On; found in Settings > Update & Security > For developers.

    развертывание решения

  4. Перейдите в меню " Сборка " и щелкните " Развернуть решение ", чтобы загружать неопубликованные приложение на компьютере.Go to the 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 and tested!

Готовые функции Azure и приложение для хранения данныхYour finished Azure Functions and Storage Application

Поздравляем, вы создали приложение смешанной реальности, которое использует функции Azure и службы хранилища Azure.Congratulations, you built a mixed reality app that leverages both the Azure Functions and Azure Storage services. Приложение сможет рисовать на сохраненных данных и предоставить действие на основе этих данных.Your app will be able to draw on stored data, and provide an action based on that data.

окончательный конец продукта

Дополнительные упражненияBonus exercises

Упражнение 1Exercise 1

Создайте вторую точку порождения и запишите, из какой порожденной точки был создан объект.Create a second spawn point and record which spawn point an object was created from. При загрузке файла данных воспроизводите созданные фигуры из первоначально созданного расположения.When you load the data file, replay the shapes being spawned from the location they originally were created.

Упражнение 2Exercise 2

Создайте способ перезапуска приложения, вместо того чтобы повторно открывать его каждый раз.Create a way to restart the app, rather than having to re-open it each time. Загрузка сцен — хорошее место для начала.Loading Scenes is a good spot to start. После этого создайте способ очистки сохраненного списка в службе хранилища Azure, чтобы его можно было легко сбросить из приложения.After doing that, create a way to clear the stored list in Azure Storage, so that it can be easily reset from your app.