HoloLens (1. genel) ve Azure 311-Microsoft Graph

Not

karışık gerçeklik akademik öğreticiler, HoloLens (1. gen) ve karma gerçeklik derinlikli kulaklıkları göz önünde bulundurularak tasarlandı. Bu nedenle, hala bu cihazlarda geliştirme konusunda rehberlik arayan geliştiriciler için Bu öğreticilerin yerinde ayrılmanız önemlidir. bu öğreticiler, HoloLens 2 ' de kullanılan en son araç kümeleri veya etkileşimler ile güncelleştirilmeyecek. Desteklenen cihazlarda çalışmaya devam etmek için tutulacağız. gelecekte HoloLens 2 için geliştirmeyi gösteren yeni bir öğretici serisi olacaktır. Bu bildirim, ne zaman nakledildiklerinde Bu öğreticilerin bir bağlantısıyla güncelleştirilir.

bu kursta, karma gerçeklik uygulamasındaki güvenli kimlik doğrulaması kullanarak Microsoft hesabı oturum açmak için Microsoft Graph kullanmayı öğreneceksiniz. Daha sonra, zamanlanan toplantılarınızı uygulama arabiriminde alır ve görüntüleriz.

Microsoft Graph , Microsoft 'un birçok hizmetine erişim sağlamak için tasarlanan bir apı kümesidir. Microsoft, ilişki ile bağlanmış bir kaynak matrisi olarak Microsoft Graph açıklar. bu, bir uygulamanın tüm bağlantılı kullanıcı verilerine erişmesine izin verir. daha fazla bilgi için Microsoft Graph sayfasınıziyaret edin.

Geliştirme, kullanıcıdan Gaze olarak talimat verilecek bir uygulama oluşturmayı ve sonra da kullanıcıdan Microsoft hesabı güvenli bir şekilde oturum açmasını isteyen bir sphere öğesine dokunmasına neden olur. Hesabında oturum açtıktan sonra, Kullanıcı, gün için zamanlanmış bir toplantılar listesi görebilir.

bu kursu tamamladığınıza göre, bir karma gerçeklik HoloLens uygulamanız olur ve bu, aşağıdakileri yapabilecekler:

  1. Dokunma hareketini kullanarak, kullanıcıdan bir Microsoft hesabında oturum açmasını (uygulamanın oturumunu açıp yeniden uygulamaya tekrar geri dönmesi) isteyen bir nesneye dokunun.
  2. Gün için zamanlanan toplantıların listesini görüntüleyin.

Uygulamanızda, sonuçları tasarımınızla nasıl tümleştirileceğini öğrenmek sizin için önemlidir. Bu kurs, Unity projenizle bir Azure hizmetini nasıl tümleştirileceğini öğretirecek şekilde tasarlanmıştır. Bu kursta, karma gerçeklik uygulamanızı geliştirmek üzere elde ettiğiniz bilgileri kullanmak sizin işimdir.

Cihaz desteği

Kurs HoloLens Modern kulaklıklar
MR ve Azure 311: Microsoft Graph ✔️

Önkoşullar

Not

Bu öğretici, Unity ve C# ile temel deneyimi olan geliştiriciler için tasarlanmıştır. Ayrıca, bu belge içindeki önkoşulların ve yazılı yönergelerin yazma sırasında nelerin sınanmış ve doğrulandığını temsil ettiğini lütfen unutmayın (Temmuz 2018). Araçları yüklemek için en son yazılımı kullanabilirsiniz, ancak bu kursla ilgili bilgilerin aşağıda listelenenlerden daha yeni yazılımda bulacağınız şekilde tam olarak eşleştiğini varsaymamalıdır.

Bu kurs için aşağıdaki donanım ve yazılımları öneririz:

Başlamadan önce

  1. Bu projeyi oluşturma sorunlarından kaçınmak için, bu öğreticide bahsedilen projeyi bir kök veya yakın kök klasörde oluşturmanız önemle önerilir (uzun klasör yolları derleme sırasında sorunlara neden olabilir).
  2. HoloLens ayarlayın ve test edin. HoloLens ayarlamayı desteklemek istiyorsanız, HoloLens kurulum makalesini ziyaret ettiğinizden emin olun.
  3. yeni bir HoloLens uygulaması geliştirmeye başlarken ayarlama ve algılayıcı ayarlamayı gerçekleştirmek iyi bir fikirdir (bazen bu görevleri her kullanıcı için gerçekleştirmeye yardımcı olabilir).

ayarlama hakkında yardım için lütfen bu bağlantıyı HoloLens ayarlama makalesineuygulayın.

algılayıcı ayarlaması hakkında yardım için lütfen bu bağlantıyı HoloLens algılayıcı ayarlama makalesineuygulayın.

Bölüm 1-uygulamanızı uygulama kayıt portalında oluşturma

İle başlamak için uygulama kayıt portalı'nda uygulamanızı oluşturmanız ve kaydetmeniz gerekir.

bu bölümde, hesap içeriğinize erişmek için Microsoft Graph çağrılar yapmanıza olanak sağlayacak hizmet anahtarını da bulacaksınız.

  1. Microsoft uygulama kayıt portalı ' na gidin ve Microsoft hesabınızla oturum açın. Oturum açtıktan sonra, uygulama kayıt portalınayönlendirilirsiniz.

  2. Uygulamalarım bölümünde, bir uygulama ekledüğmesine tıklayın.

    Önemli

    Uygulama kayıt portalı , daha önce Microsoft Graphçalışdığınıza bağlı olarak farklı görünebilir. Aşağıdaki ekran görüntülerinde bu farklı sürümler görüntülenir.

  3. Uygulamanız için bir ad ekleyin ve Oluştur' a tıklayın.

  4. Uygulama oluşturulduktan sonra uygulama ana sayfasına yönlendirilirsiniz. Uygulama kimliği ' ni kopyalayın ve bu değeri güvenli bir yerde aklınızda olduğunuzdan emin olun. Bu işlem, kodunuzda yakında kullanacaksınız.

  5. Platformlar bölümünde, yerel uygulamanın görüntülendiğinden emin olun. Yoksa, Platform Ekle' ye tıkladıktan sonra yerel uygulama' yı seçin.

  6. aynı sayfada aşağı kaydırın ve Microsoft Graph izinler adlı bölümde, uygulama için ek izinler eklemeniz gerekir. Temsilci izinleri' nin yanındaki Ekle ' ye tıklayın.

  7. Uygulamanızın kullanıcının takvimine erişmesini istediğiniz için, takvimler. Read adlı kutuyu Işaretleyin ve Tamam' a tıklayın.

  8. En Alta kaydırın ve Kaydet düğmesine tıklayın.

  9. Kaydetme yapmanız onaylanır ve uygulama kayıt portalındanoturumu kapatabilirsiniz.

Bölüm 2-Unity projesini ayarlama

Aşağıda, karma gerçeklik ile geliştirme için tipik bir kurulum verilmiştir ve bu, diğer projeler için iyi bir şablondur.

  1. Unity 'yi açın ve Yeni' ye tıklayın.

  2. Unity proje adı sağlamanız gerekir. Msgraphmrekleyin. Proje şablonunun 3Bolarak ayarlandığından emin olun. Konumu sizin için uygun bir yere ayarlayın (unutmayın, kök dizinlerin yakınına daha iyi). Ardından proje oluştur' a tıklayın.

  3. Unity açık olduğunda, varsayılan komut dosyası düzenleyicisininVisual Studioolarak ayarlanmış olması gerekir. Tercihleri Düzenle ' ye gidin ve sonra yeni penceresinden dış araçlar' a gidin. dış betik düzenleyicisiniVisual Studio 2017olarak değiştirin. Tercihler penceresini kapatın.

  4. dosyaderleme Ayarlar gidin ve Evrensel Windows Platformu' i seçin, sonra seçiminizi uygulamak için platformu değiştir düğmesine tıklayın.

  5. hala dosyaderleme Ayarlar, şunları yaptığınızdan emin olun:

    1. Hedef cihazHoloLens olarak ayarlandı

    2. Yapı türüD3D olarak ayarlandı

    3. SDKen son yüklü olarak ayarlandı

    4. Visual Studio sürümüen son yüklü olarak ayarlandı

    5. Oluşturma ve çalıştırma , yerel makine olarak ayarlandı

    6. Sahneyi kaydedin ve yapıya ekleyin.

      1. Açık sahneler Ekleseçeneğini belirleyerek bunu yapın. Bir Kaydet penceresi görüntülenir.

      2. Bu ve gelecekteki tüm sahneye yönelik yeni bir klasör oluşturun. Yeni klasör düğmesini seçin , yeni bir klasör oluşturun ve sahnealanı ' nı adlandırın.

      3. Yeni oluşturulan sahneler klasörünüzü açın ve sonra dosya adı: metin alanında MR_ComputerVisionSceneyazın ve ardından Kaydet' e tıklayın.

        Önemli

        Bilmeniz gerekirse, Unity sahnelerinizi varlıklar klasörü içine kaydetmeniz gerekir, çünkü Unity projesiyle ilişkilendirilmesi gerekir. Sahneler klasörünü oluşturma (ve diğer benzer klasörler), Unity projesini yapılandırmak için tipik bir yoldur.

    7. yapı Ayarlariçindeki kalan ayarlar şimdilik varsayılan olarak bırakılmalıdır.

  6. Derleme AyarlarPlayer Ayarlar düğmesine tıklayın. Bu, Denetçinin bulunduğu alanda ilgili paneli açar.

  7. Bu panelde birkaç ayarın doğrulanmış olması gerekir:

    1. Diğer Ayarlar:

      1. Betik ÇalışmaZamanı SürümüDeneysel (.NET 4.6 Eşdeğeri) olmalıdır; bu da Düzenleyici'nin yeniden başlatılmasını tetikler.

      2. Betik Arka Ucu.NET olmalı

      3. API Uyumluluk Düzeyi.NET 4.6 olmalı

    2. Yayımlama sekmesi Ayarlar altında şunlarıkontrol edin:

      • InternetClient

    3. Panelin daha aşağılarında, XR Ayarlar 'de (Yayımlama Ayarlaraltında bulunur) Sanal Gerçeklik Desteği'ni kontrol edin,Windows Mixed Reality SDK'sı eklenmiştir.

  8. Derleme çalışma Ayarlargeri dönüp Unity C# Projeleri artık gri değil; bunun yanındaki onay kutusunu işaretleyin.

  9. Derleme ve Ayarlar kapatın.

  10. Sahnenizi ve projenizi kaydedin (DOSYA KAYDETMESAHNELER / DOSYA KAYDETPROJE).

Bölüm 3 - Unity'de Kitaplıkları İçeri Aktarma

Önemli

Bu kursun Unity Set up bileşenini atlayıp doğrudan koda geçmek isterseniz, bu Azure-MR-311.unitypackage'ıindirebilir, Özel Paket olarak projenize aktarabilir ve ardından 5.Bölümden devam edin.

Unity içinde Microsoft Graph kullanmak için Microsoft.Identity.Client DLL'sini kullanmalıdır. Microsoft Graph SDK'sı kullanmak mümkündür, ancak Unity projesini (derleme sonrası projeyi düzenleme anlamına gelir) sonra bir NuGet paketi eklemesi gerekir. Gerekli URL'lerin doğrudan Unity'ye içeri aktarılacağı daha basit kabul edilir.

Not

Unity'de şu anda eklentilerin içeri aktarmadan sonra yeniden yapılandırılması gereken bilinen bir sorun vardır. Hata çözüldükten sonra bu adımlar (bu bölümde 4 - 7) gerekli olmayacaktır.

Microsoft Graph'i kendi projenize içeri aktarın, MSGraph_LabPlugins.zip indirin. Bu paket, test edilmiş kitaplıkların sürümleriyle oluşturulmuş.

Unity projenize özel URL'ler ekleme hakkında daha fazla bilgi için bu bağlantıyı izleyin.

Paketi içeri aktarma:

  1. Varlıklar Paketi Özel Paketi İçeri Aktar menü seçeneğini kullanarakUnity PaketiniUnity'ye ekleyin. Az önce indirdiğiniz paketi seçin.

  2. Açılan Unity Paketini İçeri Aktar kutusunda Eklentiler altındaki (ve dahil) her şeyin seçili olduğundan emin olun.

  3. Öğeleri projenize eklemek için İçeri Aktar düğmesine tıklayın.

  4. Project Paneli'ninEklentiler altındaki MSGraph klasörüne gidin ve Microsoft.Identity.Client adlı eklentiyi seçin.

  5. Eklenti seçiliyken Herhangi Bir Platform seçeneğinin işaretlenmemiş olduğundan emin olun, ardından WSAPlayer öğesinin de işaretlenmemiş olduğundan emin olun ve Uygula'ya tıklayın. Bu yalnızca dosyaların doğru yapılandırıldığından emin olmak için kullanılır.

    Not

    Bu eklentileri işaretlemek, bunları yalnızca Unity Düzenleyicisi'nde kullanılacak şekilde yapılandırıyor. WSA klasöründe proje Unity'den Universal Windows Application olarak dışarı aktarıldıktan sonra kullanılacak olan farklı bir DLL kümesi vardır.

  6. Ardından, MSGraphklasörünün içinde WSA klasörünü açabilirsiniz. Az önce yapılandırmış olduğunuz dosyanın bir kopyasını görüyorsunuz. Dosyayı seçin ve ardından denetçide:

    • Tüm Platformlar'ınişaretinin kaldırlendiğinden veyalnızcaWSAPlayer'ın işaretlendiğinden emin olun.

    • SDK'nınUWP olarak,Betik Arka Ucu'nın da Dot Net olarak ayarlanmış olduğundan emin olmak

    • İşleme'nin işaretli olduğundan emin olun.

  7. Uygula’ya tıklayın.

Bölüm 4 - Kamera Kurulumu

Bu bölümde sahnenizin Ana Kamera'sı ayarlanır:

  1. Hiyerarşi Panelinde AnaKamera'yı seçin.

  2. Seçildikten sonra Denetçi panelinde Ana Kamera'nın tüm bileşenlerinigörüntüleyebilirsiniz.

    1. Camera nesnesinin adı Ana Kamera (yazıma dikkat edin!)

    2. Ana Kamera Etiketi MainCamera olarak ayarlansın (yazıma dikkat edin!)

    3. Dönüştürme Konumu'nın 0,0, 0 olarak ayarlanmış olduğundan emin olun

    4. Clear Flags'i DüzRenk olarak ayarlama

    5. Kamera Bileşeninin Arka Plan Rengini Siyah, Alfa 0(Altıgen Kod: #00000000) olarak ayarlayın

  3. Hiyerarşi Paneli'nin son nesne yapısı aşağıdaki resimde gösterilene benzer olmalıdır:

Bölüm 5 - MeetingsUI sınıfı oluşturma

Oluşturmanız gereken ilk betik, uygulamanın kullanıcı arabirimini (karşılama iletisi, yönergeler ve toplantı ayrıntıları) barındırma ve doldurmakla sorumlu olan MeetingsUIbetiğidir.

Bu sınıfı oluşturmak için:

  1. Project Panel'de Assetsklasörünesağ tıklayın ve Ardından Klasör Oluştur'useçin. Klasöre Betikler adını girin.

  2. Betikler klasörünü açın ve bu klasörün içinde C# Betiği Oluştur'asağ tıklayın. Betiği MeetingsUI olarak adlar.

  3. Yeni MeetingsUI betiğine çift tıklar ve bu betiği Visual Studio.

  4. Aşağıdaki ad alanlarını ekleyin:

    using System;
    using UnityEngine;
    
  5. sınıfının içine aşağıdaki değişkenleri girin:

        /// <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. Ardından Start() yöntemini değiştirin ve bir Uyut() yöntemi ekleyin. Bunlar, sınıf başlatılırken çağrılır:

        /// <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. Toplantılar kullanıcı arabirimini oluşturmakla sorumlu yöntemleri ekleyin ve istenen zaman geçerli toplantılarla bunu ekleyin:

        /// <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. Update() yöntemini silin ve Unity'ye geri Visual Studio değişikliklerinizi kaydedin.

Bölüm 6 - Graph oluşturma

Oluşturulan sonraki betik, Graph betiğidir. Bu betik, kullanıcının kimliğini doğrulamak ve kullanıcının takviminde geçerli günün zamanlanmış toplantılarını almak için çağrılar yapmaktan sorumludur.

Bu sınıfı oluşturmak için:

  1. Betikler klasörüne çift tıklayın ve açın.

  2. Betikler klasörünün içine sağ tıklayın, C# BetiğiOluştur'a tıklayın. Betiği olarak Graph.

  3. Betiğin üzerine çift tıklar ve bu betiği Visual Studio.

  4. Aşağıdaki ad alanlarını ekleyin:

    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
    

    Önemli

    Bu betikte yer alan kodun bölümlerinin ÖnDerleme Yönergeleri çevresinde sarmalanmış olduğunu fark Visual Studio. Bu, derleme Çözümünü derlemek için kitaplıklarla ilgili sorunları önlemektir.

  5. Kullanılmayacaklarıiçin Start() ve Update() yöntemlerini silin.

  6. Aşağıdaki Graph dışında, günlük zamanlanmış toplantılar temsil eden JSON nesnesinin serisini çıkararak gereken aşağıdaki nesneleri ekler:

    /// <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. Graph sınıfına aşağıdaki değişkenleri ekleyin:

        /// <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;
    
    

    Not

    appId değerini Bölüm 1'de not not edin ve 4.adımda not edin. Bu değer, Uygulama Kayıt Portalı'nın uygulama kayıt sayfasında görüntülenen değerle aynı olması gerekir.

  8. Graph sınıfının içinde, kullanıcıdan oturum açma kimlik bilgilerini eklemesi istenecek SignInAsync() ve AquireTokenAsync()yöntemlerini ekleyin.

        /// <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. Aşağıdaki iki yöntemi ekleyin:

    1. BuildTodayCalendarEndpoint(), zamanlanan toplantıların alınarak gün ve zaman aralığı belirten URI'yi derleme.

    2. ListMeetingsAsync(), Microsoft'tanzamanlanmış toplantılar Graph.

        /// <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. Artık komut dosyasını Graph. Unity'ye geri Visual Studio değişikliklerinizi kaydedin.

Bölüm 7 - GazeInput betiği oluşturma

Şimdi GazeInput'i oluşturacak. Bu sınıf, Ana Kameradan gelen bir Raycast kullanarak kullanıcının bakışını ele alıyor ve takip ediyor.

Betiği oluşturmak için:

  1. Betikler klasörüne çift tıklayın ve açın.

  2. Betikler klasörünün içine sağ tıklayın, C# BetiğiOluştur'a tıklayın. Betiği GazeInput olarak adlandırın.

  3. Betiğin üzerine çift tıklar ve bu betiği Visual Studio.

  4. Ad alanları kodunu aşağıdakiyle eşleştiecek şekilde ve seri hale getirilsin diye GazeInput sınıfınıza '[System.Serializable]' etiketini ekleyerek değiştirebilirsiniz:

    using UnityEngine;
    
    /// <summary>
    /// Class responsible for the User's Gaze interactions
    /// </summary>
    [System.Serializable]
    public class GazeInput : MonoBehaviour
    {
    
  5. GazeInput sınıfının içine aşağıdaki değişkenleri ekleyin:

        [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. Sahnenin en HoloLens oluşturmak ve Start() yönteminden yöntemini çağıran CreateCursor() yöntemini ekleyin:

        /// <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. Aşağıdaki yöntemler Raycast'in bakışını etkinleştirir ve odaklanmış nesneleri takip eder.

    /// <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. Unity'ye geri Visual Studio değişikliklerinizi kaydedin.

8. Bölüm - Etkileşimler sınıfını oluşturma

Şimdi aşağıdakilerin sorumluluğunda olan Etkileşimler betiği oluşturmanız gerekir:

  • Kullanıcının sahnede "düğme" olarak oturumaçması için Dokunma etkileşimini ve Kamera Bakışı'nın işlenmesi.

  • Kullanıcının etkileşim kurması için sahnede "düğme" nesnesinde günlüğü oluşturma.

Betiği oluşturmak için:

  1. Betikler klasörüne çift tıklayın ve açın.

  2. Betikler klasörünün içine sağ tıklayın, C# BetiğiOluştur'a tıklayın. Betiği Etkileşimler olarak ad girin.

  3. Betiğin üzerine çift tıklar ve bu betiği Visual Studio.

  4. Aşağıdaki ad alanlarını ekleyin:

    using UnityEngine;
    using UnityEngine.XR.WSA.Input;
    
  5. Interaction sınıfının MonoBehaviour olan devralmayı GazeInput olarak değiştirme.

    public sınıfı Etkileşimleri: MonoBehaviour

    public class Interactions : GazeInput
    
  6. Interaction sınıfının içine aşağıdaki değişkeni girin:

        /// <summary>
        /// Allows input recognition with the HoloLens
        /// </summary>
        private GestureRecognizer _gestureRecognizer;
    
  7. Start yöntemini değiştirin; bunun 'base' Gaze sınıf yöntemini çağıran bir geçersiz kılma yöntemi olduğunu fark. Sınıf başlatıldığında, giriş tanımaya kaydolarak ve sahnede oturum açma düğmesini oluştururken Start() çağrılır:

        /// <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. Sahnede oturum açma düğmesinin örneğini oluşturacak ve özelliklerini ayar edecek CreateSignInButton() yöntemini ekleyin:

        /// <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. Tap user GestureRecognizer_Tapped yanıt veren GestureRecognizer_Tapped() yöntemini ekleyin.

        /// <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. Update() yöntemini silin ve Unity'ye geri dönmeden Visual Studio değişikliklerinizi kaydedin.

Bölüm 9 - Betik başvurularını ayarlama

Bu bölümde Etkileşimler betiği'nin Ana Kamera'ya yer öğrenmesi gerekir. Bu betik daha sonra diğer betikleri olması gereken yere yerleştirmeyi ele alar.

  • Project Paneli'ninScripts klasöründen Etkileşimler betiği aşağıda resimde olduğu gibi Ana Kamera nesnesine sürükleyin.

Bölüm 10 - Etiketi Ayarlama

Bakışı ele alan kod, kullanıcının Microsoft Graph'de oturum açmak için hangi nesneyle etkileşim kuracaklarını belirlemek için Tag SignInButton'uGraph.

Etiketi oluşturmak için:

  1. Unity Düzenleyicisi'nde Hiyerarşi Panelinde Ana Kamera'yatıklayın.

  2. Denetçi PanelindeMainCamera Etiketi'netıklar ve açılan listeyi açın. Etiket Ekle...

  3. Düğmesine + tıklayın.

  4. Etiket adını SignInButton olarak yazın ve Kaydet'e tıklayın.

Bölüm 11 - Unity projesini UWP'ye derleme

Bu projenin Unity bölümü için gereken her şey artık tamamlandı, bu nedenle bunu Unity'den oluşturmanın zamanı geldi.

  1. Build Ayarlar ( FileBuild Ayarlar).

  2. Henüz yoksa Unity C# Projeleri'ne tıklar.

  3. Derleme'ye tıklayın. Unity bir Dosya Gezgini penceresi açar ve burada uygulamayı derlemek için bir klasör seçmeniz gerekir. Bu klasörü şimdi oluşturun ve App olarak ad girin. Ardından Uygulama klasörü seçiliyken Klasör Seç'e tıklayın.

  4. Unity projenizi App klasörüne oluşturmaya başlar.

  5. Unity derlemeyi tamamladikten sonra (biraz zaman alır), derlemenizin bulunduğu konumda bir Dosya Gezgini penceresi açar (görev çubuğuna bakın çünkü her zaman pencerenizin üzerinde görünse de yeni bir pencerenin ekini size bildirecek).

Bölüm 12 - Dağıtım HoloLens

Dağıtım için HoloLens:

  1. Uygulamanızın IP Adresine (Uzaktan HoloLens için) ve uygulamanızın Geliştirici HoloLens olduğundan emin olmak gerekir. Bunu yapmak için:

    1. Dosyanızı takarak HoloLens için Ayarlar.

    2. İnterneti>>>>

    3. IPv4 adresini not yazın.

    4. Ardından, Ayarlar'a geri gidinve ardından Geliştiriciler için Güvenliği Güncelleştirme'yegidin

    5. Üzerinde Geliştirici Modunu ayarlayın.

  2. Yeni Unity derlemenize (App klasörüne) gidin ve Visual Studio.

  3. Çözüm Yapılandırması'da HataAyıkla'ya seçin.

  4. Çözüm Platformu'dax86, Uzak Makine'yi seçin. Uzak bir cihazın IP adresini (bu durumda HoloLens) girmeniz istenir.

  5. Derleme menüsüne gidin ve Çözümü Dağıt'a tıklar ve uygulamayı uygulamanıza HoloLens.

  6. Artık uygulamanız, uygulama uygulamanıza yüklenmiş uygulamalar listesinde HoloLens kullanıma hazır!

Microsoft Graph HoloLens uygulama

Tebrikler, kullanıcı Takvim verilerini okumak ve görüntülemek için Microsoft Graph'nden yararlanan bir karma gerçeklik uygulaması inşa ettiniz.

Ek alıştırmalar

Alıştırma 1

Kullanıcı Graph bilgileri görüntülemek için Microsoft Graph'i kullanma

  • Kullanıcı e-postası / telefon numarası / profil resmi

Alıştırma 1

Microsoft kullanıcı arabiriminde gezinmek için ses Graph gerçekleştirin.