はじめに
※Unityでの開発を前提として紹介します。
ARKit のポジショントラッキングという機能に着目し、 VR 空間で自分が動けるのではないかと考え、 AR と VR の切り替えを試してみました。
今回、単眼のみなので言葉の定義として以下のように捉えています。
- AR : 現実世界が写っている画面
- VR : 現実世界が写っておらず、CGのみが写っている画面 ※複眼ではないです。
開発環境のおさらい
たくさんのサイトで紹介していると思いますが、おさらいしておきます。
- iPhone6s 〜
- iOS11〜
- Xcode9〜
- Unity5.6.1.p1〜
- Unityを使用する場合、iPhone 8 Plus では 2017.2.0f3が必要です。(画面がバグります。)
- ネイティブ・UnrealEngine でも可
- Unity ARKit Plugin
- AssetStoreに公開しているものを使用。
Build 時の注意
- ARKit は A9/A10チップのみ対応
詳細はこちらの記事から確認してください。
ちなみに、 iPhone 6以下の端末でも Build が通ってしまい、あたかも成功しているように見えるので注意が必要です。
- UnityARkitRemote を利用する時は、Develop Build を忘れずに!!
詳細はこちらの記事から確認してください。
Develop Build でないと、 Profiler に繋ぐことが出来ません。 2017.1 からは Console から Connected Player を 選択出来るようになります。
ポジショントラッキングの使用方法
まずは、適当な GameObject を作成し、後述するポジショントラッキングのスクリプトを適用します。
次に、 vrCamera に任意のカメラを紐付けしてください。今回は MainCamera を付けます。
この時、今回は使用しないUnityARCameraManagerでやっているようなことをしてます。
CardBoard を利用する場合は、以下の2点を行うようにしましょう。
- vrCamera に MainCamera の親オブジェクトを付ける
- 回転情報を渡さないようにする
以下が、ポジショントラッキングのスクリプトになります。
public class ARKitPositionTracker : MonoBehaviour { public Transform vrCamera; //対象のカメラ private UnityARSessionNativeInterface m_session; //ARKit との橋渡し。 void Start() { Application.targetFrameRate = 60; m_session = UnityARSessionNativeInterface.GetARSessionNativeInterface(); //ARkit を利用する為の初期設定 ARKitWorldTrackingSessionConfiguration config = new ARKitWorldTrackingSessionConfiguration(); config.planeDetection = UnityARPlaneDetection.Horizontal; config.alignment = UnityARAlignment.UnityARAlignmentGravity; config.getPointCloudData = true; config.enableLightEstimation = true; m_session.RunWithConfig(config); } void Update(){ if (vrCamera != null) { Matrix4x4 matrix = m_session.GetCameraPose(); //ARKit の回転情報をカメラに渡す。 vrCamera.transform.localRotation = UnityARMatrixOps.GetRotation (matrix); //ARKit の座標情報をカメラに渡す。 vrCamera.transform.localPosition = UnityARMatrixOps.GetPosition(matrix); } } }
VR ・ AR の切り替え
まずは、後述する切り替えスクリプトをUnityARVideoを適用している MainCamera につけてください。
この UnityARVideo が現実世界を写しています。
後は、 ChangeXR()を任意のタイミングで呼べば、 AR と VR の切り替えを行うことができます。
以下が切り替えスクリプトになります。
public class SwitchXR : MonoBehaviour { public GameObject vrRoom; //VR の時に表示させたい GameObject public bool vrMode = false; private Camera m_mainCamera; //MainCamera private Material m_savedClearMaterial = null; //ARVideo のマテリアルを保存用 void Start(){ m_mainCamera = Camera.main; } //AR と VR の切り替え public void ChangeXR(){ vrMode = !vrMode; if(vrMode) changeToVR(); else changeToAR(); } //VR への切り替え private void changeToVR(){ m_mainCamera.clearFlags = CameraClearFlags.Skybox; vrRoom.SetActive(true); //AR Camera の破棄 UnityARVideo arVideo = GetComponent<UnityARVideo>(); m_savedClearMaterial = arVideo.m_ClearMaterial; Destroy(arVideo); } //AR への切り替え private void changeToAR(){ m_mainCamera.clearFlags = CameraClearFlags.Depth; vrRoom.SetActive(false); //AR Camera の初期化 UnityARVideo arVideo = this.gameObject.AddComponent<UnityARVideo>(); arVideo.m_ClearMaterial = m_savedClearMaterial; } }
最終的に Inspector 上ではこのようになります
まとめ
gif では分かりづらいかもしれませんが、左下のボタンで AR と VR の切り替えが可能になっていて、ギャップロロゴを中心に自分が動くようにしています。
これを利用することで、面倒な設定をしなくても VR 内で自分が動くということが出来ます。このことに最初はすごい感動を覚えました。 この方法を応用することで色々なことが出来そうですね!
是非試してみてください。