共用方式為


Unity 中的 QR 代碼

HoloLens 2 頭戴式裝置可以追蹤及偵測可用來提供全像投影和其他 AR 功能的 QR 代碼。 本文會引導您完成在 Unity 應用程式中開始使用 QR 代碼所需的一切,包括:

  • 將 QR 代碼偵測新增至 Unity 應用程式。
  • 瞭解您需要使用的重要概念和 Unity 元件。
  • 提供涵蓋常見 QR 代碼使用方式的教學課程。
  • 介紹 AR 標記範例案例,示範已啟用 QR 代碼的場景和範例腳本。

在繼續本文之前,建議您先流覽 QR 代碼概觀

追蹤的 QR 代碼

設定 Unity 專案和應用程式

您的 Unity 專案和應用程式必須正確設定並設定,才能啟用 QR 代碼功能,這需要:

  • 適用於 Windows Mixed Reality 113.2403.5001 或更新版本的 OpenXR。

    注意

    這隨附於操作系統,並可透過 Windows 市集進行更新。 請注意,使用者可能已安裝舊版,且其裝置將無法使用AR標記,例如QR代碼,直到更新至113.2403.5001版或更新版本為止。

  • 與支援的 Unity 版本相容的專案:
    • Unity 2022.3 LTS (建議)
    • Unity 2021.3 LTS
  • 混合實境 OpenXR 外掛程式。
  • 為您的 Unity 專案啟用網路攝影機功能。
  • 授與應用程式的相機許可權。

下列各節將引導您瞭解如何設定 Unity 專案和應用程式,以啟用 QR 代碼偵測。

取得混合實境 OpenXR 外掛程式

混合實境 OpenXR 外掛程式套件包含可用來存取 QR 代碼功能的 C# API

若要匯入套件:

  1. 下載 並執行混合實境功能工具。
  2. 安裝 OpenXR 外掛程式。

混合實境功能工具也可簡化套件管理,並可用來尋找、更新及新增應用程式所需的混合實境功能。 如需如何使用此工具的詳細指示,請參閱 歡迎使用混合實境功能工具

啟用 WebCam 功能

若要偵測和追蹤 QR 代碼,您的 Unity 專案必須 啟用 WebCam 功能。

若要啟用 WebCam 功能:

  1. 開啟 Unity 專案。
  2. 按兩下 Unity 編輯器應用程式選單中的 [編輯 ]。
  3. 移至 [項目設定 > 播放機 ],然後選取 [UWP ] 索引標籤,如下所示: UWP 索引標籤設定
  4. 在 [功能] 列表中啟用 WebCam已啟用 WebCam 功能
  5. 結束 項目設定

您的 Unity 應用程式現在已啟用 WebCam 功能。 不過,您的應用程式仍必須獲得存取裝置相機的許可權。

授與您的應用程式相機訪問許可權

如果您的應用程式 已啟用 WebCam 功能,[許可權] 對話方塊會提示使用者將裝置相機的存取權授與您的應用程式。

相機許可權對話框

此對話框只會向用戶顯示一次,通常是在輸入包含ARMarkerManager已啟用 QR 代碼標記支援的場景時。 如果拒絕相機存取,使用者可以移至 [ 設定 > 應用程式 ],並透過應用程式的 [進階選項] 加以啟用。

已啟用許可權的應用程式進階選項

將 QR 代碼偵測建置至場景

QR 代碼偵測必須內建於您想要在其中使用 QR 代碼的每個場景,這需要:

建立 QR 代碼的預製專案

若要在場景中使用 QR 代碼,您必須建立 QR 代碼的預製專案。 ARMarkerManager 使用此預製專案,在偵測到 QR 代碼時從 建立 GameObject

若要製作 QR 代碼的預製專案:

  1. 為您的專案建立新的預製專案
  2. ARMarker元件新增至 prefab,位於 Script > Microsoft.MixedReality.OpenXR > ARMarker 底下
    新增 ARMarker 元件

您現在有要使用的基本預製專案。 您可能想要讓應用程式以可視化方式呈現環境中偵測到的 QR 代碼。 下一節將逐步引導您新增 QR 代碼的視覺表示法。

新增視覺效果

在上一節中,新增 ARMarker至預製專案也會自動新增 ARMarkerScale 元件。 此元件用來比對 QR 代碼視覺表示法與其實體對應項目的規模。

若要這麼做︰

  1. 將空白 GameObject 新增至您在上一節中建立的預製專案。 它會代表所有視覺 標記內容
  2. 將子 3D GameObject,例如 Quad,新增至標記內容 GameObject將 3D GameObject 新增至 ARMarker 預製專案
  3. 在預製項目元件中ARMarkerScale,將 [標記尺規轉換] 設定為標記內容 GameObject。 設定此欄位可確保您選擇的 3D GameObject 已正確調整,以符合真實世界的 QR 代碼。

新增 ARMarkerManager 至場景

ARMarkerManager 只負責建立、更新和移除每個 GameObject 偵測到的 QR 代碼。

若要新增 ARMarkerManager 至您的場景:

  1. 將 放入 GameObject 您的場景。
  2. ARMarkerManager元件新增至 GameObject位於 Script > Microsoft.MixedReality.OpenXR > ARMarkerManager 底下的
    新增ARMarkerManager元件
  3. 將 [ARMarkerManager標記預製專案] 字段設定為您在上一節中建立的預製專案。 標記預製欄位集
  4. 展開 [啟用標記類型],然後選擇元素,並將其設定為 QR代碼已啟用 QR 代碼標記類型

追蹤 QR 代碼變更

ARMarkerManager 包含 markersChanged 提供給訂閱者的事件 ARMarkersChangedEventArgs 。 使用這些事件自變數來追蹤從偵測或更新的姿勢數據新增或移除的 QR 代碼。

下列程式代碼示範訂閱 ARMarkerManager.markersChanged 事件,使用其事件自變數逐一查看 ARMarker 物件 ARMarkerManager 正在處理並寫入偵錯,無論它們是否已新增、移除或更新。

using System;
using Microsoft.MixedReality.OpenXR;

// ...

private void Awake()
{
    m_arMarkerManager = GetComponent<ARMarkerManager>();
    m_arMarkerManager.markersChanged += OnQRCodesChanged;
}

void OnQRCodesChanged(ARMarkersChangedEventArgs args)
{
    foreach (ARMarker qrCode in args.added)
        Debug.Log($"QR code with the ID {qrCode.trackableId} added.");

    foreach (ARMarker qrCode in args.removed)
        Debug.Log($"QR code with the ID {qrCode.trackableId} removed.");

    foreach (ARMarker qrCode in args.updated)
    {
        Debug.Log($"QR code with the ID {qrCode.trackableId} updated.");
        Debug.Log($"Pos:{qrCode.transform.position} Rot:{qrCode.transform.rotation} Size:{qrCode.size}");
    }
}

取得上次偵測到 QR 代碼的時間

ARMarker.lastSeenTime使用 屬性來判斷裝置上次追蹤到的 QR 代碼的時間,以及遺失追蹤的時間量。 時間是以 Unity 啟動您的應用程式以來的秒數來測量,類似於 UnityEngine.Time.realtimeSinceStartup

使用 QR 代碼的可追蹤識別碼

QR 代碼是 可追蹤的,這是AR裝置可在實體環境中偵測和追蹤的任何專案。 可追蹤專案衍生自提供標識碼、追蹤狀態、姿勢和其他數據的型 ARTrackable<TSessionRelativeData, TTrackable> 別。

QR 代碼的可追蹤識別碼可以傳遞至 ARMarkerManager 方法來取得 QR 代碼的屬性、原始位元組資料和字串表示,以及設定 QR 代碼的轉換模式。 這些方法可讓您擷取 QR 代碼的數據,而不需要保留 ARMarker 對象參考。

您可以將 QR 代碼的識別碼傳遞至下列 ARMarkerManager 方法:

注意

GetRawData對於方法參數 allocator,傳遞Unity.Collections.Allocator.Temp對大部分案例而言就已足夠。

遵循 QR 代碼的追蹤狀態

ARMarker因為 是可追蹤的,所以它會繼承 屬性,trackingState並且設定為三UnityEngine.XR.ARSubsystems.TrackingState個的其中一個:

  • Limited:表示正在追蹤 QR 代碼,但有有限的資訊可用或品質不佳。
  • Tracking:指定正在完整追蹤 QR 代碼。
  • None:表示未追蹤 QR 代碼。

若要監視 QR 代碼的追蹤狀態,請 ARMarkerManager.markersChanged 訂閱 ,並逐一查看 ARMarker 傳遞至事件處理程式的事件自變數中所提供的標記集合。

下列程式代碼示範如何使用 ARMarkerManager.markersChanged 事件逐一查看 ARMarker 新偵測到 QR 代碼的物件,並將其可追蹤標識碼寫入 [偵錯] 視窗。

using System;
using Microsoft.MixedReality.OpenXR;

// ...

private void Awake()
{
    m_arMarkerManager = GetComponent<ARMarkerManager>();
    m_arMarkerManager.markersChanged += OnQRCodesChanged;
}

void OnQRCodesChanged(ARMarkersChangedEventArgs args)
{
    foreach (ARMarker qrCode in args.added)
    {
       if (qrCode.trackingState == UnityEngine.XR.ARSubsystems.TrackingState.Tracking)
           Debug.Log($"Fully tracked QR code with the ID {qrCode.trackableId} was added.");
    }
}

取得 QR 代碼的版本和 QR 代碼類型

若要取得偵測到 QR 代碼的版本和類型:

  1. 呼叫 ARMarker.GetQRCodeProperties()會傳回 實例的 QRCodeProperties
  2. 存取傳回值中的欄位 QRCodeProperties ,以取得 QR 代碼的類型。 值為 QRCodeType.QRCodeQRCodeType.MicroQRCode
  3. 存取傳回值欄位 QRCodeProperties.version 以取得 QR 代碼的版本。 如果類型為 ,則此值的範圍從 1 到 40,如果類型為 QRCodeType.QRCodeQRCodeType.MicroQRCode,則從 1 到 4。

或者,傳遞 ARMarker 物件的可追蹤標識碼, ARMarkerManager.GetQRCodeProperties(TrackableId) 以取得 QR 代碼的類型和版本。

警告

QR 代碼是目前唯一支援的標記類型,不過未來版本中可能會新增其他標記類型的支援。 如果 markerType 不是 ARMarkerType.QRCode,則呼叫 GetQRCodeProperties(TrackableId)System.InvalidOperationException擲回 。 如果這可能會在稍後於您的應用程式中造成問題,請考慮將呼叫 GetQRCodeProperties(TrackableId) 包裝在 try-catch 區塊中。

讀取 QR 數據

元件ARMarker會附加至每個GameObjectARMarkerManager建立的元件。 ARMarker 提供兩個傳回 QR 代碼資料的方法:

下列程式代碼示範 和GetRawData(Unity.Collections.Allocator allocator)的基本用法GetDecodedString()

using System;
using Microsoft.MixedReality.OpenXR;

// ...

void OnQRCodesChanged(ARMarkersChangedEventArgs args)
{
    foreach (ARMarker qrCode in args.added)
    {
        var text = qrCode.GetDecodedString();
        Debug.Log($"QR code text: {text}");

        var bytes = qrCode.GetRawData(Unity.Collections.Allocator.Temp);
        Debug.Log($"QR code bytes: {bytes.Length}");
        bytes.Dispose();
    }
}

取得 QR 代碼大小、位置、旋轉和置中

ARMarker物件會提供它所代表 QR 代碼的大小、位置、旋轉和中心。

若要取得以公尺為單位的 QR 代碼大小,請使用 屬性 ARMarker.size

ARMarker.transform使用 屬性可取得 QR 代碼轉換的旋轉和世界空間位置,以及 ARMarker.center QR 代碼的 2D 座標,相對於 QR 代碼的轉換。 轉換本身會根據 ARMarker.transformMode [轉換模式] 設定TransformMode.MostStable為 (最穩定、QR 代碼的左上方) 或 TransformMode.Center中,QR 代碼的幾何中心) 來置中。

ARMarkerManager.defaultTransformMode使用欄位來設定轉換模式ARMarkerManager會使用 建立新的 ARMarker 物件。 欄位會 Default Transform Mode 使用 字段初始化,在 Unity Inspector 中設定為 ,如下所示:

ARMarkerManager 元件的默認轉換模式偵測器字段

若要替代使用 ARMarker.transformMode,請將物件的可追蹤標識元傳遞 ARMarker 至 以 ARMarkerManager.SetTransformMode(TrackableId, TransformMode) 設定其轉換模式。

下列程式代碼示範如何取得新的 QR 代碼大小和中心、其轉換的位置和旋轉,以及變更轉換模式之後更新的轉換位置。

using System;
using Microsoft.MixedReality.OpenXR;

// ...

void OnMarkersChanged(ARMarkersChangedEventArgs args)
{
    Debug.Log($"Default transform mode is {ARMarkerManager.Instance.defaultTransformMode}./n");

    if (e.added.Count > 0)
    {
        ARMarker qrCode = args.added[0];

        Debug.Log($"Position: {qrCode.transform.position}");
        Debug.Log($"Rotation: {qrCode.transform.rotation}");
        Debug.Log($"Center: {qrCode.center}");

        if (qrCode.transformMode == TransformMode.Center)
            qrCode.transformMode = TransformMode.MostStable;
        else
            qrCode.transformMode = TransformMode.Center;

        Debug.Log($"QR code's transform mode is now set to {qrCode.transformMode}. /n");
        Debug.Log($"New position: {qrCode.transform.position}");
    }
}

AR 標記範例案例

OpenXR 外掛程式套件所提供的範例包含已啟用 QR 代碼的場景,提供如何使用 ARMarkerManagerARMarker 的範例。

場景位於 Assets > ARMarker 中 ,如下所示: ARMarker 場景資產位置

您可以在 GitHub 上的 OpenXR Unity 混合實境範例存放庫中找到場景中使用的 C# 腳本:/OpenXR-Unity-MixedReality-Samples/tree/main/SampleScenarios/Scenarios/MarkerSample/Scripts

另請參閱