Freigeben über


HoloLens (1. Generation) und Azure 311: Microsoft Graph

Hinweis

Die Tutorials der Mixed Reality Academy wurden im Hinblick auf HoloLens (1. Gen.) und immersive Mixed Reality-Headsets entworfen. Daher halten wir es für wichtig, diese Tutorials für Entwickler verfügbar zu halten, die noch nach Anleitung beim Entwickeln für diese Geräte suchen. Diese Tutorials werden nicht mit den neuesten Toolsets oder Interaktionen aktualisiert, die für HoloLens 2 verwendet werden. Sie werden gewartet, um weiterhin auf den unterstützten Geräten zu funktionieren. Es wird eine neue Reihe von Lernprogrammen geben, die in Zukunft veröffentlicht werden, die zeigen, wie sie für HoloLens 2 entwickelt werden. Dieser Hinweis wird mit einem Link zu diesen Lernprogrammen aktualisiert, wenn sie veröffentlicht werden.

In diesem Kurs erfahren Sie, wie Sie sich mit Microsoft Graph bei Ihrem Microsoft-Konto mit sicherer Authentifizierung in einer Mixed Reality-Anwendung anmelden. Anschließend rufen Sie Ihre geplanten Besprechungen auf der Anwendungsoberfläche ab und zeigen sie an.

Screenshot der geplanten Besprechungen in der Anwendungsoberfläche.

Microsoft Graph ist eine Reihe von APIs, die den Zugriff auf viele microsoft-Dienste ermöglichen. Microsoft beschreibt Microsoft Graph als eine Matrix von Ressourcen, die durch Beziehungen verbunden sind, was bedeutet, dass eine Anwendung auf alle Arten verbundener Benutzerdaten zugreifen kann. Weitere Informationen finden Sie auf der Microsoft Graph-Seite.

Die Entwicklung umfasst die Erstellung einer App, in der der Benutzer angewiesen wird, sich zu betrachten und dann auf eine Kugel zu tippen, die den Benutzer auffordert, sich sicher bei einem Microsoft-Konto anzumelden. Sobald Sie sich bei ihrem Konto angemeldet haben, kann der Benutzer eine Liste der für den Tag geplanten Besprechungen anzeigen.

Nachdem Sie diesen Kurs abgeschlossen haben, haben Sie eine Mixed Reality HoloLens-Anwendung, die folgende Aktionen ausführen kann:

  1. Tippen Sie mit der Tippbewegung auf ein Objekt, das den Benutzer auffordert, sich bei einem Microsoft-Konto anzumelden (aus der App heraus, um sich anzumelden, und dann wieder in die App).
  2. Zeigen Sie eine Liste der für den Tag geplanten Besprechungen an.

In Ihrer Anwendung liegt es an Ihnen, wie Sie die Ergebnisse in Ihr Design integrieren. Dieser Kurs soll Ihnen vermitteln, wie Sie einen Azure Service in Ihr Unity-Projekt integrieren. Es ist Ihre Aufgabe, das Wissen zu nutzen, das Sie aus diesem Kurs gewinnen, um Ihre Mixed Reality-Anwendung zu verbessern.

Unterstützung für Geräte

Kurs HoloLens Immersive Headsets
MR und Azure 311: Microsoft Graph ✔️

Voraussetzungen

Hinweis

Dieses Lernprogramm wurde für Entwickler entwickelt, die grundlegende Erfahrung mit Unity und C# haben. Bitte beachten Sie auch, dass die Voraussetzungen und schriftlichen Anweisungen in diesem Dokument darstellen, was zum Zeitpunkt der Schriftlichkeit (Juli 2018) getestet und überprüft wurde. Sie können die neueste Software verwenden, wie im Artikel "Tools installieren" aufgeführt, aber es sollte nicht davon ausgegangen werden, dass die Informationen in diesem Kurs perfekt mit dem übereinstimmen, was Sie in neuerer Software finden werden als die unten aufgeführten.

Wir empfehlen die folgende Hardware und Software für diesen Kurs:

Vor der Installation

  1. Um Probleme beim Erstellen dieses Projekts zu vermeiden, wird dringend empfohlen, das in diesem Lernprogramm erwähnte Projekt in einem Stamm- oder Near-Root-Ordner zu erstellen (lange Ordnerpfade können zu Buildzeit zu Problemen führen).
  2. Richten Sie Ihre HoloLens ein, und testen Sie sie. Wenn Sie Unterstützung beim Einrichten Ihrer HoloLens benötigen, besuchen Sie den HoloLens-Setupartikel.
  3. Es empfiehlt sich, beim Entwickeln einer neuen HoloLens-App Kalibrierung und Sensoroptimierung durchzuführen (manchmal kann es hilfreich sein, diese Aufgaben für jeden Benutzer auszuführen).

Hilfe zur Kalibrierung finden Sie unter diesem Link zum HoloLens-Kalibrierungsartikel.

Hilfe zur Sensoroptimierung finden Sie in diesem Link zum Artikel "HoloLens Sensor Tuning".

Kapitel 1 – Erstellen Ihrer App im Anwendungsregistrierungsportal

Zunächst müssen Sie Ihre Anwendung im Anwendungsregistrierungsportal erstellen und registrieren.

In diesem Kapitel finden Sie auch den Dienstschlüssel, mit dem Sie Anrufe an Microsoft Graph tätigen können, um auf Ihre Kontoinhalte zuzugreifen.

  1. Navigieren Sie zum Microsoft-Anwendungsregistrierungsportal , und melden Sie sich mit Ihrem Microsoft-Konto an. Nachdem Sie sich angemeldet haben, werden Sie zum Anwendungsregistrierungsportal umgeleitet.

  2. Klicken Sie im Abschnitt "Meine Anwendungen " auf die Schaltfläche " App hinzufügen".

    Screenshot, der zeigt, wo Eine App hinzugefügt werden soll.

    Wichtig

    Das Anwendungsregistrierungsportal kann je nachdem, ob Sie zuvor mit Microsoft Graph gearbeitet haben, unterschiedlich aussehen. Die folgenden Screenshots zeigen diese verschiedenen Versionen an.

  3. Fügen Sie einen Namen für Ihre Anwendung hinzu, und klicken Sie auf " Erstellen".

    Screenshot, der zeigt, wo Ein name für Ihre Anwendung hinzugefügt werden soll.

  4. Nachdem die Anwendung erstellt wurde, werden Sie zur Hauptseite der Anwendung umgeleitet. Kopieren Sie die Anwendungs-ID , und achten Sie darauf, diesen Wert an einem sicheren Ort zu notieren. Sie werden ihn in Kürze in Ihrem Code verwenden.

    Screenshot, der zeigt, wo die Anwendungs-ID angezeigt werden soll.

  5. Stellen Sie im Abschnitt "Plattformen " sicher, dass native Anwendung angezeigt wird. Wenn Sie nicht auf "Plattform hinzufügen" klicken und "Native Anwendung" auswählen.

    Screenshot, der den Abschnitt

  6. Scrollen Sie auf derselben Seite nach unten, und fügen Sie im Abschnitt "Microsoft Graph-Berechtigungen" zusätzliche Berechtigungen für die Anwendung hinzu. Klicken Sie auf "Hinzufügen" neben delegierten Berechtigungen.

    Screenshot, der zeigt, wo Neben delegierten Berechtigungen

  7. Da Ihre Anwendung auf den Kalender des Benutzers zugreifen soll, aktivieren Sie das Kontrollkästchen "Calendars.Read ", und klicken Sie auf " OK".

    Screenshot des Kontrollkästchens

  8. Scrollen Sie nach unten, und klicken Sie auf die Schaltfläche "Speichern ".

    Screenshot, der zeigt, wo

  9. Ihr Speicher wird bestätigt, und Sie können sich vom Anwendungsregistrierungsportal abmelden.

Kapitel 2 – Einrichten des Unity-Projekts

Im Folgenden sehen Sie eine typische Einrichtung für die Entwicklung mit Mixed Reality und ist daher eine gute Vorlage für andere Projekte.

  1. Öffnen Sie Unity , und klicken Sie auf "Neu".

    Screenshot der Unity-Schnittstelle.

  2. Sie müssen einen Unity-Projektnamen angeben. Fügen Sie MSGraphMR ein. Stellen Sie sicher, dass die Projektvorlage auf 3D festgelegt ist. Legen Sie den Speicherort an einer für Sie geeigneten Stelle fest (denken Sie daran, dass die Stammverzeichnisse besser sind). Klicken Sie dann auf "Projekt erstellen".

    Screenshot, der zeigt, wo Sie

  3. Wenn Unity geöffnet ist, lohnt es sich, den Standardmäßigen Skript-Editor auf Visual Studio festzulegen. Wechseln Sie zu "Einstellungen bearbeiten>", und navigieren Sie dann im neuen Fenster zu "Externe Tools". Ändern Sie den externen Skript-Editor in Visual Studio 2017. Schließen Sie das Fenster Einstellungen.

    Screenshot, der zeigt, wo der Externe Skript-Editor auf Visual Studio 2017 festgelegt werden soll.

  4. Wechseln Sie zu "Dateibuildeinstellungen>", und wählen Sie Universelle Windows-Plattform aus, und klicken Sie dann auf die Schaltfläche "Plattform wechseln", um Ihre Auswahl anzuwenden.

    Screenshot, der zeigt, wo

  5. Stellen Sie sicher>, dass:

    1. Zielgerät ist auf HoloLens festgelegt

    2. Buildtyp ist auf D3D festgelegt

    3. SDK ist auf "Neueste Installation" festgelegt.

    4. Visual Studio-Version ist auf "Neueste Installation" festgelegt.

    5. Build und Ausführung ist auf den lokalen Computer festgelegt.

    6. Speichern Sie die Szene, und fügen Sie sie dem Build hinzu.

      1. Wählen Sie dazu "Offene Szenen hinzufügen" aus. Ein Speicherfenster wird angezeigt.

        Screenshot, der zeigt, wo Sie

      2. Erstellen Sie einen neuen Ordner für diese und jede zukünftige Szene. Wählen Sie die Schaltfläche "Neuer Ordner " aus, um einen neuen Ordner zu erstellen, nennen Sie ihn "Szenen".

        Screenshot, der zeigt, wo der neue Ordner angegeben werden soll.

      3. Öffnen Sie den neu erstellten Ordner "Szenen", und klicken Sie dann im Feld "Dateiname": "Textfeld", geben Sie MR_ComputerVisionScene ein, und klicken Sie dann auf "Speichern".

        Screenshot, der zeigt, wo der Dateiname eingegeben werden soll.

        Wichtig

        Beachten Sie, dass Sie Ihre Unity-Szenen im Ordner "Assets " speichern müssen, da sie dem Unity-Projekt zugeordnet sein müssen. Das Erstellen des Szenenordners (und andere ähnliche Ordner) ist eine typische Methode zum Strukturieren eines Unity-Projekts.

    7. Die übrigen Einstellungen in den Buildeinstellungen sollten jetzt als Standard beibehalten werden.

  6. Klicken Sie im Fenster "Buildeinstellungen " auf die Schaltfläche "Spielereinstellungen ". Dadurch wird der zugehörige Bereich im Bereich geöffnet, in dem sich der Inspektor befindet.

    Screenshot des Dialogfelds

  7. In diesem Bereich müssen einige Einstellungen überprüft werden:

    1. Auf der Registerkarte "Andere Einstellungen" folgendes:

      1. Skripting Runtime Version sollte Experimental (.NET 4.6 Equivalent) sein, wodurch ein Neustart des Editors ausgelöst wird.

      2. Scripting Back-End sollte .NET sein

      3. API-Kompatibilitätsstufe sollte .NET 4.6 sein

        Screenshot, der zeigt, wo die API-Kompatibilitätsstufe überprüft werden soll.

    2. Aktivieren Sie auf der Registerkarte "Veröffentlichungseinstellungen " unter "Funktionen" Folgendes:

      • InternetClient

        Screenshot, der zeigt, wo die InternetClient-Option ausgewählt werden soll.

    3. Überprüfen Sie weiter unten im Bereich unter "XR-Einstellungen" (unter "Veröffentlichungseinstellungen" die Option "Virtual Reality Unterstützt", vergewissern Sie sich, dass das Windows Mixed Reality SDK hinzugefügt wurde.

      Screenshot, der zeigt, wo Windows Mixed Reality SDK hinzugefügt werden soll.

  8. Zurück in build settings, Unity C# Projects is no longer greyed out; check the checkbox next to this.

  9. Schließen Sie das Fenster Buildeinstellungen.

  10. Speichern Sie Ihre Szene und Ihr Projekt (FILE>SAVE SCENES / FILE>SAVE PROJECT).

Kapitel 3 – Importieren von Bibliotheken in Unity

Wichtig

Wenn Sie die Unity Set up-Komponente dieses Kurses überspringen und direkt mit Code fortfahren möchten, können Sie dieses Azure-MR-311.unitypackage herunterladen, es als benutzerdefiniertes Paket in Ihr Projekt importieren und dann mit Kapitel 5 fortfahren.

Um Microsoft Graph in Unity zu verwenden, müssen Sie die Microsoft.Identity.Client-DLL verwenden. Es ist jedoch möglich, das Microsoft Graph SDK zu verwenden, es erfordert jedoch das Hinzufügen eines NuGet-Pakets, nachdem Sie das Unity-Projekt erstellt haben (d. h. das Bearbeiten des Projekts nach dem Build). Es wird als einfacher angesehen, die erforderlichen DLLs direkt in Unity zu importieren.

Hinweis

Es gibt derzeit ein bekanntes Problem in Unity, das erfordert, dass Plug-Ins nach dem Import neu konfiguriert werden. Diese Schritte (4 - 7 in diesem Abschnitt) sind nach der Behebung des Fehlers nicht mehr erforderlich.

Um Microsoft Graph in Ihr eigenes Projekt zu importieren, laden Sie die MSGraph_LabPlugins.zip Datei herunter. Dieses Paket wurde mit Versionen der Bibliotheken erstellt, die getestet wurden.

Wenn Sie mehr darüber erfahren möchten, wie Sie Ihrem Unity-Projekt benutzerdefinierte DLLs hinzufügen können, folgen Sie diesem Link.

So importieren Sie das Paket:

  1. Fügen Sie das Unity-Paket zu Unity hinzu, indem Sie die Menüoption "Paketimportpaket>>importieren" verwenden. Wählen Sie das Paket aus, das Sie gerade heruntergeladen haben.

  2. Stellen Sie im Popupfeld "Unity-Paket importieren" sicher, dass alles unter (und einschließlich) Plug-Ins ausgewählt ist.

    Screenshot der ausgewählten Konfigurationsparameter unter Plugins.

  3. Klicken Sie auf die Schaltfläche "Importieren ", um dem Projekt die Elemente hinzuzufügen.

  4. Wechseln Sie im Projektbereich zu dem Ordner "MSGraph" unter "Plugins", und wählen Sie das Plug-In "Microsoft.Identity.Client" aus.

    Screenshot des Microsoft.Identity.Client-Plug-Ins.

  5. Stellen Sie bei ausgewähltem Plug-In sicher, dass "Beliebige Plattform" deaktiviert ist, und stellen Sie sicher, dass WSAPlayer ebenfalls deaktiviert ist, und klicken Sie dann auf "Übernehmen". Dies ist nur zu bestätigen, dass die Dateien ordnungsgemäß konfiguriert sind.

    Screenshot, der zeigt, wo bestätigt werden soll, dass

    Hinweis

    Wenn Sie diese Plug-Ins markieren, werden sie nur im Unity-Editor verwendet. Es gibt einen anderen Satz von DLLs im WSA-Ordner, der verwendet wird, nachdem das Projekt aus Unity als universelle Windows-Anwendung exportiert wurde.

  6. Als Nächstes müssen Sie den WSA-Ordner innerhalb des MSGraph-Ordners öffnen. Es wird eine Kopie derselben Datei angezeigt, die Sie gerade konfiguriert haben. Wählen Sie die Datei und dann im Inspektor aus:

    • Stellen Sie sicher, dass "Beliebige Plattform" deaktiviert ist und nur WSAPlayer aktiviert ist.

    • Stellen Sie sicher, dass das SDK auf UWP festgelegt ist und das Skripting-Back-End auf Dot Net festgelegt ist.

    • Stellen Sie sicher, dass "Nicht verarbeiten" aktiviert ist.

      Screenshot, der zeigt, dass

  7. Klicken Sie auf Anwenden.

Kapitel 4 – Kameraeinrichtung

In diesem Kapitel richten Sie die Hauptkamera Ihrer Szene ein:

  1. Wählen Sie im Hierarchiebereich die Hauptkamera aus.

  2. Nach der Auswahl können Sie alle Komponenten der Hauptkamera im Inspektorbereich anzeigen.

    1. Das Camera-Objekt muss die Hauptkamera genannt werden (beachten Sie die Schreibweise!)

    2. Das Hauptkameratag muss auf "MainCamera" festgelegt werden (beachten Sie die Schreibweise!)

    3. Stellen Sie sicher, dass die Transformationsposition auf 0, 0, 0 festgelegt ist.

    4. Festlegen von Clear Flags auf Volltonfarbe

    5. Festlegen der Hintergrundfarbe der Kamerakomponente auf Schwarz, Alpha 0 (Hex-Code: #00000000)

      Screenshot, der hervorhebung, wo die Hintergrundfarbe festgelegt werden soll.

  3. Die endgültige Objektstruktur im Hierarchiebereich sollte wie in der abbildung unten dargestellten sein:

    Screenshot der endgültigen Objektstruktur im Hierarchiebereich.

Kapitel 5 – Erstellen einer MeetingsUI-Klasse

Das erste Skript, das Sie erstellen müssen, ist MeetingsUI, das für das Hosten und Auffüllen der Benutzeroberfläche der Anwendung (Willkommensnachricht, Anweisungen und Besprechungsdetails) verantwortlich ist.

So erstellen Sie diese Klasse:

  1. Klicken Sie im Projektbereich mit der rechten Maustaste auf den Ordner "Objekte", und wählen Sie dann "Ordner erstellen>" aus. Benennen Sie den Ordner Skripts.

    Screenshot, der zeigt, wo der Ordner Screenshot, der zeigt, wo der Ordner

  2. Öffnen Sie den Ordner "Skripts", und klicken Sie dann in diesem Ordner mit der rechten Maustaste auf "C#-Skript erstellen>". Benennen Sie das Skript "MeetingsUI".

    Screenshot, der zeigt, wo der Ordner

  3. Doppelklicken Sie auf das neue MeetingsUI-Skript , um es mit Visual Studio zu öffnen.

  4. Fügen Sie die folgenden Namespaces ein:

    using System;
    using UnityEngine;
    
  5. Fügen Sie in der Klasse die folgenden Variablen ein:

        /// <summary>
        /// Allows this class to behave like a singleton
        /// </summary>
        public static MeetingsUI Instance;
    
        /// <summary>
        /// The 3D text of the scene
        /// </summary>
        private TextMesh _meetingDisplayTextMesh;
    
  6. Ersetzen Sie dann die Start() -Methode, und fügen Sie eine Awake()- Methode hinzu. Diese werden aufgerufen, wenn die Klasse initialisiert wird:

        /// <summary>
        /// Called on initialization
        /// </summary>
        void Awake()
        {
            Instance = this;
        }
    
        /// <summary>
        /// Called on initialization, after Awake
        /// </summary>
        void Start ()
        {
            // Creating the text mesh within the scene
            _meetingDisplayTextMesh = CreateMeetingsDisplay();
        }
    
  7. Fügen Sie die Methoden hinzu, die für das Erstellen der Besprechungsbenutzeroberfläche verantwortlich sind, und füllen Sie sie bei Bedarf mit den aktuellen Besprechungen auf:

        /// <summary>
        /// Set the welcome message for the user
        /// </summary>
        internal void WelcomeUser(string userName)
        {
            if(!string.IsNullOrEmpty(userName))
            {
                _meetingDisplayTextMesh.text = $"Welcome {userName}";
            }
            else 
            {
                _meetingDisplayTextMesh.text = "Welcome";
            }
        }
    
        /// <summary>
        /// Set up the parameters for the UI text
        /// </summary>
        /// <returns>Returns the 3D text in the scene</returns>
        private TextMesh CreateMeetingsDisplay()
        {
            GameObject display = new GameObject();
            display.transform.localScale = new Vector3(0.03f, 0.03f, 0.03f);
            display.transform.position = new Vector3(-3.5f, 2f, 9f);
            TextMesh textMesh = display.AddComponent<TextMesh>();
            textMesh.anchor = TextAnchor.MiddleLeft;
            textMesh.alignment = TextAlignment.Left;
            textMesh.fontSize = 80;
            textMesh.text = "Welcome! \nPlease gaze at the button" +
                "\nand use the Tap Gesture to display your meetings";
    
            return textMesh;
        }
    
        /// <summary>
        /// Adds a new Meeting in the UI by chaining the existing UI text
        /// </summary>
        internal void AddMeeting(string subject, DateTime dateTime, string location)
        {
            string newText = $"\n{_meetingDisplayTextMesh.text}\n\n Meeting,\nSubject: {subject},\nToday at {dateTime},\nLocation: {location}";
    
            _meetingDisplayTextMesh.text = newText;
        }
    
  8. Löschen Sie die Update()- Methode, und speichern Sie Ihre Änderungen in Visual Studio, bevor Sie zu Unity zurückkehren.

Kapitel 6 – Erstellen der Graph-Klasse

Das nächste zu erstellende Skript ist das Graph-Skript . Dieses Skript ist dafür verantwortlich, die Anrufe zum Authentifizieren des Benutzers durchzuführen und die geplanten Besprechungen für den aktuellen Tag aus dem Kalender des Benutzers abzurufen.

So erstellen Sie diese Klasse:

  1. Doppelklicken Sie auf den Ordner "Skripts ", um ihn zu öffnen.

  2. Klicken Sie mit der rechten Maustaste in den Ordner "Skripts", und klicken Sie auf "C#-Skript erstellen>". Nennen Sie das Skript Graph.

  3. Doppelklicken Sie auf das Skript, um es mit Visual Studio zu öffnen.

  4. Fügen Sie die folgenden Namespaces ein:

    using System.Collections.Generic;
    using UnityEngine;
    using Microsoft.Identity.Client;
    using System;
    using System.Threading.Tasks;
    
    #if !UNITY_EDITOR && UNITY_WSA
    using System.Net.Http;
    using System.Net.Http.Headers;
    using Windows.Storage;
    #endif
    

    Wichtig

    Sie werden feststellen, dass Teile des Codes in diesem Skript um Präkompilierungsdirektiven umschlossen werden, um Probleme mit den Bibliotheken beim Erstellen der Visual Studio-Lösung zu vermeiden.

  5. Löschen Sie die Methoden Start() und Update(), da sie nicht verwendet werden.

  6. Fügen Sie außerhalb der Graph-Klasse die folgenden Objekte ein, die zum Deserialisieren des JSON-Objekts erforderlich sind, das die täglich geplanten Besprechungen darstellt:

    /// <summary>
    /// The object hosting the scheduled meetings
    /// </summary>
    [Serializable]
    public class Rootobject
    {
        public List<Value> value;
    }
    
    [Serializable]
    public class Value
    {
        public string subject { get; set; }
        public StartTime start { get; set; }
        public Location location { get; set; }
    }
    
    [Serializable]
    public class StartTime
    {
        public string dateTime;
    
        private DateTime? _startDateTime;
        public DateTime StartDateTime
        {
            get
            {
                if (_startDateTime != null)
                    return _startDateTime.Value;
                DateTime dt;
                DateTime.TryParse(dateTime, out dt);
                _startDateTime = dt;
                return _startDateTime.Value;
            }
        }
    }
    
    [Serializable]
    public class Location
    {
        public string displayName { get; set; }
    }
    
  7. Fügen Sie in der Graph-Klasse die folgenden Variablen hinzu:

        /// <summary>
        /// Insert your Application Id here
        /// </summary>
        private string _appId = "-- Insert your Application Id here --";
    
        /// <summary>
        /// Application scopes, determine Microsoft Graph accessibility level to user account
        /// </summary>
        private IEnumerable<string> _scopes = new List<string>() { "User.Read", "Calendars.Read" };
    
        /// <summary>
        /// Microsoft Graph API, user reference
        /// </summary>
        private PublicClientApplication _client;
    
        /// <summary>
        /// Microsoft Graph API, authentication
        /// </summary>
        private AuthenticationResult _authResult;
    
    

    Hinweis

    Ändern Sie den AppId-Wert in die App-ID, die Sie in Kapitel 1, Schritt 4 angegeben haben. Dieser Wert sollte mit dem wert übereinstimmen, der im Anwendungsregistrierungsportal in Ihrer Anwendungsregistrierungsseite angezeigt wird.

  8. Fügen Sie in der Graph-Klasse die Methoden SignInAsync() und AquireTokenAsync(), die den Benutzer auffordern, die Anmeldeinformationen für die Anmeldung einzufügen.

        /// <summary>
        /// Begin the Sign In process using Microsoft Graph Library
        /// </summary>
        internal async void SignInAsync()
        {
    #if !UNITY_EDITOR && UNITY_WSA
            // Set up Grap user settings, determine if needs auth
            ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
            string userId = localSettings.Values["UserId"] as string;
            _client = new PublicClientApplication(_appId);
    
            // Attempt authentication
            _authResult = await AcquireTokenAsync(_client, _scopes, userId);
    
            // If authentication is successful, retrieve the meetings
            if (!string.IsNullOrEmpty(_authResult.AccessToken))
            {
                // Once Auth as been completed, find the meetings for the day
                await ListMeetingsAsync(_authResult.AccessToken);
            }
    #endif
        }
    
        /// <summary>
        /// Attempt to retrieve the Access Token by either retrieving
        /// previously stored credentials or by prompting user to Login
        /// </summary>
        private async Task<AuthenticationResult> AcquireTokenAsync(
            IPublicClientApplication app, IEnumerable<string> scopes, string userId)
        {
            IUser user = !string.IsNullOrEmpty(userId) ? app.GetUser(userId) : null;
            string userName = user != null ? user.Name : "null";
    
            // Once the User name is found, display it as a welcome message
            MeetingsUI.Instance.WelcomeUser(userName);
    
            // Attempt to Log In the user with a pre-stored token. Only happens
            // in case the user Logged In with this app on this device previously
            try
            {
                _authResult = await app.AcquireTokenSilentAsync(scopes, user);
            }
            catch (MsalUiRequiredException)
            {
                // Pre-stored token not found, prompt the user to log-in 
                try
                {
                    _authResult = await app.AcquireTokenAsync(scopes);
                }
                catch (MsalException msalex)
                {
                    Debug.Log($"Error Acquiring Token: {msalex.Message}");
                    return _authResult;
                }
            }
    
            MeetingsUI.Instance.WelcomeUser(_authResult.User.Name);
    
    #if !UNITY_EDITOR && UNITY_WSA
            ApplicationData.Current.LocalSettings.Values["UserId"] = 
            _authResult.User.Identifier;
    #endif
            return _authResult;
        }
    
  9. Fügen Sie die folgenden beiden Methoden hinzu:

    1. BuildTodayCalendarEndpoint(), der den URI erstellt, der den Tag und die Zeitspanne angibt, in der die geplanten Besprechungen abgerufen werden.

    2. ListMeetingsAsync(), das die geplanten Besprechungen von Microsoft Graph anfordert.

        /// <summary>
        /// Build the endpoint to retrieve the meetings for the current day.
        /// </summary>
        /// <returns>Returns the Calendar Endpoint</returns>
        public string BuildTodayCalendarEndpoint()
        {
            DateTime startOfTheDay = DateTime.Today.AddDays(0);
            DateTime endOfTheDay = DateTime.Today.AddDays(1);
            DateTime startOfTheDayUTC = startOfTheDay.ToUniversalTime();
            DateTime endOfTheDayUTC = endOfTheDay.ToUniversalTime();
    
            string todayDate = startOfTheDayUTC.ToString("o");
            string tomorrowDate = endOfTheDayUTC.ToString("o");
            string todayCalendarEndpoint = string.Format(
                "https://graph.microsoft.com/v1.0/me/calendarview?startdatetime={0}&enddatetime={1}",
                todayDate,
                tomorrowDate);
    
            return todayCalendarEndpoint;
        }
    
        /// <summary>
        /// Request all the scheduled meetings for the current day.
        /// </summary>
        private async Task ListMeetingsAsync(string accessToken)
        {
    #if !UNITY_EDITOR && UNITY_WSA
            var http = new HttpClient();
    
            http.DefaultRequestHeaders.Authorization = 
            new AuthenticationHeaderValue("Bearer", accessToken);
            var response = await http.GetAsync(BuildTodayCalendarEndpoint());
    
            var jsonResponse = await response.Content.ReadAsStringAsync();
    
            Rootobject rootObject = new Rootobject();
            try
            {
                // Parse the JSON response.
                rootObject = JsonUtility.FromJson<Rootobject>(jsonResponse);
    
                // Sort the meeting list by starting time.
                rootObject.value.Sort((x, y) => DateTime.Compare(x.start.StartDateTime, y.start.StartDateTime));
    
                // Populate the UI with the meetings.
                for (int i = 0; i < rootObject.value.Count; i++)
                {
                    MeetingsUI.Instance.AddMeeting(rootObject.value[i].subject,
                                                rootObject.value[i].start.StartDateTime.ToLocalTime(),
                                                rootObject.value[i].location.displayName);
                }
            }
            catch (Exception ex)
            {
                Debug.Log($"Error = {ex.Message}");
                return;
            }
    #endif
        }
    
  10. Sie haben nun das Graph-Skript abgeschlossen. Speichern Sie Ihre Änderungen in Visual Studio, bevor Sie zu Unity zurückkehren.

Kapitel 7 – Erstellen des GazeInput-Skripts

Jetzt erstellen Sie " GazeInput". Diese Klasse behandelt und verfolgt den Blick des Benutzers unter Verwendung eines Raycasts , der von der Hauptkamera stammt, und zeichnet sich vorwärts aus.

So erstellen Sie das Skript:

  1. Doppelklicken Sie auf den Ordner "Skripts ", um ihn zu öffnen.

  2. Klicken Sie mit der rechten Maustaste in den Ordner "Skripts", und klicken Sie auf "C#-Skript erstellen>". Nennen Sie das Skript GazeInput.

  3. Doppelklicken Sie auf das Skript, um es mit Visual Studio zu öffnen.

  4. Ändern Sie den Namespacescode so, dass er dem folgenden Code entspricht, und fügen Sie das Tag "[System.Serializable]" oberhalb der GazeInput-Klasse hinzu, damit sie serialisiert werden kann:

    using UnityEngine;
    
    /// <summary>
    /// Class responsible for the User's Gaze interactions
    /// </summary>
    [System.Serializable]
    public class GazeInput : MonoBehaviour
    {
    
  5. Fügen Sie innerhalb der GazeInput-Klasse die folgenden Variablen hinzu:

        [Tooltip("Used to compare whether an object is to be interacted with.")]
        internal string InteractibleTag = "SignInButton";
    
        /// <summary>
        /// Length of the gaze
        /// </summary>
        internal float GazeMaxDistance = 300;
    
        /// <summary>
        /// Object currently gazed
        /// </summary>
        internal GameObject FocusedObject { get; private set; }
    
        internal GameObject oldFocusedObject { get; private set; }
    
        internal RaycastHit HitInfo { get; private set; }
    
        /// <summary>
        /// Cursor object visible in the scene
        /// </summary>
        internal GameObject Cursor { get; private set; }
    
        internal bool Hit { get; private set; }
    
        internal Vector3 Position { get; private set; }
    
        internal Vector3 Normal { get; private set; }
    
        private Vector3 _gazeOrigin;
    
        private Vector3 _gazeDirection;
    
  6. Fügen Sie die CreateCursor()- Methode hinzu, um den HoloLens-Cursor in der Szene zu erstellen, und rufen Sie die Methode aus der Start() -Methode auf:

        /// <summary>
        /// Start method used upon initialisation.
        /// </summary>
        internal virtual void Start()
        {
            FocusedObject = null;
            Cursor = CreateCursor();
        }
    
        /// <summary>
        /// Method to create a cursor object.
        /// </summary>
        internal 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 = new Vector3(0.05f, 0.05f, 0.05f);
            Material mat = new Material(Shader.Find("Diffuse"));
            newCursor.GetComponent<MeshRenderer>().material = mat;
            mat.color = Color.HSVToRGB(0.0223f, 0.7922f, 1.000f);
            newCursor.SetActive(true);
    
            return newCursor;
        }
    
  7. Mit den folgenden Methoden können Sie den Blick Raycast aktivieren und die fokussierten Objekte nachverfolgen.

    /// <summary>
    /// Called every frame
    /// </summary>
    internal virtual void Update()
    {
        _gazeOrigin = Camera.main.transform.position;
    
        _gazeDirection = Camera.main.transform.forward;
    
        UpdateRaycast();
    }
    /// <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))
            {
                // Provide the 'Gaze Exited' event.
                oldFocusedObject.SendMessage("OnGazeExited", SendMessageOptions.DontRequireReceiver);
            }
        }
    }
    
        private void UpdateRaycast()
        {
            // Set the old focused gameobject.
            oldFocusedObject = FocusedObject;
            RaycastHit hitInfo;
    
            // Initialise Raycasting.
            Hit = Physics.Raycast(_gazeOrigin,
                _gazeDirection,
                out hitInfo,
                GazeMaxDistance);
                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. If so, reset the focused object.
            if (FocusedObject != oldFocusedObject)
            {
                ResetFocusedObject();
                if (FocusedObject != null)
                {
                    if (FocusedObject.CompareTag(InteractibleTag))
                    {
                        // Provide the 'Gaze Entered' event.
                        FocusedObject.SendMessage("OnGazeEntered", 
                            SendMessageOptions.DontRequireReceiver);
                    }
                }
            }
        }
    
  8. Speichern Sie Ihre Änderungen in Visual Studio, bevor Sie zu Unity zurückkehren.

Kapitel 8 – Erstellen der Interactions-Klasse

Sie müssen nun das Skript "Interaktionen" erstellen, das für Folgendes zuständig ist:

  • Behandeln der Tippinteraktion und des Kameraverweises, wodurch der Benutzer mit dem Protokoll in der Szene "Schaltfläche" interagieren kann.

  • Erstellen des Anmeldeobjekts "button" in der Szene, mit dem der Benutzer interagieren soll.

So erstellen Sie das Skript:

  1. Doppelklicken Sie auf den Ordner "Skripts ", um ihn zu öffnen.

  2. Klicken Sie mit der rechten Maustaste in den Ordner "Skripts", und klicken Sie auf "C#-Skript erstellen>". Nennen Sie das Skript "Interaktionen".

  3. Doppelklicken Sie auf das Skript, um es mit Visual Studio zu öffnen.

  4. Fügen Sie die folgenden Namespaces ein:

    using UnityEngine;
    using UnityEngine.XR.WSA.Input;
    
  5. Ändern Sie die Vererbung der Interaction-Klasse von MonoBehaviour in GazeInput.

    öffentliche Klasseninteraktionen : MonoBehaviour

    public class Interactions : GazeInput
    
  6. Fügen Sie in der Interaction-Klasse die folgende Variable ein:

        /// <summary>
        /// Allows input recognition with the HoloLens
        /// </summary>
        private GestureRecognizer _gestureRecognizer;
    
  7. Ersetzen Sie die Start-Methode . Beachten Sie, dass es sich um eine Außerkraftsetzungsmethode handelt, die die Gaze-Klassenmethode "base" aufruft. Start() wird aufgerufen, wenn die Klasse initialisiert, sich für die Eingabeerkennung registriert und die Anmeldeschaltfläche in der Szene erstellt:

        /// <summary>
        /// Called on initialization, after Awake
        /// </summary>
        internal override void Start()
        {
            base.Start();
    
            // Register the application to recognize HoloLens user inputs
            _gestureRecognizer = new GestureRecognizer();
            _gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap);
            _gestureRecognizer.Tapped += GestureRecognizer_Tapped;
            _gestureRecognizer.StartCapturingGestures();
    
            // Add the Graph script to this object
            gameObject.AddComponent<MeetingsUI>();
            CreateSignInButton();
        }
    
  8. Fügen Sie die CreateSignInButton()-Methode hinzu, die die Anmeldeschaltfläche in der Szene instanziiert und dessen Eigenschaften festlegt:

        /// <summary>
        /// Create the sign in button object in the scene
        /// and sets its properties
        /// </summary>
        void CreateSignInButton()
        {
            GameObject signInButton = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    
            Material mat = new Material(Shader.Find("Diffuse"));
            signInButton.GetComponent<Renderer>().material = mat;
            mat.color = Color.blue;
    
            signInButton.transform.position = new Vector3(3.5f, 2f, 9f);
            signInButton.tag = "SignInButton";
            signInButton.AddComponent<Graph>();
        }
    
  9. Fügen Sie die methode GestureRecognizer_Tapped() hinzu, die für das Tap-Benutzerereignis reagiert werden soll.

        /// <summary>
        /// Detects the User Tap Input
        /// </summary>
        private void GestureRecognizer_Tapped(TappedEventArgs obj)
        {
            if(base.FocusedObject != null)
            {
                Debug.Log($"TAP on {base.FocusedObject.name}");
                base.FocusedObject.SendMessage("SignInAsync", SendMessageOptions.RequireReceiver);
            }
        }
    
  10. Löschen Sie die Update() -Methode, und speichern Sie ihre Änderungen in Visual Studio, bevor Sie zu Unity zurückkehren.

Kapitel 9 – Einrichten der Skriptverweise

In diesem Kapitel müssen Sie das Skript "Interaktionen" auf die Hauptkamera setzen. Dieses Skript behandelt dann das Platzieren der anderen Skripts, wo sie sein müssen.

  • Ziehen Sie im Ordner "Skripts" im Projektbereich das Skriptinteraktionen auf das Hauptkameraobjekt, wie unten dargestellt.

    Screenshot, der zeigt, wo das Skript

Kapitel 10 – Einrichten des Tags

Der Code, der den Blick behandelt, verwendet tag SignInButton , um zu identifizieren, mit welchem Objekt der Benutzer interagiert, um sich bei Microsoft Graph anzumelden.

So erstellen Sie das Tag:

  1. Klicken Sie im Unity-Editor im Hierarchiebereich auf die Hauptkamera.

  2. Klicken Sie im Inspektorbereich auf das MainCamera-Tag, um eine Dropdownliste zu öffnen. Klicken Sie auf Tag hinzufügen...

    Screenshot, der das Add-Tag hervorhebung... Option.

  3. Klicken Sie auf die Schaltfläche +.

    Screenshot der Schaltfläche

  4. Schreiben Sie den Tagnamen als SignInButton , und klicken Sie auf "Speichern".

    Screenshot, der zeigt, wo der SignInButton-Tagname hinzugefügt werden soll.

Kapitel 11 – Erstellen des Unity-Projekts auf UWP

Alles, was für den Unity-Abschnitt dieses Projekts erforderlich ist, wurde jetzt abgeschlossen, daher ist es an der Zeit, es aus Unity zu erstellen.

  1. Navigieren Sie zu Buildeinstellungen (Dateibuildeinstellungen>).

    Screenshot des Dialogfelds

  2. Wenn noch nicht geschehen, ticken Sie unter "Unity C#-Projekte".

  3. Klicken Sie auf Erstellen. Unity startet ein Explorer-Fenster, in dem Sie einen Ordner erstellen und dann einen Ordner auswählen müssen, in dem die App erstellt werden soll. Erstellen Sie diesen Ordner jetzt, und nennen Sie ihn " App". Klicken Sie dann mit ausgewähltem App-Ordner auf "Ordner auswählen".

  4. Unity beginnt mit dem Erstellen Ihres Projekts im App-Ordner .

  5. Nachdem Unity das Erstellen abgeschlossen hat (es kann einige Zeit dauern), öffnet es ein Explorer Fenster an der Position Ihres Builds (überprüfen Sie Ihre Taskleiste, da sie möglicherweise nicht immer über Ihren Fenstern angezeigt wird, sondern Sie über dem Hinzufügen eines neuen Fensters informiert).

Kapitel 12 – Bereitstellen für HoloLens

So stellen Sie holoLens bereit:

  1. Sie benötigen die IP-Adresse Ihrer HoloLens (für Remotebereitstellung) und um sicherzustellen, dass Sich Ihre HoloLens im Entwicklermodus befindet. Gehen Sie dazu wie folgt vor:

    1. Öffnen Sie beim Tragen Ihrer HoloLens die Einstellungen.

    2. Wechseln sie zu den erweiterten Optionen für Netzwerk- und Internet-WLAN>>

    3. Notieren Sie sich die IPv4-Adresse .

    4. Navigieren Sie als Nächstes zurück zu "Einstellungen" und dann zu "Update & Sicherheit>für Entwickler".

    5. Legen Sie den Entwicklermodus aktiviert fest.

  2. Navigieren Sie zu Ihrem neuen Unity-Build (dem App-Ordner ), und öffnen Sie die Projektmappendatei mit Visual Studio.

  3. Wählen Sie in der Lösungskonfiguration "Debuggen" aus.

  4. Wählen Sie in der Lösungsplattform x86, Remotecomputer aus. Sie werden aufgefordert, die IP-Adresse eines Remotegeräts einzufügen (in diesem Fall die HoloLens, die Sie angegeben haben).

    Screenshot, der zeigt, wo x86 und Remotecomputer ausgewählt werden sollen.

  5. Wechseln Sie zum Menü "Erstellen ", und klicken Sie auf " Lösung bereitstellen", um die Anwendung in Ihre HoloLens querzuladen.

  6. Ihre App sollte jetzt in der Liste der installierten Apps auf Ihrer HoloLens angezeigt werden, damit sie gestartet werden können!

Ihre Microsoft Graph HoloLens-Anwendung

Herzlichen Glückwunsch, Sie haben eine Mixed Reality-App erstellt, die Microsoft Graph nutzt, um Benutzerkalenderdaten zu lesen und anzuzeigen.

Screenshot der abgeschlossenen Mixed Reality-App.

Zusatzübungen

Übung 1

Verwenden von Microsoft Graph zum Anzeigen anderer Informationen zum Benutzer

  • Benutzer-E-Mail/ Telefonnummer / Profilbild

Übung 1

Implementieren Sie das Sprachsteuerelement, um in der Microsoft Graph-Benutzeroberfläche zu navigieren.