Unity の QR コード

HoloLens 2 ヘッドセットは、ホログラムやその他の AR 機能を提供するために使用できる QR コードを追跡および検出できます。 この記事では、Unity アプリで QR コードの使用を開始するために知っておくべきすべての手順について説明します。これには、次のものが含まれます。

  • Unity アプリに QR コード検出を追加する。
  • 使用する必要がある重要な概念と Unity コンポーネントについて説明します。
  • 一般的な QR コードの使用方法に関するチュートリアルを提供します。
  • QR コード対応のシーンとサンプル スクリプトを示す AR マーカーのサンプル シナリオ について説明します。

この記事に進む前に、 QR コードの概要を確認することをお勧めします

追跡された QR コード

Unity プロジェクトとアプリの構成

QR コード機能を有効にするには、Unity プロジェクトとアプリを適切に設定して構成する必要があります。これには、次のものが必要です。

  • OpenXR for Windows Mixed Reality バージョン 113.2403.5001 以降。

    Note

    これは OS に付属しており、Windows ストアを通じて更新できます。 ユーザーは以前のバージョンがインストールされている可能性があり、デバイスはバージョン 113.2403.5001 以降に更新されるまで QR コードなどの AR マーカーを使用できません。

  • サポートされているバージョンの Unity と互換性のあるプロジェクト:
    • Unity 2022.3 LTS (推奨)
    • Unity 2021.3 LTS
  • Mixed Reality OpenXR プラグイン。
  • Unity プロジェクトで Web カメラ機能が有効になっています。
  • アプリに付与されたカメラのアクセス許可。

以下のセクションでは、QR コード検出を有効にするように Unity プロジェクトとアプリを構成する方法について説明します。

Mixed Reality OpenXR プラグインの取得

Mixed Reality OpenXR Plugin パッケージには、QR コード機能にアクセスするために使用できる C# API が含まれています。

パッケージをインポートするには、次のようにします。

  1. Mixed Reality Feature Tool をダウンロード 実行します。
  2. OpenXR プラグインをインストール します。

Mixed Reality 機能ツールを使用すると、パッケージ管理も簡素化され、アプリで必要な Mixed Reality 機能を検索、更新、追加するために使用できます。 ツールの使用方法の詳細については、「 Mixed Reality Feature Tool に関する記事を参照してください。

WebCam 機能の有効化

QR コードを検出して追跡するには、Unity プロジェクトで WebCam 機能が有効になっている必要があります。

WebCam機能を有効にするには:

  1. Unity プロジェクトを開きます。
  2. Unity エディターのアプリ メニューで Edit をクリックします。
  3. Project Settings > Player に移動し次のように UWP タブを選択します。UWP タブの設定
  4. Capabilities リストで WebCam を有効にします。 有効な WebCam 機能
  5. プロジェクト設定を終了します。

Unity アプリで WebCam 機能が有効になりました。 ただし、デバイス カメラにアクセスするためのアクセス許可がアプリに付与されている必要があります。

アプリ カメラへのアクセス許可の付与

アプリで WebCam 機能が有効になっている場合、アクセス許可ダイアログでは、デバイス カメラへのアクセス権をアプリに付与するようにユーザーに求められます。

[カメラの権限] ダイアログ

このダイアログボックスは、通常、QR コード マーカーがサポートされている ARMarkerManager を含むシーンを入力する場合 有効に 1 回だけ表示されます。 カメラ アクセスが拒否された場合、ユーザーは Settings > Apps に移動し アプリの Advanced Options を使用して有効にすることができます。

アクセス許可が有効になっているアプリの詳細オプション

QR コード検出をシーンに組み込む

QR コード検出は、QR コードを使用するすべてのシーンに組み込む必要があります。これには次のものが必要です。

  • ARMarkerManagerがアタッチされたGameObjectARMarkerManager は、検出された QR コードのすべての GameObject を作成、更新、および削除する責任を負います。
  • ARMarkerがアタッチされたプレハブ。
  • ARMarkerManager QR コードが検出されたときに GameObject を作成するときにプレハブを使用するように構成されています。

QR コード用のプレハブの作成

シーンで QR コードを使用するには、QR コード用のプレハブを作成する必要があります。 ARMarkerManager は、このプレハブを使用して、QR コードが検出されるたびに GameObject を作成します。

QR コードのプレハブを作成するには:

  1. プロジェクトの新しいプレハブ を作成します。
  2. ARMarkerコンポーネントをプレハブに追加します。このコンポーネントは、microsoft.MixedReality.OpenXR > ARMarker > Script の下にあります
    ARMarker コンポーネントの追加

これで、使用する基本的なプレハブが作成されました。 多くの場合、環境内で検出された QR コードをアプリで視覚的に表す必要があります。 次のセクションでは、QR コードの視覚的表現を追加する方法について説明します。

ビジュアルの追加

前のセクションでは、プレハブに ARMarkerを追加すると、 ARMarkerScale コンポーネントも自動的に追加されました。 このコンポーネントは、QR コードの視覚的表現のスケールを、対応する物理的な表現と一致させるために使用されます。

そのためには次のようにします。

  1. 前のセクションで作成したプレハブに空の GameObject を追加します。 すべてのビジュアル マーカー コンテンツを表します。
  2. マーカー コンテンツ GameObjectに、Quadなどの子 3D GameObjectを追加します。 ARMarker プレハブに 3D GameObject を追加する
  3. プレハブのARMarkerScale コンポーネントで、マーカー コンテンツ GameObjectMarker Scale Transform を設定します。 このフィールドを設定すると、選択した 3D GameObject が実際の QR コードと一致するように正しくスケーリングされます。

シーンに ARMarkerManager を追加する

ARMarkerManager は、検出された QR コードのすべての GameObject を作成、更新、および削除する責任を負います。

シーンに ARMarkerManager を追加するには:

  1. シーンに GameObject を配置します。
  2. ARMarkerManager コンポーネントを、Script > Microsoft.MixedReality.OpenXR > ARMarkerManager の下にあるGameObjectに追加します。
    ARMarkerManager コンポーネントの追加
  3. ARMarkerManager Marker Prefab フィールドを前のセクションで作成したプレハブに設定します。 マーカー プレハブ フィールド セット
  4. [ Enabled Marker Types を展開し、要素を選択し、 QR コードに設定しますQR コード マーカーの種類が有効

QR コードの変更を追跡する

ARMarkerManagerには、サブスクライバーにARMarkersChangedEventArgsを提供するmarkersChanged イベントが含まれています。 これらのイベント引数を使用して、検出または更新されたポーズ データに対して追加または削除される QR コードを追跡します。

次のコードは、ARMarkerManager.markersChanged イベントをサブスクライブし、そのイベント引数を使用して、追加、削除、または更新のどちらであるかに関係なく、処理および Debug への書き込みARMarkerManagerARMarker オブジェクトを反復処理する方法を示しています。

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 コードの追跡可能な ID の使用

QR コードは 追跡可能ですこれは、AR デバイスが物理環境で検出して追跡できるあらゆるものです。 追跡可能オブジェクトは、ID、追跡状態、ポーズ、およびその他のデータを提供する型 ARTrackable<TSessionRelativeData, TTrackable> から派生します。

QR コードの追跡可能な ID を ARMarkerManager メソッドに渡して、QR コードのプロパティ、生バイト データ、および文字列表現を取得し、QR コードの変換モードを設定できます。 これらのメソッドを使用すると、 ARMarker オブジェクト参照を保持することなく、QR コードのデータを取得できます。

QR コードの ID は、次の ARMarkerManager メソッドに渡すことができます。

Note

GetRawData メソッド パラメーターのallocatorでは、ほとんどのシナリオでUnity.Collections.Allocator.Tempを渡すことで十分です。

QR コードの追跡状態に従う

ARMarkerは追跡可能であるため、trackingState プロパティを継承し、次の 3 つのUnityEngine.XR.ARSubsystems.TrackingStateのいずれかに設定されます。

  • Limited: QR コードが追跡されているが、限られた情報が利用可能であるか、品質が低いかどうかを示します。
  • Tracking: QR コードが完全に追跡されていることを指定します。
  • None: QR コードが追跡されていないことを示します。

QR コードの追跡状態を監視するには、 ARMarkerManager.markersChanged をサブスクライブし、イベント ハンドラーに渡されたイベント引数で提供される ARMarker マーカー コレクションを反復処理します。

次のコードは、 ARMarkerManager.markersChanged イベントを使用して、新しく検出された QR コードの ARMarker オブジェクトを反復処理し、追跡可能な ID をデバッグ ウィンドウに書き込む方法を示しています。

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. QRCodeProperties インスタンスを返すARMarker.GetQRCodeProperties()を呼び出します。
  2. 戻り値のフィールド QRCodeProperties にアクセスして、QR コードの型を取得します。 値は QRCodeType.QRCode または QRCodeType.MicroQRCode です。
  3. 戻り値の QRCodeProperties.version フィールドにアクセスして、QR コードのバージョンを取得します。 型が QRCodeType.QRCodeの場合は 1 から 40、型が QRCodeType.MicroQRCodeの場合は 1 から 4 の範囲です。

別の方法として、 ARMarker オブジェクトの追跡可能な ID を ARMarkerManager.GetQRCodeProperties(TrackableId) に渡して、QR コードの種類とバージョンを取得します。

警告

QR コードは現在サポートされている唯一のマーカーの種類ですが、他のマーカーの種類のサポートは今後のリリースで追加される可能性があります。 markerTypeARMarkerType.QRCodeされていない場合、GetQRCodeProperties(TrackableId)を呼び出すとSystem.InvalidOperationExceptionがスローされます。 後でアプリで問題が発生する可能性がある場合は、try-catch ブロックで GetQRCodeProperties(TrackableId) の呼び出しをラップすることを検討してください。

QR データの読み取り

ARMarker コンポーネントは、ARMarkerManager作成されるすべてのGameObjectにアタッチされます。 ARMarker には、QR コード データを返す 2 つのメソッドが用意されています。

  • GetDecodedString():このメソッドは、URL などの QR コードの文字列表現を取得します。

  • GetRawData(Unity.Collections.Allocator allocator): このメソッドは QR コードの内容をバイト配列として返し、配列の割り当て方法を細かく調整できます。 このメソッドは、ホット パスや、パフォーマンスが重要なその他の状況で使用します。

次のコードは、 GetDecodedString()GetRawData(Unity.Collections.Allocator allocator)の基本的な使用方法を示しています。

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 コードの変換の回転位置とワールド空間位置を取得し、QR コードの変換に対する QR コードの 2D 座標にARMarker.centerします。 変換自体は、 ARMarker.transformMode ( transform モード) が TransformMode.MostStable ( 最も安定、QR コードの左上) または TransformMode.Center (center QR コードの幾何学的中心) に設定されているかどうかに応じて中央に配置されます。

ARMarkerManager.defaultTransformMode フィールドを使用して、新しいARMarker オブジェクトを作成ARMarkerManager変換モードを設定します。 このフィールドは、次のように Unity インスペクターで Default Transform Mode フィールドが設定されて初期化されます。

ARMarkerManager コンポーネントの既定の変換モードインスペクター フィールド

ARMarker.transformModeを使用する代わりに、ARMarker オブジェクトの追跡可能な ID を渡して、変換モードを設定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 プラグイン パッケージで提供されるサンプルには、 ARMarkerManagerARMarker を使用する方法の例を示す QR コード対応のシーンが含まれています。

次に示すように、シーンは Assets > ARMarker にあります。 ARMarker シーンアセットの場所

シーンで使用されている C# スクリプトは、GitHub の OpenXR Unity Mixed Reality Samples リポジトリにあります : /OpenXR-Unity-MixedReality-Samples/tree/main/SampleScenarios/Scenarios/MarkerSample/Scripts

関連項目