はじめに
※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 内で自分が動くということが出来ます。このことに最初はすごい感動を覚えました。 この方法を応用することで色々なことが出来そうですね!
是非試してみてください。








