HoloLens (1e generatie) en Azure 311 - Microsoft Graph
Notitie
De Mixed Reality Academy-zelfstudies zijn ontworpen met HoloLens (1e generatie) en Mixed Reality Immersive Headsets in gedachten. Daarom vinden we het belangrijk om deze zelfstudies te behouden voor ontwikkelaars die nog steeds op zoek zijn naar richtlijnen bij het ontwikkelen voor die apparaten. Deze zelfstudies worden niet bijgewerkt met de nieuwste toolsets of interacties die worden gebruikt voor HoloLens 2. Ze blijven behouden om door te gaan met het werken op de ondersteunde apparaten. Er is een nieuwe reeks zelfstudies die in de toekomst zullen worden gepost en die laten zien hoe u zich ontwikkelt voor HoloLens 2. Deze kennisgeving wordt bijgewerkt met een koppeling naar deze zelfstudies wanneer ze worden gepost.
In deze cursus leert u hoe u Microsoft Graph gebruikt om u aan te melden bij uw Microsoft-account met behulp van beveiligde verificatie in een mixed reality-toepassing. Vervolgens haalt u de geplande vergaderingen op en geeft u deze weer in de toepassingsinterface.
Microsoft Graph is een set API's die zijn ontworpen voor toegang tot veel van de services van Microsoft. Microsoft Graph beschrijft Microsoft Graph als een matrix van resources die zijn verbonden door relaties, wat betekent dat een toepassing toegang heeft tot allerlei soorten verbonden gebruikersgegevens. Ga naar de Microsoft Graph-pagina voor meer informatie.
Ontwikkeling omvat het maken van een app waarin de gebruiker wordt geïnstrueerd om naar een bol te kijken en vervolgens op een bol te tikken, waardoor de gebruiker wordt gevraagd zich veilig aan te melden bij een Microsoft-account. Zodra de gebruiker zich heeft aangemeld bij zijn of haar account, ziet hij een lijst met vergaderingen die voor de dag zijn gepland.
Nadat u deze cursus hebt voltooid, hebt u een HoloLens-toepassing voor mixed reality, die het volgende kan doen:
- Tik met behulp van het tikbeweging op een object, waarmee de gebruiker wordt gevraagd zich aan te melden bij een Microsoft-account (de app wordt verwijderd om u aan te melden en vervolgens weer in de app).
- Bekijk een lijst met vergaderingen die zijn gepland voor de dag.
In uw toepassing is het aan u om te bepalen hoe u de resultaten integreert met uw ontwerp. Deze cursus is ontworpen om u te leren hoe u een Azure Service integreert met uw Unity-project. Het is uw taak om de kennis die u uit deze cursus krijgt te gebruiken om uw mixed reality-toepassing te verbeteren.
Ondersteuning voor apparaten
Cursus | HoloLens | Insluitende headsets |
---|---|---|
MR en Azure 311: Microsoft Graph | ✔️ |
Vereisten
Notitie
Deze zelfstudie is ontworpen voor ontwikkelaars die basiservaring hebben met Unity en C#. Houd er ook rekening mee dat de vereisten en schriftelijke instructies in dit document staan voor wat er op het moment van schrijven is getest en geverifieerd (juli 2018). U bent vrij om de nieuwste software te gebruiken, zoals vermeld in het artikel over de installatie van de hulpprogramma's , hoewel wordt ervan uitgegaan dat de informatie in deze cursus perfect overeenkomt met wat u vindt in nieuwere software dan hieronder wordt vermeld.
Voor deze cursus raden we de volgende hardware en software aan:
- Een ontwikkel-pc
- Windows 10 Fall Creators Update (of hoger) waarvoor de ontwikkelaarsmodus is ingeschakeld
- De nieuwste Windows 10 SDK
- Unity 2017.4
- Visual Studio 2017
- Een Microsoft HoloLens waarvoor de ontwikkelaarsmodus is ingeschakeld
- Internettoegang voor het instellen van Azure en het ophalen van Microsoft Graph-gegevens
- Een geldig Microsoft-account (persoonlijk of werk/school)
- Een paar vergaderingen gepland voor de huidige dag, met hetzelfde Microsoft-account
Voordat u begint
- Om problemen met het bouwen van dit project te voorkomen, wordt u sterk aangeraden het project te maken dat in deze zelfstudie wordt genoemd in een hoofdmap of in een near-rootmap (lange mappaden kunnen problemen veroorzaken tijdens de build).
- Uw HoloLens instellen en testen. Als u ondersteuning nodig hebt voor het instellen van uw HoloLens, gaat u naar het installatieartikel van HoloLens.
- Het is een goed idee om kalibratie en sensorafstemming uit te voeren bij het ontwikkelen van een nieuwe HoloLens-app (soms kan het helpen om deze taken voor elke gebruiker uit te voeren).
Voor hulp bij kalibratie volgt u deze koppeling naar het HoloLens-kalibratieartikel.
Volg deze koppeling naar het artikel HoloLens Sensor Tuning voor hulp bij sensorafstemming.
Hoofdstuk 1: Uw app maken in de portal voor toepassingsregistratie
Om te beginnen moet u uw toepassing maken en registreren in de portal voor toepassingsregistratie.
In dit hoofdstuk vindt u ook de servicesleutel waarmee u microsoft Graph kunt aanroepen om toegang te krijgen tot uw accountinhoud.
Navigeer naar de Microsoft-portal voor toepassingsregistratie en meld u aan met uw Microsoft-account. Zodra u zich hebt aangemeld, wordt u omgeleid naar de portal voor toepassingsregistratie.
Klik in de sectie Mijn toepassingen op de knop Een app toevoegen.
Belangrijk
De portal voor toepassingsregistratie kan er anders uitzien, afhankelijk van of u eerder met Microsoft Graph hebt gewerkt. In de onderstaande schermafbeeldingen worden deze verschillende versies weergegeven.
Voeg een naam toe voor uw toepassing en klik op Maken.
Zodra de toepassing is gemaakt, wordt u omgeleid naar de hoofdpagina van de toepassing. Kopieer de toepassings-id en noteer deze waarde ergens veilig. U gebruikt deze binnenkort in uw code.
Zorg ervoor dat systeemeigen toepassing wordt weergegeven in de sectie Platforms. Als u niet op Platform toevoegen klikt en systeemeigen toepassing selecteert.
Schuif omlaag op dezelfde pagina en in de sectie Met de naam Microsoft Graph-machtigingen moet u extra machtigingen voor de toepassing toevoegen. Klik op Toevoegen naast Gedelegeerde machtigingen.
Aangezien u wilt dat uw toepassing toegang heeft tot de agenda van de gebruiker, schakelt u het selectievakje Agenda's.Lezen in en klikt u op OK.
Schuif naar de onderkant en klik op de knop Opslaan .
Uw opslag wordt bevestigd en u kunt zich afmelden bij de portal voor toepassingsregistratie.
Hoofdstuk 2 - Het Unity-project instellen
Hier volgt een typische opzet voor het ontwikkelen met mixed reality en is als zodanig een goede sjabloon voor andere projecten.
Open Unity en klik op Nieuw.
U moet een Unity-projectnaam opgeven. MSGraphMR invoegen. Zorg ervoor dat de projectsjabloon is ingesteld op 3D. Stel de locatie in op een locatie die geschikt is voor u (vergeet niet, dichter bij hoofdmappen is beter). Klik vervolgens op Project maken.
Als Unity is geopend, is het de moeite waard om te controleren of de standaardscripteditor is ingesteld op Visual Studio. Ga naar Voorkeuren bewerken>en navigeer vervolgens vanuit het nieuwe venster naar Externe hulpprogramma's. Wijzig de externe scripteditor in Visual Studio 2017. Sluit het venster Voorkeuren .
Ga naar Instellingen voor bestandsbuild>en selecteer Universeel Windows-platform en klik vervolgens op de knop Platform wisselen om uw selectie toe te passen.
Zorg er tijdens het maken van >bestanden voor dat:
Doelapparaat is ingesteld op HoloLens
Buildtype is ingesteld op D3D
SDK is ingesteld op Laatst geïnstalleerd
Visual Studio-versie is ingesteld op Meest recent geïnstalleerd
Bouwen en uitvoeren is ingesteld op lokale computer
Sla de scène op en voeg deze toe aan de build.
Doe dit door Open Scènes toevoegen te selecteren. Er wordt een venster voor opslaan weergegeven.
Maak een nieuwe map voor deze en eventuele toekomstige scènes. Selecteer de knop Nieuwe map om een nieuwe map te maken, geef deze de naam Scènes.
Open de zojuist gemaakte map Scènes en klik vervolgens in het tekstvak Bestandsnaam, typ MR_ComputerVisionScene en klik vervolgens op Opslaan.
Belangrijk
Houd er rekening mee dat u uw Unity-scènes in de map Assets moet opslaan, omdat deze moeten worden gekoppeld aan het Unity-project. Het maken van de scènemap (en andere vergelijkbare mappen) is een typische manier om een Unity-project te structureren.
De overige instellingen, in Build-instellingen, moeten voorlopig standaard blijven staan.
Klik in het venster Build-instellingen op de knop Spelerinstellingen . Hiermee opent u het gerelateerde deelvenster in de ruimte waar de Inspector zich bevindt.
In dit deelvenster moeten enkele instellingen worden geverifieerd:
Op het tabblad Overige instellingen :
Scripting Runtime-versie moet experimenteel (.NET 4.6 Equivalent) zijn, waardoor de editor opnieuw moet worden opgestart.
Back-end voor scripts moet .NET zijn
API-compatibiliteitsniveau moet .NET 4.6 zijn
Schakel op het tabblad Publicatie-instellingen onder Mogelijkheden het volgende in:
InternetClient
Ga verder naar het deelvenster in XR-instellingen (hieronder Publicatie-instellingen), controleer virtual reality ondersteund en controleer of de Windows Mixed Reality SDK is toegevoegd.
In build-instellingen wordt Unity C# Projects niet meer grijs weergegeven. Schakel het selectievakje ernaast in.
Sluit het venster Build Settings.
Sla uw scène en project op (FILE>SAVE SCENES / FILE>SAVE PROJECT).
Hoofdstuk 3 - Bibliotheken importeren in Unity
Belangrijk
Als u het Unity Set up-onderdeel van deze cursus wilt overslaan en direct in code wilt doorgaan, kunt u dit Azure-MR-311.unitypackage downloaden, het importeren in uw project als een aangepast pakket en vervolgens doorgaan vanaf hoofdstuk 5.
Als u Microsoft Graph in Unity wilt gebruiken, moet u gebruikmaken van het DLL-bestand Microsoft.Identity.Client. Het is echter mogelijk om de Microsoft Graph SDK te gebruiken, maar het vereist de toevoeging van een NuGet-pakket nadat u het Unity-project hebt gebouwd (wat betekent dat u het project na de build bewerkt). Het wordt beschouwd als eenvoudiger om de vereiste DLL's rechtstreeks in Unity te importeren.
Notitie
Er is momenteel een bekend probleem in Unity waarvoor invoegtoepassingen na het importeren opnieuw moeten worden geconfigureerd. Deze stappen (4 - 7 in deze sectie) zijn niet meer vereist nadat de fout is opgelost.
Als u Microsoft Graph in uw eigen project wilt importeren, downloadt u het MSGraph_LabPlugins.zip-bestand. Dit pakket is gemaakt met versies van de bibliotheken die zijn getest.
Als u meer wilt weten over het toevoegen van aangepaste DLL's aan uw Unity-project, volgt u deze koppeling.
Het pakket importeren:
Voeg het Unity-pakket toe aan Unity met behulp van de menuoptie Aangepast pakket> voor assets>importeren. Selecteer het pakket dat u zojuist hebt gedownload.
Controleer in het vak Import Unity Package dat verschijnt of alles onder (en inclusief) invoegtoepassingen is geselecteerd.
Klik op de knop Importeren om de items aan uw project toe te voegen.
Ga naar de map MSGraph onder Invoegtoepassingen in het projectvenster en selecteer de invoegtoepassing Microsoft.Identity.Client.
Als de invoegtoepassing is geselecteerd, controleert u of Any Platform is uitgeschakeld en controleert u of WSAPlayer ook is uitgeschakeld en klikt u vervolgens op Toepassen. Dit is alleen om te bevestigen dat de bestanden correct zijn geconfigureerd.
Notitie
Als u deze invoegtoepassingen markeert, worden ze alleen gebruikt in de Unity Editor. Er is een andere set DLL's in de WSA-map die wordt gebruikt nadat het project uit Unity is geëxporteerd als een Universele Windows-toepassing.
Vervolgens moet u de WSA-map openen in de map MSGraph . U ziet een kopie van hetzelfde bestand dat u zojuist hebt geconfigureerd. Selecteer het bestand en klik vervolgens in de inspector:
zorg ervoor dat Elk platform is uitgeschakeld en dat alleen WSAPlayer is ingeschakeld.
Zorg ervoor dat de SDK is ingesteld op UWP en dat de back-end voor scripts is ingesteld op Dot Net
Zorg ervoor dat het proces niet is ingeschakeld.
Klik op Toepassen.
Hoofdstuk 4 - Camera-instelling
Tijdens dit hoofdstuk stelt u de hoofdcamera van uw scène in:
Selecteer in het deelvenster Hiërarchie de hoofdcamera.
Zodra deze optie is geselecteerd, kunt u alle onderdelen van de hoofdcamera in het deelvenster Inspector zien.
Het cameraobject moet de naam Hoofdcamera hebben (let op de spelling!)
De hoofdcamera-tag moet worden ingesteld op MainCamera (let op de spelling!)
Zorg ervoor dat de positie van de transformatie is ingesteld op 0, 0, 0
Duidelijke vlaggen instellen op effen kleur
Stel de achtergrondkleur van het cameraonderdeel in op Zwart, Alpha 0 (Hex Code: #0000000000)
De uiteindelijke objectstructuur in het deelvenster Hiërarchie moet eruitzien als de structuur die wordt weergegeven in de onderstaande afbeelding:
Hoofdstuk 5 - Klas MeetingsUI maken
Het eerste script dat u moet maken, is MeetingsUI, die verantwoordelijk is voor het hosten en vullen van de gebruikersinterface van de toepassing (welkomstbericht, instructies en de details van de vergaderingen).
Ga als volgt te werk om deze klasse te maken:
Klik met de rechtermuisknop op de map Assets in het deelvenster Project en selecteer Map maken>. Geef de mapscripts een naam.
Open de map Scripts en klik in die map met de rechtermuisknop op C#-script maken>. Geef het script MeetingsUI een naam.
Dubbelklik op het nieuwe MeetingsUI-script om het te openen met Visual Studio.
Voeg de volgende naamruimten in:
using System; using UnityEngine;
Voeg in de klasse de volgende variabelen in:
/// <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;
Vervang vervolgens de Methode Start() en voeg een Awake() -methode toe. Deze worden aangeroepen wanneer de klasse wordt geïnitialiseerd:
/// <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(); }
Voeg de methoden toe die verantwoordelijk zijn voor het maken van de gebruikersinterface voor vergaderingen en vul deze in met de huidige vergaderingen wanneer dit wordt aangevraagd:
/// <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; }
Verwijder de methode Update() en sla uw wijzigingen op in Visual Studio voordat u terugkeert naar Unity.
Hoofdstuk 6: de Graph-klasse maken
Het volgende script dat moet worden gemaakt, is het Graph-script . Dit script is verantwoordelijk voor het uitvoeren van de aanroepen om de gebruiker te verifiëren en de geplande vergaderingen voor de huidige dag op te halen uit de agenda van de gebruiker.
Ga als volgt te werk om deze klasse te maken:
Dubbelklik op de map Scripts om deze te openen.
Klik met de rechtermuisknop in de map Scripts en klik op C#-script maken>. Geef de scriptgrafiek een naam.
Dubbelklik op het script om het te openen met Visual Studio.
Voeg de volgende naamruimten in:
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
Belangrijk
U zult merken dat delen van de code in dit script zijn verpakt rond precompile-instructies. Dit is om problemen met de bibliotheken te voorkomen bij het bouwen van de Visual Studio-oplossing.
Verwijder de methoden Start() en Update(), omdat ze niet worden gebruikt.
Voeg buiten de Graph-klasse de volgende objecten in, die nodig zijn om het JSON-object te deserialiseren voor de dagelijkse geplande vergaderingen:
/// <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; } }
Voeg in de Graph-klasse de volgende variabelen toe:
/// <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;
Notitie
Wijzig de appId-waarde in de app-id die u hebt genoteerd in hoofdstuk 1, stap 4. Deze waarde moet hetzelfde zijn als die wordt weergegeven in de portal voor toepassingsregistratie, op de registratiepagina van uw toepassing.
Voeg in de Graph-klasse de methoden SignInAsync() en AquireTokenAsync() toe, waarmee de gebruiker wordt gevraagd de aanmeldingsreferenties in te voegen.
/// <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; }
Voeg de volgende twee methoden toe:
BuildTodayCalendarEndpoint(), waarmee de URI wordt gebouwd die de dag en de tijdsduur aangeeft, waarin de geplande vergaderingen worden opgehaald.
ListMeetingsAsync(), die de geplande vergaderingen van Microsoft Graph aanvraagt.
/// <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 }
U hebt nu het Graph-script voltooid. Sla uw wijzigingen op in Visual Studio voordat u terugkeert naar Unity.
Hoofdstuk 7: het GazeInput-script maken
U gaat nu de GazeInput maken. Deze klasse verwerkt en houdt de blik van de gebruiker bij met behulp van een Raycast die afkomstig is van de hoofdcamera, die vooruit projecteert.
Het script maken:
Dubbelklik op de map Scripts om deze te openen.
Klik met de rechtermuisknop in de map Scripts en klik op C#-script maken>. Geef het script de naam GazeInput.
Dubbelklik op het script om het te openen met Visual Studio.
Wijzig de code van de naamruimten zodat deze overeenkomt met de code hieronder, samen met het toevoegen van de tag [System.Serializable] boven uw GazeInput-klasse , zodat deze kan worden geserialiseerd:
using UnityEngine; /// <summary> /// Class responsible for the User's Gaze interactions /// </summary> [System.Serializable] public class GazeInput : MonoBehaviour {
Voeg in de klasse GazeInput de volgende variabelen toe:
[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;
Voeg de methode CreateCursor() toe om de HoloLens-cursor in de scène te maken en roep de methode aan vanuit de Methode Start( ):
/// <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; }
Met de volgende methoden kunt u Raycast bekijken en de gerichte objecten bijhouden.
/// <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); } } } }
Sla uw wijzigingen op in Visual Studio voordat u terugkeert naar Unity.
Hoofdstuk 8 : de klasse Interacties maken
U moet nu het script Interacties maken. Dit is verantwoordelijk voor:
Omgaan met de interactie Tik en de Camera Gaze, waarmee de gebruiker kan communiceren met het aanmelden 'knop' in de scène.
Het logboek maken in het object 'button' in de scène waarmee de gebruiker kan communiceren.
Het script maken:
Dubbelklik op de map Scripts om deze te openen.
Klik met de rechtermuisknop in de map Scripts en klik op C#-script maken>. Geef de scriptinteracties een naam.
Dubbelklik op het script om het te openen met Visual Studio.
Voeg de volgende naamruimten in:
using UnityEngine; using UnityEngine.XR.WSA.Input;
Wijzig de overname van de klasse Interaction van MonoBehaviour in GazeInput.
interacties van openbare klasse : MonoBehaviourpublic class Interactions : GazeInput
Voeg in de klasse Interactie de volgende variabele in:
/// <summary> /// Allows input recognition with the HoloLens /// </summary> private GestureRecognizer _gestureRecognizer;
Vervang de Start-methode . U ziet dat het een onderdrukkingsmethode is, die de methode 'base' Gaze class aanroept. Start() wordt aangeroepen wanneer de klasse wordt geïnitialiseerd, wordt geregistreerd voor invoerherkenning en het maken van de aanmeldingsknop in de scène:
/// <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(); }
Voeg de methode CreateSignInButton() toe, waarmee de aanmeldingsknop in de scène wordt geïnstitueerde en de eigenschappen ervan worden ingesteld:
/// <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>(); }
Voeg de methode GestureRecognizer_Tapped() toe, die moet reageren op de gebeurtenis Tik op de gebruiker.
/// <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); } }
Verwijder de methode Update() en sla uw wijzigingen op in Visual Studio voordat u terugkeert naar Unity.
Hoofdstuk 9 - Scriptverwijzingen instellen
In dit hoofdstuk moet u het script Interacties op de hoofdcamera plaatsen. Dat script verwerkt vervolgens het plaatsen van de andere scripts waar ze moeten zijn.
Sleep vanuit de map Scripts in het projectvenster het scriptInteracties naar het object Hoofdcamera, zoals hieronder wordt weergegeven.
Hoofdstuk 10 - De tag instellen
De code die de blik verwerkt, maakt gebruik van de Tag SignInButton om te bepalen met welk object de gebruiker zal communiceren om zich aan te melden bij Microsoft Graph.
De tag maken:
Klik in de Unity-editor op de hoofdcamera in het deelvenster Hiërarchie.
Klik in het Inspector-deelvenster op de MainCamera-tag om een vervolgkeuzelijst te openen. Klik op Tag toevoegen...
Klik op de + knop.
Schrijf de tagnaam als SignInButton en klik op Opslaan.
Hoofdstuk 11 - Het Unity-project bouwen aan UWP
Alles wat nodig is voor de Unity-sectie van dit project is nu voltooid, dus het is tijd om het te bouwen vanuit Unity.
Navigeer naar Build-instellingen (instellingen voor bestandsbuild>).
Als dat nog niet zo is, tikt u op Unity C#-projecten.
Klik op Opbouwen. Unity start een Bestandenverkenner-venster waarin u een map moet maken en vervolgens een map selecteert waarin u de app wilt inbouwen. Maak die map nu en noem deze app. Klik vervolgens met de map App geselecteerd op Map selecteren.
Unity begint met het bouwen van uw project in de app-map .
Zodra Unity klaar is met bouwen (het kan enige tijd duren), wordt er een Bestandenverkenner venster geopend op de locatie van uw build (controleer de taakbalk, omdat deze mogelijk niet altijd boven uw vensters wordt weergegeven, maar u ontvangt een melding over de toevoeging van een nieuw venster).
Hoofdstuk 12 - Implementeren in HoloLens
Implementeren op HoloLens:
U hebt het IP-adres van uw HoloLens nodig (voor Extern implementeren) en om ervoor te zorgen dat uw HoloLens zich in de ontwikkelaarsmodus bevindt. U doet dit als volgt:
Open de instellingen terwijl u uw HoloLens draagt.
Ga naar Netwerk en Internet>Wi-Fi>Geavanceerde opties
Noteer het IPv4-adres .
Ga vervolgens terug naar Instellingen en ga vervolgens naar Update & Security>for Developers
Stel de ontwikkelaarsmodus in.
Navigeer naar uw nieuwe Unity-build (de app-map ) en open het oplossingsbestand met Visual Studio.
Selecteer foutopsporing in de oplossingsconfiguratie.
Selecteer x86, Remote Machine in het Solution Platform. U wordt gevraagd het IP-adres van een extern apparaat in te voegen (in dit geval de HoloLens, die u hebt genoteerd).
Ga naar het menu Bouwen en klik op Oplossing implementeren om de toepassing sideloaden naar uw HoloLens.
Uw app moet nu worden weergegeven in de lijst met geïnstalleerde apps op uw HoloLens, klaar om te worden gestart.
Uw Microsoft Graph HoloLens-toepassing
Gefeliciteerd, u hebt een mixed reality-app gemaakt die gebruikmaakt van Microsoft Graph, om gebruikersagendagegevens te lezen en weer te geven.
Bonusoefeningen
Oefening 1
Microsoft Graph gebruiken om andere informatie over de gebruiker weer te geven
- E-mailadres van gebruiker/telefoonnummer/profielafbeelding
Oefening 1
Implementeer spraakbesturing om door de Microsoft Graph-gebruikersinterface te navigeren.