Blog
Unity × Meta Quest 3S — 現行実装に合わせた QR 検出と安定配置の実装ガイド
Published · Dec 2, 2025
Topics
Unity
Meta Quest
MR
QR
MRUK
OpenXR
Unity と Meta Quest 3S で QR コード検出を安定して扱うための実装ガイドです。MR Utility Kit(MRUK)に合わせた実装と運用上のポイントをまとめます。
更新日: 2026年1月(内容を現在の実装に合わせて更新)
対象読者: Unity MR 開発者(初級〜中級)
動作確認環境(参考):
- HMD: Meta Quest 3S
- Unity Editor: 6000.2.7f2
- Meta XR SDK: 81.0.0 (packages:
com.meta.xr.sdk.all,com.meta.xr.sdk.core) - MR Utility Kit (MRUK): 81.0.0 (
com.meta.xr.mrutilitykit) - Unity URP: 17.2.0 (
com.unity.render-pipelines.universal) - OpenXR: 1.16.0 (
com.unity.xr.openxr) - XR Management: 4.5.3 (
com.unity.xr.management) - Input System: 1.14.2 (
com.unity.inputsystem)
動作デモ
実際の実装による QR コードの検出と、オブジェクトの追従安定性を以下の動画で確認できます。
この記事でやること / やらないこと
- やること: MRUK の QR トラッキングを拾い、UUID をキーに「検出/更新/喪失」を安定して扱う
- やること: 瞬断やスパイクに耐えるために、喪失タイムアウトと IQR ベースの平滑化を入れる
- やらないこと: QR ペイロードの解析・認証や、アンカー永続化(Spatial Anchor 連携)の詳細実装
実装リポジトリ
本記事で説明している内容は、以下の Unity プロジェクトの現行実装に合わせて整理しています。
https://github.com/ttokunaga-ja/Group4_MoleWhack
目次
概要
Meta XR Utility Kit (MRUK) で QR コードを検出し、World 座標を安定して取得・利用するまでの実装をまとめました。
ポイントは「中央集約の QRManager」「喪失タイムアウト」「IQR(四分位範囲)を使ったスムージング」で、カメラ移動時のスパイクや瞬断に強い座標更新を実現しています。
システム構成
QRManager(Singleton)
- MRUK から
MRUKTrackableを取得し、UUID をキーにQRInfoを管理 - イベント:
OnQRAdded / OnQRUpdated / OnQRLost lostTimeoutを設け、一時的な見失いでは喪失扱いにしないenableDetailedLoggingやdetectionCooldownなどの設定が追加されています
- MRUK から
QRInfo
firstPose(初回検出時の Pose)とlastPose(最新の Pose)を保持lastSeenTimeで最終観測時刻を記録
QRObjectPositioner
OnQRUpdatedを購読して Prefab(Respawn/Enemy)を生成・追従- IQR 平滑化は
Common_QRPoseSmootherに委譲(既定: 過去 5 秒、IQR k=1.5) - 回転は軽い Slerp でローパス
QRPoseLocker / Prefab Helpers
QRPoseLockerが収集・ロックを担当(セットアップ運用)Setup_QRPrefabResolver/Setup_QRAnchorFactoryが Prefab 解決・生成を担当
コード構成
QRManager(中央集約)
- ファイル:
Assets/Scripts/Common/Common_QRManager.cs✅ - MRUK の
GetTrackables()を毎フレーム走査し、IsTrackedを基準に検出/更新/喪失判定を実施 lostTimeout(既定 1.0s)を超えたトラッキング喪失でOnQRLostを発行CurrentTrackedUUIDsを公開し、カメラ向きチェックなどで利用可能
QRInfo
- ファイル:
Assets/Scripts/Common/Common_QRInfo.cs✅ firstPose/lastPose/firstSeenAt/lastSeenTime/isTrackedを保持
QRObjectPositioner(ゲーム固有の配置ロジック)
- ファイル:
Assets/Scripts/Setup/Setup_QRObjectPositioner.cs✅ - Respawn(旧 Cube) と Enemy(旧 Sphere) を生成・更新
useLockedPoseOnlyをサポート:QRPoseLockerによりロックされるまで待機する仕組みありposeSmoother(Common_QRPoseSmoother)を用いて IQR 平滑化(既定: 5 秒)を適用- 便利メソッド:
ClearAllEnemies(),ClearAllObjects(),ForceSpawnMissingEnemies()など
(注) このリポジトリでは CubeColorOnQr は存在せず、代わりに Prefab の色変更や独自の視認フィードバックを Respawn / Enemy 側で実装してください。
セットアップ手順
Hierarchy
MRUtilityKit(MRUK コンポーネント付き)QRManager(シングルトン)QRObjectPositioner(Respawn/Enemy Prefab を Inspector に割当)- Prefab の視認性を高めたい場合は Prefab 側で色変更等を実装してください(本リポジトリは専用コンポーネントを持ちません)
Meta XR Settings
- Scene Understanding / QR Code Tracking を有効化
パラメータの目安
lostTimeout: 1.0s(瞬断に耐える)poseSmootherの窓長: 5 秒(既定)- Prefab を
Assets/Resources/Prefabs/に置けば Inspector 未設定でも自動ロード可
デバッグ
adb logcat -s Unity
QRManagerの[QR_ADDED] / [QR_UPDATED] / [QR_LOST]を確認QRObjectPositionerの[QR_POSITIONED] / [QR_UPDATED]で座標追従を確認- Prefab 側のログや見た目で検出/喪失を確認
トラブルシュート
- Prefab 未設定で無効化される:
QRObjectPositionerに Cube/Sphere Prefab を割当(または Resources/Prefabs に配置) - 座標がジャンプする: IQR スムージングを有効化し、
sphereHeightOffset/cubeHeightOffsetを調整 - イベントが受け取れない:
QRManagerがシーンに 1 つだけ存在するか確認
今後の改善
- IQR 窓長や係数をユースケース別にプロファイルしてデフォルト値を最適化
- 長期安定化のために空間アンカー(OVRSpatialAnchor 等)を導入する
- QR のペイロードを利用したコンテンツ紐付けの実装
