Cara membuat dan menemukan jangkar menggunakan Azure Spatial Anchors di Unity

Azure Spatial Anchors memungkinkan Anda menggunakan jangkar yang sama di dunia antara perangkat yang berbeda. Layanan ini mendukung beberapa lingkungan pengembangan yang berbeda. Dalam artikel ini, kita akan mempelajari cara menggunakan SDK Azure Spatial Anchors, di Unity, untuk:

  • Menyiapkan dan mengelola sesi Azure Spatial Anchors dengan benar.
  • Membuat dan mengatur properti pada jangkar lokal.
  • Mengunggahnya ke cloud.
  • Menemukan dan menghapus jangkar spasial cloud.

Prasyarat

Untuk menyelesaikan panduan ini, pastikan Anda telah:

Cross Platform

Menginisialisasi sesi

Titik masuk utama untuk SDK adalah kelas yang mewakili sesi Anda. Umumnya Anda akan mendeklarasikan bidang di kelas yang mengelola tampilan dan sesi AR asli Anda.

Pelajari selengkapnya tentang kelas CloudSpatialAnchorSession.

    CloudSpatialAnchorSession cloudSession;
    // In your view handler
    this.cloudSession = new CloudSpatialAnchorSession();

Mengonfigurasikan autentikasi

Untuk mengakses layanan, Anda perlu menyediakan kunci akun, token akses, atau token autentikasi Microsoft Entra. Anda juga dapat membaca selengkapnya tentang ini di halaman Konsep Autentikasi.

Kunci Akun

Kunci Akun adalah informasi masuk yang memungkinkan aplikasi Anda untuk mengautentikasi dengan layanan Azure Spatial Anchors. Tujuan yang dimaksudkan dari Kunci Akun adalah untuk membantu Anda memulai dengan cepat. Terutama selama fase pengembangan integrasi aplikasi Anda dengan Azure Spatial Anchors. Dengan demikian, Anda dapat menggunakan Kunci Akun dengan menyematkannya di aplikasi klien Anda selama pengembangan. Saat Anda maju di luar pengembangan, sangat disarankan untuk pindah ke mekanisme autentikasi tingkat produksi, didukung oleh Token Akses, atau autentikasi pengguna Microsoft Entra. Untuk mendapatkan Kunci Akun untuk pengembangan, kunjungi akun Azure Spatial Anchors Anda, dan navigasikan ke tab "Kunci".

Pelajari selengkapnya tentang kelas SessionConfiguration.

    this.cloudSession.Configuration.AccountKey = @"MyAccountKey";

Token Akses

Token Akses adalah metode yang lebih kuat untuk mengautentikasi dengan Spatial Anchors Azure. Terutama saat Anda menyiapkan aplikasi Anda untuk penyebaran produksi. Ringkasan pendekatan ini adalah untuk menyiapkan layanan ujung belakang yang dapat diautentikasi dengan aman oleh aplikasi klien Anda. Antarmuka layanan ujung belakang Anda dengan AAD pada runtime dan dengan Layanan Token Aman Spatial Anchors Azure untuk meminta Token Akses. Token ini kemudian dikirim ke aplikasi klien dan digunakan dalam SDK untuk mengautentikasi dengan Spatial Anchors Azure.

    this.cloudSession.Configuration.AccessToken = @"MyAccessToken";

Jika token akses belum diatur, Anda harus menangani kejadian TokenRequired, atau menerapkan metode tokenRequired pada protokol delegasi.

Anda dapat menangani kejadian secara sinkron dengan mengatur properti pada argumen kejadian.

Pelajari selengkapnya tentang delegasi TokenRequiredDelegate.

    this.cloudSession.TokenRequired += (object sender, TokenRequiredEventArgs args) =>
    {
        args.AccessToken = @"MyAccessToken";
    };

Jika Anda harus menjalankan tugas asinkron di handler, Anda dapat menunda pengaturan token dengan meminta obhek deferral, lalu menyelesaikannya, seperti dalam contoh berikut.

    this.cloudSession.TokenRequired += async (object sender, TokenRequiredEventArgs args) =>
    {
        var deferral = args.GetDeferral();
        string myToken = await MyGetTokenAsync();
        if (myToken != null) args.AccessToken = myToken;
        deferral.Complete();
    };

Autentikasi Microsoft Entra

Azure Spatial Anchors juga memungkinkan aplikasi untuk mengautentikasi dengan token ID Microsoft Entra (Direktori Aktif) pengguna. Misalnya, Anda dapat menggunakan token Microsoft Entra untuk berintegrasi dengan Azure Spatial Anchors. Jika Enterprise mempertahankan pengguna di ID Microsoft Entra, Anda dapat menyediakan token Microsoft Entra pengguna di Azure Spatial Anchors SDK. Melakukannya memungkinkan Anda mengautentikasi langsung ke layanan Azure Spatial Anchors untuk akun yang merupakan bagian dari penyewa Microsoft Entra yang sama.

    this.cloudSession.Configuration.AuthenticationToken = @"MyAuthenticationToken";

Seperti token akses, jika token Microsoft Entra tidak diatur, Anda harus menangani peristiwa TokenRequired, atau menerapkan metode tokenRequired pada protokol delegasi.

Anda dapat menangani kejadian secara sinkron dengan mengatur properti pada argumen kejadian.

    this.cloudSession.TokenRequired += (object sender, TokenRequiredEventArgs args) =>
    {
        args.AuthenticationToken = @"MyAuthenticationToken";
    };

Jika Anda harus menjalankan tugas asinkron di handler, Anda dapat menunda pengaturan token dengan meminta obhek deferral, lalu menyelesaikannya, seperti dalam contoh berikut.

    this.cloudSession.TokenRequired += async (object sender, TokenRequiredEventArgs args) =>
    {
        var deferral = args.GetDeferral();
        string myToken = await MyGetTokenAsync();
        if (myToken != null) args.AuthenticationToken = myToken;
        deferral.Complete();
    };

Menyiapkan sesi

Panggil Start() untuk mengaktifkan sesi Anda guna memproses data lingkungan.

Untuk menangani kejadian yang ditimbulkan oleh sesi Anda, pasang handler kejadian.

Pelajari selengkapnya tentang metode Mulai.

#if UNITY_ANDROID || UNITY_IOS
    this.cloudSession.Session = aRSession.subsystem.nativePtr.GetPlatformPointer();
#elif UNITY_WSA || WINDOWS_UWP
    // No need to set a native session pointer for HoloLens.
#else
    throw new NotSupportedException("The platform is not supported.");
#endif

    this.cloudSession.Start();

Menyediakan bingkai ke sesi

Sesi jangkar spasial bekerja dengan memetakan ruang di sekitar pengguna. Melakukannya membantu menentukan lokasi jangkar. Platform seluler (iOS & Android) memerlukan panggilan asli ke umpan kamera untuk mendapatkan bingkai dari pustaka AR platform Anda. Sebaliknya, HoloLens terus memindai lingkungan, jadi, tidak memerlukan panggilan tertentu seperti pada platform seluler.

Pelajari selengkapnya tentang metode ProcessFrame.

#if UNITY_ANDROID || UNITY_IOS
    XRCameraFrame xRCameraFrame;
    if (aRCameraManager.subsystem.TryGetLatestFrame(cameraParams, out xRCameraFrame))
    {
        long latestFrameTimeStamp = xRCameraFrame.timestampNs;

        bool newFrameToProcess = latestFrameTimeStamp > lastFrameProcessedTimeStamp;

        if (newFrameToProcess)
        {
            session.ProcessFrame(xRCameraFrame.nativePtr.GetPlatformPointer());
            lastFrameProcessedTimeStamp = latestFrameTimeStamp;
        }
    }
#endif

Memberikan umpan balik kepada pengguna

Anda dapat menulis kode untuk menangani kejadian yang diperbarui sesi. Kejadian ini terjadi setiap kali sesi meningkatkan pemahamannya tentang lingkungan Anda. Dengan melakukannya, memungkinkan Anda:

  • Menggunakan kelas UserFeedback untuk memberikan umpan balik kepada pengguna saat perangkat bergerak dan sesi memperbarui pemahaman lingkungannya. Untuk melakukan ini,
  • Tentukan pada titik apa data spasial yang dilacak tersedia cukup untuk membuat jangkar spasial. Anda menentukan ini dengan ReadyForCreateProgress atau RecommendedForCreateProgress. Setelah ReadyForCreateProgress di atas 1, kita memiliki cukup data untuk menyimpan jangkar spasial cloud, meskipun kami menyarankan Anda menunggu hingga RecommendedForCreateProgress di atas 1 untuk melakukannya.

Pelajari selengkapnya tentang delegasi SessionUpdatedDelegate.

    this.cloudSession.SessionUpdated += (object sender, SessionUpdatedEventArgs args) =>
    {
        var status = args.Status;
        if (status.UserFeedback == SessionUserFeedback.None) return;
        this.feedback = $"Feedback: {Enum.GetName(typeof(SessionUserFeedback), status.UserFeedback)} -" +
            $" Recommend Create={status.RecommendedForCreateProgress: 0.#%}";
    };

Menemukan jangkar spasial cloud

Untuk membuat jangkar spasial cloud, Anda pertama-tama membuat jangkar di sistem AR platform, lalu membuat mitra cloud. Anda menggunakan metode CreateAnchorAsync().

Pelajari selengkapnya tentang kelas CloudSpatialAnchor.

    // Create a local anchor, perhaps by hit-testing and spawning an object within the scene
    Vector3 hitPosition = new Vector3();
#if UNITY_ANDROID || UNITY_IOS
    Vector2 screenCenter = new Vector2(0.5f, 0.5f);
    List<ARRaycastHit> aRRaycastHits = new List<ARRaycastHit>();
    if(arRaycastManager.Raycast(screenCenter, aRRaycastHits) && aRRaycastHits.Count > 0)
    {
        ARRaycastHit hit = aRRaycastHits[0];
        hitPosition = hit.pose.position;
    }
#elif WINDOWS_UWP || UNITY_WSA
    RaycastHit hit;
    if (this.TryGazeHitTest(out hit))
    {
        hitPosition = hit.point;
    }
#endif

    Quaternion rotation = Quaternion.AngleAxis(0, Vector3.up);
    this.localAnchor = GameObject.Instantiate(/* some prefab */, hitPosition, rotation);
    this.localAnchor.AddComponent<CloudNativeAnchor>();

    // If the user is placing some application content in their environment,
    // you might show content at this anchor for a while, then save when
    // the user confirms placement.
    CloudNativeAnchor cloudNativeAnchor = this.localAnchor.GetComponent<CloudNativeAnchor>();
    if (cloudNativeAnchor.CloudAnchor == null) { await cloudNativeAnchor.NativeToCloud(); }  
    CloudSpatialAnchor cloudAnchor = cloudNativeAnchor.CloudAnchor;
    await this.cloudSession.CreateAnchorAsync(cloudAnchor);
    this.feedback = $"Created a cloud anchor with ID={cloudAnchor.Identifier}");

Seperti yang dijelaskan sebelumnya, Anda memerlukan data lingkungan yang memadai yang diambil sebelum mencoba membuat jangkar spasial cloud baru. Artinya ReadyForCreateProgress harus di atas 1, meskipun kami sarankan Anda menunggu sampai RecommendedForCreateProgress di atas 1 untuk melakukannya.

Pelajari selengkapnya tentang metode GetSessionStatusAsync.

    SessionStatus value = await this.cloudSession.GetSessionStatusAsync();
    if (value.RecommendedForCreateProgress < 1.0f) return;
    // Issue the creation request ...

Mengatur properti

Anda dapat memilih untuk menambahkan beberapa properti saat menyimpan jangkar spasial cloud Anda. Seperti jenis objek yang disimpan, atau properti dasar seperti apakah ini harus diaktifkan untuk interaksi. Melakukannya dapat berguna setelah penemuan: Anda dapat segera merender objek untuk pengguna, misalnya bingkai gambar dengan konten kosong. Selanjutnya, unduhan yang berbeda di latar belakang mendapatkan detail status tambahan, misalnya, gambar untuk ditampilkan dalam bingkai.

Pelajari selengkapnya tentang properti AppProperties.

    CloudSpatialAnchor cloudAnchor = new CloudSpatialAnchor() { LocalAnchor = localAnchor };
    cloudAnchor.AppProperties[@"model-type"] = @"frame";
    cloudAnchor.AppProperties[@"label"] = @"my latest picture";
    await this.cloudSession.CreateAnchorAsync(cloudAnchor);

Memperbarui properti

Untuk memperbarui properti pada jangkar, Anda menggunakan metode UpdateAnchorProperties(). Jika dua atau lebih perangkat mencoba memperbarui properti untuk jangkar yang sama pada saat yang sama, kita menggunakan model konkurensi optimis. Yang berarti tulisan pertama akan menang. Semua tulisan lainnya akan mendapatkan kesalahan "Konkurensi": refresh properti akan diperlukan sebelum mencoba lagi.

Pelajari selengkapnya tentang metode UpdateAnchorPropertiesAsync.

    CloudSpatialAnchor anchor = /* locate your anchor */;
    anchor.AppProperties[@"last-user-access"] = @"just now";
    await this.cloudSession.UpdateAnchorPropertiesAsync(anchor);

Anda tidak dapat memperbarui lokasi jangkar setelah dibuat di layanan - Anda harus membuat jangkar baru dan menghapus yang lama untuk melacak posisi baru.

Jika Anda tidak perlu menemukan jangkar untuk memperbarui propertinya, Anda dapat menggunakan metode GetAnchorPropertiesAsync(), yang mengembalikan objek CloudSpatialAnchor dengan properti.

Pelajari selengkapnya tentang metode GetAnchorPropertiesAsync.

    var anchor = await cloudSession.GetAnchorPropertiesAsync(@"anchorId");
    if (anchor != null)
    {
        anchor.AppProperties[@"last-user-access"] = @"just now";
        await this.cloudSession.UpdateAnchorPropertiesAsync(anchor);
    }

Mengatur tanggal kedaluwarsa

Anda juga dapat mengonfigurasi masa berakhir jangkar secara otomatis pada tanggal tertentu di masa mendatang. Ketika jangkar berakhir, jangkar tidak akan lagi ditemukan atau diperbarui. Waktu kedaluwarsa hanya dapat diatur ketika jangkar dibuat sebelum menyimpannya ke cloud. Tidak mungkin memperbarui kedaluwarsa setelahnya. Jika tidak ada waktu kedaluwarsa yang diatur saat pembuatan jangkar, jangkar hanya akan kedaluwarsa saat dihapus secara manual.

Pelajari selengkapnya tentang properti Kedaluwarsa.

    cloudAnchor.Expiration = DateTimeOffset.Now.AddDays(7);

Menemukan jangkar spasial cloud

Mampu menemukan jangkar spasial cloud yang disimpan sebelumnya adalah salah satu alasan utama untuk menggunakan Azure Spatial Anchors. Untuk ini, kami menggunakan "Watchers". Anda hanya dapat menggunakan satu Watcher pada satu waktu; beberapa Pengamat tidak didukung. Ada beberapa cara berbeda (juga dikenal sebagai Jangkar Temukan Strategi) Pengamat dapat menemukan jangkar spasial cloud. Anda dapat menggunakan satu strategi pada watcher pada satu waktu.

  • Cari jangkar dengan pengidentifikasi.
  • Temukan jangkar yang terhubung ke jangkar yang telah ditemukan sebelumnya. Anda dapat belajar tentang hubungan jangkar di sini.
  • Cari jangkar menggunakan relokasi Kasar.

Catatan

Setiap kali Anda menemukan jangkar, Azure Spatial Anchors akan mencoba menggunakan data lingkungan yang dikumpulkan untuk menambah informasi visual pada jangkar. Jika Anda mengalami kesulitan menemukan jangkar, perlu untuk membuat jangkar, lalu temukan beberapa kali dari sudut dan kondisi pencahayaan yang berbeda.

Jika Anda menemukan jangkar spasial cloud dengan pengidentifikasi, Anda dapat menyimpan pengidentifikasi jangkar spasial cloud di layanan back-end aplikasi Anda, dan membuatnya dapat diakses oleh semua perangkat yang dapat mengautentikasinya dengan benar. Untuk contoh ini, lihat Tutorial: Berbagi Spatial Anchors di seluruh perangkat.

Mencontohkan objek AnchorLocateCriteria, atur pengidentifikasi yang Anda cari, dan gunakan metode CreateWatcher pada sesi tersebut dengan menyediakan AnchorLocateCriteria Anda.

Pelajari selengkapnya tentang metode CreateWatcher.

    AnchorLocateCriteria criteria = new AnchorLocateCriteria();
    criteria.Identifiers = new string[] { @"id1", @"id2", @"id3" };
    this.cloudSession.CreateWatcher(criteria);

Setelah watcher Anda dibuat, acara akan AnchorLocated menembak untuk setiap jangkar yang diminta. Peristiwa ini terjadi ketika jangkar berada, atau jika jangkar tidak dapat ditemukan. Jika situasi ini terjadi, alasannya akan dinyatakan dalam status tersebut. Setelah semua jangkar untuk pengamat diproses, ditemukan atau tidak ditemukan, maka peristiwa LocateAnchorsCompleted itu akan menembak. Ada batas 35 pengidentifikasi per pengamat.

Pelajari selengkapnya tentang delegasi AnchorLocatedDelegate.

    this.cloudSession.AnchorLocated += (object sender, AnchorLocatedEventArgs args) =>
    {
        switch (args.Status)
        {
            case LocateAnchorStatus.Located:
                CloudSpatialAnchor foundAnchor = args.Anchor;
                // Go add your anchor to the scene...
                break;
            case LocateAnchorStatus.AlreadyTracked:
                // This anchor has already been reported and is being tracked
                break;
            case LocateAnchorStatus.NotLocatedAnchorDoesNotExist:
                // The anchor was deleted or never existed in the first place
                // Drop it, or show UI to ask user to anchor the content anew
                break;
            case LocateAnchorStatus.NotLocated:
                // The anchor hasn't been found given the location data
                // The user might in the wrong location, or maybe more data will help
                // Show UI to tell user to keep looking around
                break;
        }
    }

Hapus jangkar

Menghapus jangkar ketika tidak lagi digunakan adalah praktik yang baik untuk disertakan sejak dini dalam proses dan praktik pengembangan Anda, untuk menjaga kebersihan sumber daya Azure Anda.

Pelajari selengkapnya tentang metode DeleteAnchorAsync.

    await this.cloudSession.DeleteAnchorAsync(cloudAnchor);
    // Perform any processing you may want when delete finishes

Menghapus jangkar tanpa menemukan

Jika Anda tidak dapat menemukan jangkar tetapi masih ingin menghapusnya, Anda dapat menggunakan GetAnchorPropertiesAsync API yang mengambil anchorId sebagai input untuk mendapatkan CloudSpatialAnchor objek. Anda kemudian dapat meneruskan objek ini ke untuk DeleteAnchorAsync menghapusnya.

var anchor = await cloudSession.GetAnchorPropertiesAsync(@"anchorId");
await this.cloudSession.DeleteAnchorAsync(anchor);

Menjeda, menyetel ulang, atau menghentikan sesi

Untuk menghentikan sesi sementara, Anda dapat memanggil Stop(). Tindakan ini akan menghentikan setiap pengamat dan pemrosesan lingkungan, bahkan jika Anda memanggil ProcessFrame(). Anda selanjutnya dapat memanggil Start() untuk melanjutkan pemrosesan. Ketika melanjutkan, data lingkungan yang sudah diambil dalam sesi akan dipertahankan.

Pelajari selengkapnya tentang metode Berhenti.

    this.cloudSession.Stop();

Untuk menyetel ulang data lingkungan yang telah diambil dalam sesi Anda, Anda dapat memanggil Reset().

Pelajari selengkapnya tentang metode Reset.

    this.cloudSession.Reset();

Untuk membersihkan dengan benar setelah sesi, panggil Dispose().

Pelajari selengkapnya tentang metode Buang.

    this.cloudSession.Dispose();

Langkah berikutnya

Dalam panduan ini, Anda belajar tentang cara membuat dan menemukan jangkar menggunakan Azure Spatial Anchors SDK. Untuk mempelajari lebih lanjut tentang hubungan jangkar, lanjutkan ke panduan berikutnya.