今回は、QRTracking を参考に位置検知を実装します。
最新のコードは実際に扱うには問題が含まれています。 以前は Legacy XR で実装されていましたが、6/18 のコミットで Unity 2019 へバージョンアップするとともに XR Plugin での実装に更新されています。こちらはアプリを実行とすると焦点があっていない現象が起きホログラムが二重に見えます。位置検知なので正確性は目で見て判断できません。
HoloLens と XR Plugin の問題なのか、QRに関することが絡んでいるのか、未調査です。また、同じような現象で Issue もたったるようなので要観察です。
キャプチャだとだいぶずれてますが、実際は大体合ってます。二重に見えるので大体です。。
というわけで、Legacy XR 版を参考にしましょう。unity2018-old ブランチを参考にしてください。
目次
検証環境
- Unity:2019.4.3f1
- VisualStudio:2019
- MRTK 2.5 (設定、UI、操作などに)
- UniRx
手順
導入~基本的なスキャン実装
- スキャン実装までの手順は前回の記事を参照してください
- 以下、XR Plugin版の追加手順
- [Package Manager] から [Windows XR Plugin] をインストール
- [Project Settings] > [XR Plug-in Management] > [Universal Windows Platform settings] タブで、Plug-in Providers の Windows Mixed Reality にチェックをつける
- MixedRealityToolkit のプロファイルを
DefaultXRSDKConfigurationProfile
に変更する- もしくはマニュアルで必要な設定をする
- Spatial Awareness をOFFるか非表示にしたり、Camera のRender from PV Camera を有効にしたり
- Legacy XR を使っていた場合は、Player Settings で当該部分をクリアにする(勝手になるかも)
実装
QRTracking のプロジェクトから SpatialGraphCoordinateSystem
クラスを拝借します。(MIT ライセンスなのでファイルの先頭にコメントつけるなど)
先に書いた通り Legacy XR を使う場合は、Unity2018-old
ブランチを参照してください。(直リン)
SpatialGraphCoordinateSystem
は、QRCode
で上がってくる SpatialGraphNodeId
を設定すると、くっついてる GameObject
をよしなに配置してくれるようです。
よしなに配置する際の Position の中心はQRコードの左上になります。テキストやQRをオーバーレイするオブジェクトを配置する場合は、位置とサイズの調整が必要になってきます。QRCode
では PhysicalSideLength
が取得できるのでこれを位置とサイズに使います。
まず Hierarchy の設定です。
オブジェクトの階層はこんな感じにしています。QRScanner
は前回のサンプルコードと同等のものです。QRVisualizer
は後ほど。
QRCode
には先程の SpatialGraphCoordinateSystem
が追加されています。Rotation
で180度回転させてこちら向きにしています。QRTracking プロジェクトを参考にしていますが、おそらく SpatialGraphCoordinateSystem
で調整される際に180度回転するため、エディタ上で実際に見える向きにしてあるのだと思われます。
Cubeはオーバーレイ用の板です。今回はCubeのZを薄くしたものを使っています。 Textはそのままだと上下反転しているので、180度回転させます。また、Scale とフォントサイズは適切に設定します。Position は後でスクリプトから調整するので編集用の値です。
続いて QRVisualizer
のコードです。
public class QRVisualizer : MonoBehaviour { public GameObject qrCodePlane; private SpatialGraphCoordinateSystem spatialGraph; private GameObject plane; private TextMeshPro data; private QRScanner qRScanner; void Start() { spatialGraph = qrCodePlane.GetComponent<SpatialGraphCoordinateSystem>(); plane = qrCodePlane.transform.Find("Cube").gameObject; data = qrCodePlane.transform.Find("Text").GetComponent<TextMeshPro>(); qRScanner = GetComponent<QRScanner>(); qRScanner.OnScanned .Subscribe(qr => { qrCodePlane.SetActive(true); spatialGraph.Id = qr.SpatialGraphNodeId; plane.transform.localPosition = new Vector3(qr.PhysicalSideLength / 2, qr.PhysicalSideLength / 2, 0); plane.transform.localScale = new Vector3(qr.PhysicalSideLength, qr.PhysicalSideLength, 0.001f); data.text = qr.Data; data.gameObject.transform.localPosition = new Vector3(qr.PhysicalSideLength / 2, qr.PhysicalSideLength / 2, -0.001f); }) .AddTo(this); qRScanner.IsReady .Where(x => x) .First() .Subscribe(_ => qRScanner.StartScan()) .AddTo(this); qrCodePlane.SetActive(false); } }
サンプルプロジェクト
ソースコード一式は以下においてあります。